Home > OS >  Getting an error when launching a material date picker from a fragment android
Getting an error when launching a material date picker from a fragment android

Time:02-12

I'm trying to launch an Material date picker from a fragment and I'm getting this error

java.lang.IllegalStateException: Fragment MaterialDatePicker{6058a76} (da2fbbc0-ee9f-4536-85f7-3942c18a1087) not attached to an activity.

My Fragment

@AndroidEntryPoint
class ReportFragment : Fragment() {

    private var _binding: FragmentReportBinding? = null
    private val binding get() = _binding!!

    private var stDate: Long? = null
    private var ndDate: Long? = null

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentReportBinding.inflate(inflater, container, false)
    
        setUpUi()

        return binding.root
    }
   
    private fun setUpUi() {
        with(binding) {
            startDate.setOnClickListener {
                showDatePicker(
                    getString(R.string.select_start_date),
                    selectedStartDate,
                    DateType.START_DATE
                )
            }
        }
     }

      private fun showDatePicker(dateCategory: String, textView: TextView, dateType: DateType) {
        val datePicker = MaterialDatePicker.Builder.datePicker().apply {
            setTitleText(dateCategory)
            setInputMode(MaterialDatePicker.INPUT_MODE_CALENDAR)
            setSelection(MaterialDatePicker.todayInUtcMilliseconds())
        }.build()
        datePicker.apply {
            show(requireActivity().supportFragmentManager, "DATE_PICKER")
            addOnPositiveButtonClickListener {
                val date = this.headerText
                textView.text = date
                when (dateType) {
                    DateType.START_DATE -> stDate = it
                    DateType.END_DATE -> ndDate = it
                }
            }
        }
    }
}

enum class DateType {
    START_DATE,
    END_DATE
}

This is the error I'm getting

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.reachafrika.reachafrikapay, PID: 15162
    java.lang.IllegalStateException: Fragment MaterialDatePicker{6058a76} (da2fbbc0-ee9f-4536-85f7-3942c18a1087) not attached to an activity.
        at androidx.fragment.app.Fragment.requireActivity(Fragment.java:928)
        at com.reachafrika.reachafrikapay.presentation.ui.fragments.reports.ReportFragment.showDatePicker(ReportFragment.kt:137)
        at com.reachafrika.reachafrikapay.presentation.ui.fragments.reports.ReportFragment.setUpUi$lambda-4$lambda-1(ReportFragment.kt:71)
        at com.reachafrika.reachafrikapay.presentation.ui.fragments.reports.ReportFragment.$r8$lambda$5X7432cB-iIkf15NUD-AuzGqT3E(Unknown Source:0)
        at com.reachafrika.reachafrikapay.presentation.ui.fragments.reports.ReportFragment$$ExternalSyntheticLambda3.onClick(Unknown Source:4)
        at android.view.View.performClick(View.java:7184)
        at android.view.View.performClickInternal(View.java:7157)
        at android.view.View.access$3500(View.java:821)
        at android.view.View$PerformClick.run(View.java:27660)
        at android.os.Handler.handleCallback(Handler.java:914)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:225)
        at android.app.ActivityThread.main(ActivityThread.java:7563)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:994)

CodePudding user response:

I replaced the

datePicker.apply {
        show(requireActivity() ...

with the following code

            show([email protected]().supportFragmentManager, "DATE_PICKER")

and it worked

Here is the full body function

 private fun showDatePicker(dateCategory: String, textView: TextView, dateType: DateType) {
        val datePicker = MaterialDatePicker.Builder.datePicker().apply {
            setTitleText(dateCategory)
            setInputMode(MaterialDatePicker.INPUT_MODE_CALENDAR)
            setSelection(MaterialDatePicker.todayInUtcMilliseconds())
        }.build()
        datePicker.apply {
            show([email protected]().supportFragmentManager, "DATE_PICKER")
            addOnPositiveButtonClickListener {
                val date = this.headerText
                textView.text = date
                when (dateType) {
                    DateType.START_DATE -> stDate = it
                    DateType.END_DATE -> ndDate = it
                }
            }
        }
    }

As the suggestion was given above. that apply changes the receiver i.e. this, and the receiver here has requireActivity() defined too, so it resolves first.

CodePudding user response:

datePicker.apply {
        show(requireActivity() ...

Here you are calling requireActivity() on the datePicker that is not attached to any activity yet. Remember that apply changes the receiver i.e. this, and the receiver here has requireActivity() defined too, so it resolves first.

You likely want to call requireActivity() on the calling fragment, as in

datePicker.apply {
        show([email protected]() ...
  • Related