Sleepy Ninja
Sleepy Ninja

Reputation: 59

How do I change DatePickerDialog default date to an user latest selected date?

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

Answers (2)

Gersard
Gersard

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

cactustictacs
cactustictacs

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 ints 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

Related Questions