Closed Bter closed 1 year ago
修复后的代码
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() {
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() {
var maxDayInMonth = getMaxDayInMonth(mYearSpinner?.value, (mMonthSpinner?.value ?: 0) - 1)
if(calendar.timeInMillis < minCalendar.timeInMillis){
calendar.timeInMillis = minCalendar.timeInMillis
}
if(calendar.timeInMillis > maxCalendar.timeInMillis){
calendar.timeInMillis = maxCalendar.timeInMillis
}
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
mYearSpinner?.minValue = minCalendar?.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
}
}
SDKV0.6.0
问题:关于setMaxMillisecond的Bug #47在V0.6.0重现
场景:Demo中的CardDatePickerDialog Max Value: 2022-01-06 14:27:53 Min Value: 1990-10-23 14:28:06 Def Value: 2016-08-13 14:28:24
点击Show Dialog
默认时间将显示在2016年01月03日14时28分24秒