Răsfoiți Sursa

Allow plain date and time dialogs to require a future date/time as well. Related to #1781.

Aidan Follestad 6 ani în urmă
părinte
comite
64c6242d44

+ 26 - 4
datetime/src/main/java/com/afollestad/materialdialogs/datetime/DatePickerExt.kt

@@ -19,11 +19,16 @@ package com.afollestad.materialdialogs.datetime
 
 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.TimeChangeListener
 import com.afollestad.materialdialogs.datetime.utils.getDatePicker
+import com.afollestad.materialdialogs.datetime.utils.isFutureDate
 import com.afollestad.materialdialogs.datetime.utils.toCalendar
-import java.util.Calendar
 import com.afollestad.materialdialogs.utils.MDUtil.isLandscape
+import java.util.Calendar
 
 /**
  * Makes the dialog a date picker.
@@ -32,6 +37,7 @@ fun MaterialDialog.datePicker(
   minDate: Calendar? = null,
   maxDate: Calendar? = null,
   currentDate: Calendar? = null,
+  requireFutureDate: Boolean = false,
   dateCallback: DateTimeCallback = null
 ): MaterialDialog {
   customView(
@@ -50,9 +56,14 @@ fun MaterialDialog.datePicker(
     getDatePicker().init(
         currentDate.get(Calendar.YEAR),
         currentDate.get(Calendar.MONTH),
-        currentDate.get(Calendar.DAY_OF_MONTH),
-        null
-    )
+        currentDate.get(Calendar.DAY_OF_MONTH)
+    ) { _, _, _, _ ->
+      val isFutureDate = getDatePicker().isFutureDate()
+      setActionButtonEnabled(
+          POSITIVE,
+          !requireFutureDate || isFutureDate
+      )
+    }
   }
 
   positiveButton(android.R.string.ok) {
@@ -60,6 +71,17 @@ fun MaterialDialog.datePicker(
   }
   negativeButton(android.R.string.cancel)
 
+  if (requireFutureDate) {
+    val changeListener = TimeChangeListener(windowContext, getDatePicker()) {
+      val isFutureDate = it.isFutureDate()
+      setActionButtonEnabled(
+          POSITIVE,
+          !requireFutureDate || isFutureDate
+      )
+    }
+    onDismiss { changeListener.dispose() }
+  }
+
   return this
 }
 

+ 10 - 8
datetime/src/main/java/com/afollestad/materialdialogs/datetime/DateTimePickerExt.kt

@@ -66,7 +66,7 @@ fun MaterialDialog.dateTimePicker(
 
   minDateTime?.let { getDatePicker().minDate = it.timeInMillis }
 
-  getDatePicker().apply {
+  with(getDatePicker()) {
     init(
         currentDateTime?.get(Calendar.YEAR) ?: year,
         currentDateTime?.get(Calendar.MONTH) ?: month,
@@ -106,14 +106,16 @@ fun MaterialDialog.dateTimePicker(
   }
   negativeButton(android.R.string.cancel)
 
-  val changeListener = TimeChangeListener(windowContext, getTimePicker()) {
-    val isFutureTime = isFutureTime(getDatePicker(), it)
-    setActionButtonEnabled(
-        POSITIVE,
-        !requireFutureDateTime || isFutureTime
-    )
+  if (requireFutureDateTime) {
+    val changeListener = TimeChangeListener(windowContext, getTimePicker()) {
+      val isFutureTime = isFutureTime(getDatePicker(), it)
+      setActionButtonEnabled(
+          POSITIVE,
+          !requireFutureDateTime || isFutureTime
+      )
+    }
+    onDismiss { changeListener.dispose() }
   }
-  onDismiss { changeListener.dispose() }
 
   return this
 }

+ 26 - 3
datetime/src/main/java/com/afollestad/materialdialogs/datetime/TimePickerExt.kt

@@ -19,19 +19,25 @@ package com.afollestad.materialdialogs.datetime
 
 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.TimeChangeListener
 import com.afollestad.materialdialogs.datetime.utils.getTimePicker
 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 java.util.Calendar
 import com.afollestad.materialdialogs.utils.MDUtil.isLandscape
+import java.util.Calendar
 
 /**
  * Makes the dialog a time picker.
  */
 fun MaterialDialog.timePicker(
   currentTime: Calendar? = null,
+  requireFutureTime: Boolean = false,
   show24HoursView: Boolean = true,
   timeCallback: DateTimeCallback = null
 ): MaterialDialog {
@@ -41,13 +47,19 @@ fun MaterialDialog.timePicker(
       dialogWrapContent = windowContext.isLandscape()
   )
 
-  getTimePicker().apply {
+  with(getTimePicker()) {
     setIs24HourView(show24HoursView)
-
     if (currentTime != null) {
       hour(currentTime.get(Calendar.HOUR_OF_DAY))
       minute(currentTime.get(Calendar.MINUTE))
     }
+    setOnTimeChangedListener { _, _, _ ->
+      val isFutureTime = isFutureTime()
+      setActionButtonEnabled(
+          POSITIVE,
+          !requireFutureTime || isFutureTime
+      )
+    }
   }
 
   positiveButton(android.R.string.ok) {
@@ -55,6 +67,17 @@ fun MaterialDialog.timePicker(
   }
   negativeButton(android.R.string.cancel)
 
+  if (requireFutureTime) {
+    val changeListener = TimeChangeListener(windowContext, getTimePicker()) {
+      val isFutureTime = it.isFutureTime()
+      setActionButtonEnabled(
+          POSITIVE,
+          !requireFutureTime || isFutureTime
+      )
+    }
+    onDismiss { changeListener.dispose() }
+  }
+
   return this
 }
 

+ 10 - 0
datetime/src/main/java/com/afollestad/materialdialogs/datetime/utils/DateTimeExt.kt

@@ -29,6 +29,16 @@ internal fun isFutureTime(
   return dateTime.timeInMillis >= now.timeInMillis
 }
 
+internal fun TimePicker.isFutureTime(): Boolean {
+  val now = Calendar.getInstance()
+  return toCalendar().timeInMillis >= now.timeInMillis
+}
+
+internal fun DatePicker.isFutureDate(): Boolean {
+  val now = Calendar.getInstance()
+  return toCalendar().timeInMillis >= now.timeInMillis
+}
+
 internal fun DatePicker.toCalendar(): Calendar {
   return GregorianCalendar(year, month, dayOfMonth, 0, 0, 1)
 }