【问题标题】:How to properly use FragmentResultListener with a Dialog如何正确使用带有对话框的 FragmentResultListener
【发布时间】:2021-03-05 00:38:53
【问题描述】:

我有一个以 DatePickerDialog 开头的 DialogFragment 片段。我想将日期传递回主机片段。我看到有人使用 setTargetFragment,但它已被弃用,并且在该函数的文档中它说使用 setFragmentResultListener,但 FragmentResultListener.onFragmentResult 函数似乎没有被调用。

我做错了什么,什么是好的约定?

主机片段:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    childFragmentManager.setFragmentResultListener(
        REQUEST_DATE,
        viewLifecycleOwner,
        this
    )
}

override fun onFragmentResult(requestKey: String, result: Bundle) {
    Log.d(TAG, "Key: $requestKey, Bundle: $result")
}

对话框:

val requestKey = requireArguments().getString(
    ARG_REQUEST_KEY,
    ""
)

val bundle = Bundle().apply {
    putSerializable(requestKey, resultDate)
}

requireParentFragment().setFragmentResult(
    requestKey,
    bundle
)

另外,我在调用 DialogFragment.show 函数时传递了宿主片段的 childFragmentManager。

【问题讨论】:

    标签: android android-fragments


    【解决方案1】:

    您不想调用requireParentFragment().setFragmentResult - 这是在父 Fragment 的 FragmentManager 中设置结果。相反,您只想按照the documentation 直接在您的片段上调用setFragmentResult()

    val requestKey = requireArguments().getString(
        ARG_REQUEST_KEY,
        ""
    )
    
    val bundle = Bundle().apply {
        putSerializable(requestKey, resultDate)
    }
    
    setFragmentResult(
        requestKey,
        bundle
    )
    

    【讨论】:

    • 谢谢你,这有效。另外,请求的 key 是否应该与 Bundle 中的 key 不同?
    • Bundle 中的内容并不重要,您可以使用任何您想要的键。
    【解决方案2】:

    您可以将 lambda 函数传递给对话框片段构造器。当您想将此数据传递给 HostFragment 时,您可以调用此函数。

    class MyDialog(
        private val backData: (String) -> Unit
    ): DialogFragment() {
        override fun onDestroy() {
            super.onDestroy()
            backData("Send your data")
        }
    }
    

    我在 onDestroy 方法中调用此方法,但您可以在任何地方调用。您也可以传递自定义数据而不是字符串

    在你的宿主片段中

    private fun setupDialog() {
        MyDialog { data ->
            // Do your thing
            Toast.makeText(context, "$data", Toast.LENGTH_SHORT).show()
        }.show(supportFragmentManager, "my_dialog")
    }
    

    我不知道这是你要找的,但我希望这可以帮助你。

    【讨论】:

    • 此解决方案不支持配置更改或进程死亡和重新创建,绝对不应在任何应用程序中使用。这正是存在像 Fragment Result API 这样的 API 的原因。
    • @ianhanniballake 先生,谢谢您的回答。实际上,我总是将片段结果用于普通片段,而不是对话片段。我不知道这是一个糟糕的解决方案。
    猜你喜欢
    • 2011-05-07
    • 2012-11-26
    • 2016-01-08
    • 2011-07-11
    • 1970-01-01
    • 2015-06-26
    • 1970-01-01
    • 2012-12-04
    • 2012-04-29
    相关资源
    最近更新 更多