Last active
October 4, 2021 19:52
-
-
Save n0m0r3pa1n/73fd53243b11370752ef4098fac26fca to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | |
) | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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