Skip to content

Instantly share code, notes, and snippets.

@n0m0r3pa1n
Last active October 4, 2021 19:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save n0m0r3pa1n/73fd53243b11370752ef4098fac26fca to your computer and use it in GitHub Desktop.
Save n0m0r3pa1n/73fd53243b11370752ef4098fac26fca to your computer and use it in GitHub Desktop.
import android.app.Dialog
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import android.widget.DatePicker
import androidx.appcompat.app.AlertDialog
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.activityViewModels
import dagger.hilt.android.AndroidEntryPoint
import java.time.LocalDate
import java.time.ZoneOffset
@AndroidEntryPoint
class DatePickerDialogFragment private constructor() : DialogFragment(), DatePicker.OnDateChangedListener {
private val preselectedDate: LocalDate by lazy { (requireArguments().getSerializable(ARG_PRESELECTED_DATE) as? LocalDate) ?: LocalDate.now() }
private val minDate: LocalDate? by lazy { (requireArguments().getSerializable(ARG_MIN_DATE) as? LocalDate) }
private val maxDate: LocalDate? by lazy { (requireArguments().getSerializable(ARG_MAX_DATE) as? LocalDate) }
private val caller: String by lazy { requireNotNull(requireArguments().getString(ARG_REQUEST_KEY)) }
private val viewModel: DatePickerDialogViewModel by activityViewModels()
private var selectedDate: LocalDate? = null
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialogView = View.inflate(requireContext(), R.layout.view_date_picker, null)
val datePicker = dialogView.findViewById<DatePicker>(R.id.date_picker)
val alertDialog = AlertDialog.Builder(requireContext()).create()
datePicker.init(preselectedDate.year, preselectedDate.legacyCalendarMonth, preselectedDate.dayOfMonth, this)
minDate?.let { datePicker.minDate = it.toEpochMilli(ZoneOffset.UTC) }
maxDate?.let { datePicker.maxDate = it.toEpochMilli(ZoneOffset.UTC) }
dialogView.findViewById<View>(R.id.btn_ok).setOnClickListener {
selectedDate?.let { viewModel.onDateSelected(requestKey = caller, date = it) }
alertDialog.dismiss()
}
dialogView.findViewById<View>(R.id.btn_cancel).setOnClickListener {
alertDialog.dismiss()
}
alertDialog.setView(dialogView)
alertDialog.window?.decorView?.addOnLayoutChangeListener { v, _, _, _, _, _, _, _, _ ->
if (doesDatePickerTakeAllScreenSpace(datePicker, dialogView)) {
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
}
}
return alertDialog
}
private fun doesDatePickerTakeAllScreenSpace(datePicker: DatePicker, dialogView: View) = datePicker.height >= dialogView.height
override fun onDateChanged(view: DatePicker?, year: Int, monthOfYear: Int, dayOfMonth: Int) {
selectedDate = localDateOfCalendar(year, monthOfYear, dayOfMonth)
}
companion object {
private const val ARG_PRESELECTED_DATE = "preselectedDate"
private const val ARG_MIN_DATE = "minDate"
private const val ARG_MAX_DATE = "maxDate"
private const val ARG_REQUEST_KEY = "requestKey"
fun newInstance(preselectedDate: LocalDate?, requestKey: String, minDate: LocalDate? = null, maxDate: LocalDate? = null) =
DatePickerDialogFragment().apply {
arguments = bundleOf(
ARG_PRESELECTED_DATE to preselectedDate,
ARG_MIN_DATE to minDate,
ARG_MAX_DATE to maxDate,
ARG_REQUEST_KEY to requestKey,
)
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<DatePicker
android:id="@+id/date_picker"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:calendarViewShown="true"
android:spinnersShown="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/btn_ok"
style="@style/Widget.AppCompat.Button.ButtonBar.AlertDialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:text="@string/ok"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/date_picker" />
<TextView
android:id="@+id/btn_cancel"
style="@style/Widget.AppCompat.Button.ButtonBar.AlertDialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:text="@string/cancel"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/btn_ok"
app:layout_constraintTop_toBottomOf="@id/date_picker" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment