I am implementing a date picker from my fragment. I want to display the selected date on my fragment.
The date picker dialog fragment:
class DatePickerDialogFragment : DialogFragment() , DatePickerDialog.OnDateSetListener {
@NotNull
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
//return super.onCreateDialog(savedInstanceState)
// Use the current date as the default date in the picker.
val c: Calendar = Calendar.getInstance()
val year: Int = c.get(Calendar.YEAR)
val month: Int = c.get(Calendar.MONTH)
val day: Int = c.get(Calendar.DAY_OF_MONTH)
// Create a new instance of DatePickerDialog and return it.
return DatePickerDialog(requireActivity(), this, year, month, day)
}
override fun onDateSet(view: DatePicker?, year: Int, month: Int, dayOfMonth: Int) {
val selectedDate = arrayOf<String>(year.toString(),month.toString(),dayOfMonth.toString())
val action = DatePickerDialogFragmentDirections.actionDatePickerDialogFragmentToDatePickerDemo(month.toString(),year.toString(),dayOfMonth.toString())
//Navigation.findNavController().navigate(action)
findNavController().navigate(action)
}
}
The DatePickerDemo class:
class DatePickerDemo : Fragment() ,View.OnClickListener {
private var mSelectedMonth: String? = null
private var mSelectedDay: String? = null
private var mSelectedYear: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_date_picker, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btnShowDate.setOnClickListener(this)
arguments?.let {
mSelectedMonth = DatePickerDemoArgs.fromBundle(it).month.toString()
mSelectedDay = DatePickerDemoArgs.fromBundle(it).day.toString()
mSelectedYear = DatePickerDemoArgs.fromBundle(it).year.toString()
}
if(mSelectedMonth != null && mSelectedDay != null && mSelectedYear != null){
processDatePickerResult(mSelectedYear!!.toInt(),mSelectedMonth!!.toInt(),mSelectedDay!!.toInt())
}
}
override fun onClick(v: View?) {
findNavController().navigate(R.id.datePickerDialogFragment)
}
}
The navigation graph for the fragment and dialog fragment is as follows:
<fragment
android:id="@+id/datePickerDemo"
android:name="com.kgandroid.droidcafeuimaster.DatePickerDemo"
android:label="DatePickerDemo" >
<action
android:id="@+id/action_datePickerDemo_to_datePickerDialogFragment"
app:destination="@id/datePickerDialogFragment" />
<argument
android:name="year"
app:argType="string"
app:nullable="true"
android:defaultValue="@null" />
<argument
android:name="month"
app:argType="string"
app:nullable="true"
android:defaultValue="@null" />
<argument
android:name="day"
app:argType="string"
app:nullable="true"
android:defaultValue="@null" />
</fragment>
<dialog
android:id="@+id/datePickerDialogFragment"
android:name="com.kgandroid.droidcafeuimaster.DatePickerDialogFragment"
android:label="fragment_date_picker_dialog"
tools:layout="@layout/fragment_date_picker_dialog" >
<action
android:id="@+id/action_datePickerDialogFragment_to_datePickerDemo"
app:destination="@id/datePickerDemo" />
</dialog>
The problem:
As obvious, I don't need the arguments in DatePikerDemo fragment when the fragment is launched. I need it when I am returning from DatePickerDialogFragment and display it as toast. So I have added null value to the arguments as you can see: app:nullable="true" android:defaultValue="@null" in the nav graph. But the problem is, the compiler is showing error:
Too many arguments for public open fun actionDatePickerDialogFragmentToDatePickerDemo
Without the default value the program is compiling but crashing with the error:
java.lang.IllegalArgumentException: Required argument "year" is missing and does not have an android:defaultValue
which is pretty obvious. So what is the solution for this?
Noticed that this kind of problems occur when communicating from fragments to dilogs and vice-versa through navigation library.