package com.loper7.date_time_picker.controller
|
|
import android.util.Log
|
import com.loper7.date_time_picker.DateTimeConfig
|
import com.loper7.date_time_picker.DateTimeConfig.DAY
|
import com.loper7.date_time_picker.DateTimeConfig.HOUR
|
import com.loper7.date_time_picker.DateTimeConfig.MIN
|
import com.loper7.date_time_picker.DateTimeConfig.MONTH
|
import com.loper7.date_time_picker.DateTimeConfig.SECOND
|
import com.loper7.date_time_picker.DateTimeConfig.YEAR
|
import com.loper7.date_time_picker.ext.*
|
import com.loper7.date_time_picker.ext.getMaxDayInMonth
|
import com.loper7.date_time_picker.ext.isSameDay
|
import com.loper7.date_time_picker.ext.isSameMonth
|
import com.loper7.date_time_picker.ext.isSameYear
|
import com.loper7.date_time_picker.number_picker.NumberPicker
|
import com.loper7.date_time_picker.utils.StringUtils
|
import java.util.*
|
import kotlin.math.min
|
|
/**
|
*
|
* @CreateDate: 2020/9/11 13:36
|
* @Description: 日期/时间逻辑控制器
|
* @Author: LOPER7
|
* @Email: loper7@163.com
|
*/
|
open class DateTimeController : BaseDateTimeController() {
|
private var mYearSpinner: NumberPicker? = null
|
private var mMonthSpinner: NumberPicker? = null
|
private var mDaySpinner: NumberPicker? = null
|
private var mHourSpinner: NumberPicker? = null
|
private var mMinuteSpinner: NumberPicker? = null
|
private var mSecondSpinner: NumberPicker? = null
|
|
private lateinit var calendar: Calendar
|
private lateinit var minCalendar: Calendar
|
private lateinit var maxCalendar: Calendar
|
|
private var global = DateTimeConfig.GLOBAL_LOCAL
|
|
private var mOnDateTimeChangedListener: ((Long) -> Unit)? = null
|
|
private var wrapSelectorWheel = true
|
private var wrapSelectorWheelTypes: MutableList<Int>? = null
|
|
|
override fun bindPicker(type: Int, picker: NumberPicker?): DateTimeController {
|
when (type) {
|
YEAR -> mYearSpinner = picker
|
MONTH -> mMonthSpinner = picker
|
DAY -> mDaySpinner = picker
|
HOUR -> mHourSpinner = picker
|
MIN -> mMinuteSpinner = picker
|
SECOND -> mSecondSpinner = picker
|
}
|
return this
|
}
|
|
override fun bindGlobal(global: Int): DateTimeController {
|
this.global = global
|
return this
|
}
|
|
override fun build(): DateTimeController {
|
calendar = Calendar.getInstance()
|
calendar.set(Calendar.MILLISECOND,0)
|
minCalendar = Calendar.getInstance()
|
minCalendar.set(Calendar.YEAR, 1900)
|
minCalendar.set(Calendar.MONTH, 0)
|
minCalendar.set(Calendar.DAY_OF_MONTH, 1)
|
minCalendar.set(Calendar.HOUR_OF_DAY, 0)
|
minCalendar.set(Calendar.MINUTE, 0)
|
minCalendar.set(Calendar.SECOND, 0)
|
|
maxCalendar = Calendar.getInstance()
|
maxCalendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) + 1900)
|
maxCalendar.set(Calendar.MONTH, 11)
|
maxCalendar.set(Calendar.DAY_OF_MONTH, maxCalendar.getMaxDayInMonth())
|
maxCalendar.set(Calendar.HOUR_OF_DAY, 23)
|
maxCalendar.set(Calendar.MINUTE, 59)
|
maxCalendar.set(Calendar.SECOND, 59)
|
|
mYearSpinner?.run {
|
maxValue = maxCalendar.get(Calendar.YEAR)
|
minValue = minCalendar.get(Calendar.YEAR)
|
value = calendar.get(Calendar.YEAR)
|
isFocusable = true
|
isFocusableInTouchMode = true
|
descendantFocusability = NumberPicker.FOCUS_BLOCK_DESCENDANTS //设置NumberPicker不可编辑
|
setOnValueChangedListener(onChangeListener)
|
}
|
|
|
mMonthSpinner?.run {
|
maxValue = maxCalendar.get(Calendar.MONTH) + 1
|
minValue = minCalendar.get(Calendar.MONTH) + 1
|
value = calendar.get(Calendar.MONTH) + 1
|
isFocusable = true
|
isFocusableInTouchMode = true
|
|
formatter = if (DateTimeConfig.showChina(global))
|
DateTimeConfig.formatter //格式化显示数字,个位数前添加0
|
else
|
DateTimeConfig.globalMonthFormatter
|
|
descendantFocusability = NumberPicker.FOCUS_BLOCK_DESCENDANTS
|
setOnValueChangedListener(onChangeListener)
|
}
|
|
mDaySpinner?.run {
|
maxValue = maxCalendar.get(Calendar.DAY_OF_MONTH)
|
minValue = minCalendar.get(Calendar.DAY_OF_MONTH)
|
value = calendar.get(Calendar.DAY_OF_MONTH)
|
isFocusable = true
|
isFocusableInTouchMode = true
|
formatter = DateTimeConfig.formatter
|
descendantFocusability = NumberPicker.FOCUS_BLOCK_DESCENDANTS
|
setOnValueChangedListener(onChangeListener)
|
}
|
|
mHourSpinner?.run {
|
maxValue = maxCalendar.get(Calendar.HOUR_OF_DAY)
|
minValue = minCalendar.get(Calendar.HOUR_OF_DAY)
|
isFocusable = true
|
isFocusableInTouchMode = true
|
value = calendar.get(Calendar.HOUR_OF_DAY)
|
formatter = DateTimeConfig.formatter
|
descendantFocusability = NumberPicker.FOCUS_BLOCK_DESCENDANTS
|
setOnValueChangedListener(onChangeListener)
|
}
|
|
mMinuteSpinner?.run {
|
maxValue = maxCalendar.get(Calendar.MINUTE)
|
minValue = minCalendar.get(Calendar.MINUTE)
|
isFocusable = true
|
isFocusableInTouchMode = true
|
value = calendar.get(Calendar.MINUTE)
|
formatter = DateTimeConfig.formatter
|
descendantFocusability = NumberPicker.FOCUS_BLOCK_DESCENDANTS
|
setOnValueChangedListener(onChangeListener)
|
}
|
|
mSecondSpinner?.run {
|
maxValue = maxCalendar.get(Calendar.SECOND)
|
minValue = minCalendar.get(Calendar.SECOND)
|
isFocusable = true
|
isFocusableInTouchMode = true
|
value = calendar.get(Calendar.SECOND)
|
formatter = DateTimeConfig.formatter
|
descendantFocusability = NumberPicker.FOCUS_BLOCK_DESCENDANTS
|
setOnValueChangedListener(onChangeListener)
|
}
|
return this
|
}
|
|
|
private val onChangeListener = NumberPicker.OnValueChangeListener { view, old, new ->
|
applyDateData()
|
limitMaxAndMin()
|
onDateTimeChanged()
|
}
|
|
/**
|
* 同步数据
|
*/
|
private fun applyDateData() {
|
calendar.clear()
|
mYearSpinner?.apply { calendar.set(Calendar.YEAR, value) }
|
mMonthSpinner?.apply { calendar.set(Calendar.MONTH, (value - 1)) }
|
|
var maxDayInMonth = getMaxDayInMonth(mYearSpinner?.value, (mMonthSpinner?.value ?: 0) - 1)
|
if (mDaySpinner?.value ?: 0 >= maxDayInMonth) {
|
mDaySpinner?.value = maxDayInMonth
|
}
|
|
mDaySpinner?.apply { calendar.set(Calendar.DAY_OF_MONTH, value) }
|
mHourSpinner?.apply { calendar.set(Calendar.HOUR_OF_DAY, value) }
|
mMinuteSpinner?.apply { calendar.set(Calendar.MINUTE, value) }
|
mSecondSpinner?.apply { calendar.set(Calendar.SECOND, value) }
|
}
|
|
/**
|
* 日期发生变化
|
*/
|
private fun onDateTimeChanged() {
|
if (mOnDateTimeChangedListener != null) {
|
mOnDateTimeChangedListener?.invoke(calendar.timeInMillis)
|
}
|
}
|
|
/**
|
* 设置允许选择的区间
|
*/
|
private fun limitMaxAndMin() {
|
if(calendar.timeInMillis < minCalendar.timeInMillis){
|
calendar.clear()
|
calendar.timeInMillis = minCalendar.timeInMillis
|
}
|
if(calendar.timeInMillis > maxCalendar.timeInMillis){
|
calendar.clear()
|
calendar.timeInMillis = maxCalendar.timeInMillis
|
}
|
var maxDayInMonth = getMaxDayInMonth(calendar?.get(Calendar.YEAR), calendar?.get(Calendar.MONTH))
|
|
mMonthSpinner?.apply {
|
minValue =
|
if (calendar.isSameYear(minCalendar)) minCalendar.get(Calendar.MONTH) + 1 else 1
|
maxValue =
|
if ((calendar.isSameYear(maxCalendar))) maxCalendar.get(Calendar.MONTH) + 1 else 12
|
}
|
mDaySpinner?.apply {
|
minValue =
|
if (calendar.isSameMonth(minCalendar)) minCalendar.get(Calendar.DAY_OF_MONTH) else 1
|
maxValue =
|
if (calendar.isSameMonth(maxCalendar)) maxCalendar.get(Calendar.DAY_OF_MONTH) else maxDayInMonth
|
}
|
mHourSpinner?.apply {
|
minValue =
|
if (calendar.isSameDay(minCalendar)) minCalendar.get(Calendar.HOUR_OF_DAY) else 0
|
maxValue =
|
if (calendar.isSameDay(maxCalendar)) maxCalendar.get(Calendar.HOUR_OF_DAY) else 23
|
}
|
mMinuteSpinner?.apply {
|
minValue = if (calendar.isSameHour(minCalendar)) minCalendar.get(Calendar.MINUTE) else 0
|
maxValue =
|
if (calendar.isSameHour(maxCalendar)) maxCalendar.get(Calendar.MINUTE) else 59
|
}
|
mSecondSpinner?.apply {
|
minValue =
|
if (calendar.isSameMinute(minCalendar)) minCalendar.get(Calendar.SECOND) else 0
|
maxValue =
|
if (calendar.isSameMinute(maxCalendar)) maxCalendar.get(Calendar.SECOND) else 59
|
}
|
mYearSpinner?.value = calendar.get(Calendar.YEAR)
|
mMonthSpinner?.value = calendar.get(Calendar.MONTH) + 1
|
mDaySpinner?.value = calendar.get(Calendar.DAY_OF_MONTH)
|
mHourSpinner?.value = calendar.get(Calendar.HOUR_OF_DAY)
|
mMinuteSpinner?.value = calendar.get(Calendar.MINUTE)
|
mSecondSpinner?.value = calendar.get(Calendar.SECOND)
|
|
if (mDaySpinner?.value ?: 0 >= maxDayInMonth) {
|
mDaySpinner?.value = maxDayInMonth
|
}
|
|
setWrapSelectorWheel(wrapSelectorWheelTypes, wrapSelectorWheel)
|
}
|
|
|
override fun setDefaultMillisecond(time: Long) {
|
if (time == 0L) return
|
calendar.clear()
|
calendar.timeInMillis = time
|
limitMaxAndMin()
|
onDateTimeChanged()
|
}
|
|
override fun setMinMillisecond(time: Long) {
|
if (time == 0L) return
|
if (maxCalendar?.timeInMillis in 1 until time) return
|
if (minCalendar == null)
|
minCalendar = Calendar.getInstance()
|
minCalendar?.timeInMillis = time
|
minCalendar?.let {
|
mYearSpinner?.minValue = it.get(Calendar.YEAR)
|
}
|
setDefaultMillisecond(calendar.timeInMillis)
|
}
|
|
override fun setMaxMillisecond(time: Long) {
|
if (time == 0L) return
|
if (minCalendar?.timeInMillis!! > 0L && time < minCalendar?.timeInMillis!!) return
|
if (maxCalendar == null)
|
maxCalendar = Calendar.getInstance()
|
maxCalendar?.timeInMillis = time
|
|
mYearSpinner?.maxValue =
|
maxCalendar?.get(Calendar.YEAR)!!
|
|
setDefaultMillisecond(calendar.timeInMillis)
|
}
|
|
|
override fun setWrapSelectorWheel(types: MutableList<Int>?, wrapSelector: Boolean) {
|
this.wrapSelectorWheelTypes = types
|
this.wrapSelectorWheel = wrapSelector
|
if (wrapSelectorWheelTypes == null || wrapSelectorWheelTypes!!.isEmpty()) {
|
wrapSelectorWheelTypes = mutableListOf()
|
wrapSelectorWheelTypes!!.add(YEAR)
|
wrapSelectorWheelTypes!!.add(MONTH)
|
wrapSelectorWheelTypes!!.add(DAY)
|
wrapSelectorWheelTypes!!.add(HOUR)
|
wrapSelectorWheelTypes!!.add(MIN)
|
wrapSelectorWheelTypes!!.add(SECOND)
|
}
|
|
wrapSelectorWheelTypes!!.apply {
|
for (type in this) {
|
when (type) {
|
YEAR -> mYearSpinner?.run { wrapSelectorWheel = wrapSelector }
|
MONTH -> mMonthSpinner?.run { wrapSelectorWheel = wrapSelector }
|
DAY -> mDaySpinner?.run { wrapSelectorWheel = wrapSelector }
|
HOUR -> mHourSpinner?.run { wrapSelectorWheel = wrapSelector }
|
MIN -> mMinuteSpinner?.run { wrapSelectorWheel = wrapSelector }
|
SECOND -> mSecondSpinner?.run { wrapSelectorWheel = wrapSelector }
|
}
|
}
|
}
|
}
|
|
|
override fun setOnDateTimeChangedListener(callback: ((Long) -> Unit)?) {
|
mOnDateTimeChangedListener = callback
|
onDateTimeChanged()
|
}
|
|
override fun getMillisecond(): Long {
|
return calendar.timeInMillis
|
}
|
}
|