从片段 android 启动 material 日期选择器时出错

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

我正在尝试从片段中启动 Material 日期选择器,但出现此错误

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

我的片段

@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
}

这是我遇到的错误

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$lambdaX7432cB-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.access00(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)
datePicker.apply {
        show(requireActivity() ...

在这里,您正在 datePicker 上调用 requireActivity(),但尚未附加到任何 activity。请记住,apply 更改了接收器,即 this,并且此处的接收器也定义了 requireActivity(),因此它首先解析。

您可能想在调用片段上调用 ​​requireActivity(),如

datePicker.apply {
        show(this@ReportFragment.requireActivity() ...

我更换了

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

使用以下代码

            show(this@ReportFragment.requireActivity().supportFragmentManager, "DATE_PICKER")

成功了

这里是全身功能

 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(this@ReportFragment.requireActivity().supportFragmentManager, "DATE_PICKER")
            addOnPositiveButtonClickListener {
                val date = this.headerText
                textView.text = date
                when (dateType) {
                    DateType.START_DATE -> stDate = it
                    DateType.END_DATE -> ndDate = it
                }
            }
        }
    }

如上建议。 apply 更改了接收者,即 this,这里的接收者也定义了 requireActivity(),所以它首先解析。