Search code examples
androidkotlinandroid-dialogfragmentandroid-architecture-navigation

Trouble showing datepicker dialog fragment using Navigation component


I am trying to use the Navigation Component to show a date picker dialog fragment. I am getting the following error:

android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?

This is my DatePicker class

class DatePickerFragment : DialogFragment(), DatePickerDialog.OnDateSetListener {

var datePickerListener: DatePickerFragmentListener? = null

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    // Use the current date as the default date in the picker
    val c = Calendar.getInstance()
    val year = c.get(Calendar.YEAR)
    val month = c.get(Calendar.MONTH)
    val day = c.get(Calendar.DAY_OF_MONTH)

    // Create a new instance of DatePickerDialog and return it
    return DatePickerDialog(VitrixDataCollectionApp.context, this, year, month, day)
}

interface DatePickerFragmentListener {
    fun onDateSet(view: DatePicker, year: Int, month: Int, day: Int)
}

override fun onDateSet(view: DatePicker, year: Int, month: Int, day: Int) {
    datePickerListener?.onDateSet(view,year, month, day)
}
}

I would like to show the date picker when a TextInputField has focus. Here is my code to Navigate to the DatePicker

private fun showDatePicker(hasFocus: Boolean, view: View) {
    Log.i(FRAGMENT_NAME, "Has focus $hasFocus")
    if (hasFocus) {
        Navigation.findNavController(view).navigate(R.id.action_createPatientDetailsFragment_to_datePickerFragment)
    }
}

Here are the relevant parts of my navigation graph xml

<fragment android:id="@+id/createPatientDetailsFragment"
          android:name="com.datacollection.ui.patients.create_patient.patient_details.CreatePatientDetailsFragment"
          android:label="create_patient_details_fragment"
          tools:layout="@layout/create_patient_details_fragment">
    <action android:id="@+id/action_createPatientDetailsFragment_to_datePickerFragment"
            app:destination="@id/datePickerFragment"/>
</fragment>
<dialog
        android:id="@+id/datePickerFragment"
        android:name="com.datacollection.ui.DatePickerFragment"/>

I am using Nav controller version: 2.1.0-alpha04

Here are my questions:

  1. How do I get the dialog fragment to show?
  2. How do I find the id of my DatePicker fragment, I sort of guessed it to be R.id.datePickerFragment

Let me know if you need any more info or need to see any more of my code.


Solution

  • 1. How do I get the dialog fragment to show?

    Exception says is your activity running? DialogFragment needs the context of activity/fragment instead of application. Update your below line of your DatePickerFragment

    return DatePickerDialog(VitrixDataCollectionApp.context, this, year, month, day)
    

    With

    return DatePickerDialog(context, this, year, month, day)
    

    in kotlin context is the property of framgent which you are extending. For java you can use getContext().