Forráskód Böngészése

Auto disable positive button in datetime dialog when time changes and selected time is no longer in the future. Resolves #1781.

Aidan Follestad 6 éve
szülő
commit
c607837abb

+ 15 - 4
datetime/src/main/java/com/afollestad/materialdialogs/datetime/DateTimePickerExt.kt

@@ -22,8 +22,10 @@ import androidx.annotation.CheckResult
 import com.afollestad.materialdialogs.MaterialDialog
 import com.afollestad.materialdialogs.WhichButton.POSITIVE
 import com.afollestad.materialdialogs.actions.setActionButtonEnabled
+import com.afollestad.materialdialogs.callbacks.onDismiss
 import com.afollestad.materialdialogs.customview.customView
 import com.afollestad.materialdialogs.datetime.internal.DateTimePickerAdapter
+import com.afollestad.materialdialogs.datetime.internal.TimeChangeListener
 import com.afollestad.materialdialogs.datetime.utils.getDatePicker
 import com.afollestad.materialdialogs.datetime.utils.getPageIndicator
 import com.afollestad.materialdialogs.datetime.utils.getPager
@@ -32,8 +34,8 @@ import com.afollestad.materialdialogs.datetime.utils.hour
 import com.afollestad.materialdialogs.datetime.utils.isFutureTime
 import com.afollestad.materialdialogs.datetime.utils.minute
 import com.afollestad.materialdialogs.datetime.utils.toCalendar
-import com.afollestad.materialdialogs.utils.MDUtil.resolveColor
 import com.afollestad.materialdialogs.utils.MDUtil.isLandscape
+import com.afollestad.materialdialogs.utils.MDUtil.resolveColor
 import java.util.Calendar
 
 typealias DateTimeCallback = ((dialog: MaterialDialog, datetime: Calendar) -> Unit)?
@@ -54,9 +56,9 @@ fun MaterialDialog.dateTimePicker(
       dialogWrapContent = windowContext.isLandscape()
   )
 
-  val viewPager = getPager()
-  viewPager.adapter = DateTimePickerAdapter()
-
+  val viewPager = getPager().apply {
+    adapter = DateTimePickerAdapter()
+  }
   getPageIndicator()?.run {
     attachViewPager(viewPager)
     setDotTint(resolveColor(windowContext, attr = attr.textColorPrimary))
@@ -104,6 +106,15 @@ fun MaterialDialog.dateTimePicker(
   }
   negativeButton(android.R.string.cancel)
 
+  val changeListener = TimeChangeListener(windowContext, getTimePicker()) {
+    val isFutureTime = isFutureTime(getDatePicker(), it)
+    setActionButtonEnabled(
+        POSITIVE,
+        !requireFutureDateTime || isFutureTime
+    )
+  }
+  onDismiss { changeListener.dispose() }
+
   return this
 }
 

+ 68 - 0
datetime/src/main/java/com/afollestad/materialdialogs/datetime/internal/TimeChangeListener.kt

@@ -0,0 +1,68 @@
+/**
+ * Designed and developed by Aidan Follestad (@afollestad)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.afollestad.materialdialogs.datetime.internal
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import java.util.Calendar
+
+/** @author Aidan Follestad (@afollestad) */
+internal class TimeChangeListener<T : Any>(
+  private var context: Context?,
+  private val argument: T?,
+  private var onChange: ((arg: T) -> Unit)? = null
+) {
+  private var lastHour: Int = -1
+  private var lastMinute: Int = -1
+
+  private val receiver = object : BroadcastReceiver() {
+    override fun onReceive(
+      context: Context?,
+      intent: Intent?
+    ) {
+      val now = Calendar.getInstance()
+      val newHour = now.get(Calendar.HOUR_OF_DAY)
+      val newMinute = now.get(Calendar.MINUTE)
+
+      if (argument != null && (lastHour != newHour || lastMinute != newMinute)) {
+        onChange?.invoke(argument)
+        lastHour = newHour
+        lastMinute = newMinute
+      }
+    }
+  }
+
+  init {
+    requireNotNull(context)
+    requireNotNull(argument)
+    requireNotNull(onChange)
+
+    val filter = IntentFilter().apply {
+      addAction(Intent.ACTION_TIME_TICK)
+      addAction(Intent.ACTION_TIMEZONE_CHANGED)
+      addAction(Intent.ACTION_TIME_CHANGED)
+    }
+    context!!.registerReceiver(receiver, filter)
+  }
+
+  fun dispose() {
+    context?.unregisterReceiver(receiver)
+    context = null
+    onChange = null
+  }
+}