Reputation: 59
I kinda stuck with this problem. I have created a DatePickerDialog in a fragment. I set the default date to be the current date when the user is opening the calendar for the first time. When the dialog is dismissed, I'm setting the EditText with the date the user have chosen. But when the user opens the date picker dialog again, it stays at the default date. I want when the user opens the dialog again to show latest selected date. What would be the best approach to this problem?
The DatePickerFragment file:
class DatePickerFragment : DialogFragment(),
DatePickerDialog.OnDateSetListener {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val c = Calendar.getInstance()
val year = c.get(Calendar.YEAR)
val month = c.get(Calendar.MONTH)
val day = c.get(Calendar.DAY_OF_MONTH)
val datePickerDialog = DatePickerDialog(requireContext(), this, year, month, day)
datePickerDialog.datePicker.maxDate = c.timeInMillis
return datePickerDialog
}
override fun onDateSet(view: DatePicker?, year: Int, month: Int, dayOfMonth: Int) {
val date = DateUtils.formatToBirthdayString(year, month, dayOfMonth)
parentFragmentManager.setFragmentResult(
KEY_BIRTH_DATE,
Bundle().apply { putString(KEY_BIRTH_DATE, date) }
)
}
}
BirthdayDialogCommand file:
class BirthdayDialogCommand(private val fragmentManager: FragmentManager) : Command {
override fun execute() {
val picker = DatePickerFragment()
if (fragmentManager.findFragmentByTag(BirthdayDialogCommand::class.java.simpleName) == null) {
picker.show(fragmentManager, BirthdayDialogCommand::class.java.simpleName)
}
}
}
And the DetailsFragment file:
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
................................
setDataBinding()
setDataListeners()
return binding.root
}
private fun setDataBinding() {
binding.apply {
................................
birthdayCommand = BirthdayDialogCommand(
parentFragmentManager
)
}
private fun setDataListeners() {
................................
parentFragmentManager.setFragmentResultListener(
KEY_BIRTH_DATE,
viewLifecycleOwner,
patientDataListener
)
}
private val patientDataListener = FragmentResultListener { _, bundle ->
bundle.getString(KEY_BIRTH_DATE)?.let {
binding.birthday.text = it
patientViewModel.setPatientBirthday(it)
}
................................
}
Upvotes: 1
Views: 1535
Reputation: 147
In your DatePickerFragment class
class DatePickerFragment : DialogFragment(),
DatePickerDialog.OnDateSetListener {
// Add a variable to keep the user selected date
var selectedDate: String? = null
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val c = Calendar.getInstance()
if (selectedDate != null) {
// You need to specify the date format are you using, in this example is "dd/MM/yyyy"
val dateUserSelected = SimpleDateFormat("dd/MM/yyyy").parse(selectedDate!!)
// The calendar instance has now the date selected by the user
c.setTime(date)
}
val year = c.get(Calendar.YEAR)
val month = c.get(Calendar.MONTH)
val day = c.get(Calendar.DAY_OF_MONTH)
val datePickerDialog = DatePickerDialog(requireContext(), this, year, month, day)
datePickerDialog.datePicker.maxDate = c.timeInMillis
return datePickerDialog
}
override fun onDateSet(view: DatePicker?, year: Int, month: Int, dayOfMonth: Int) {
val date = DateUtils.formatToBirthdayString(year, month, dayOfMonth)
parentFragmentManager.setFragmentResult(
KEY_BIRTH_DATE,
Bundle().apply { putString(KEY_BIRTH_DATE, date) }
)
}
Now, you need provide the user selected date
class BirthdayDialogCommand(private val fragmentManager: FragmentManager) : Command {
override fun execute() {
val picker = DatePickerFragment()
// It must be set before the .show method
picker.selectedDate = editTextWithTheDate.getText().toString()
if (fragmentManager.findFragmentByTag(BirthdayDialogCommand::class.java.simpleName) == null) {
picker.show(fragmentManager, BirthdayDialogCommand::class.java.simpleName)
}
}
}
Upvotes: 2
Reputation: 19514
Whenever the system creates that dialog to display it, it runs the code in onCreateDialog
which is where you're setting the dialog up. You're explicitly setting the date to "today" when you do that, so it's always going to default to that.
When you get a value you want to keep and reference later, you need to store it somewhere - the usual way is in SharedPreferences
. That way, when you come to display your dialog, you can check if there's a value stored - if so, use it! If not, fall back to your default.
Exactly how you want to do this is up to you - since you're pulling day
, month
and year
int
s from the Calendar
, you might just want to store each of those
with(prefs.edit()) {
putInt(KEY_BIRTHDAY_DAY, day)
putInt(KEY_BIRTHDAY_MONTH, month)
...
apply()
}
and you can use getInt
with a default value like -1 to pull the values back out - if any of them aren't a valid number (e.g. -1) then you don't have a date stored!
Here's some stuff on SharedPreferences
, there's a few ways to use them - you can provide a name to create a prefs file specifically for handling your stored data if you want:
https://developer.android.com/training/data-storage/shared-preferences
Upvotes: 1