你好,我的问题如下,我有 2 个片段,一个使用 SetFragmentResultListener 接收,另一个使用 setFragmentResult 发送
问题是 setFragmentResult 不能在 OnClickListener 内部工作,但可以在外部工作
家长
setFragmentResultListener("scannedCode") { requestKey, bundle ->
val result = bundle.getString("code")
Log.i("MYLOG-find","$result")
}
孩子 - 它有效
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_scan, container, false)
setFragmentResult("scannedCode", bundleOf("code" to "pedro"))
return view
}
孩子 - 这不起作用
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_scan, container, false)
view.textView2.setOnClickListener {
setFragmentResult("scannedCode", bundleOf("code" to "pedro"))
}
return view
}
根据 @ianhanniballake 的回答,我更进一步,因为我遇到了类似的问题,并阅读了他提到的文档(特别是在主机活动中接收结果部分)。进行片段间通信(父子)的关键之一是使用 Activity 的
supportFragmentManager
方法来执行信息交换。示例:
requireActivity().supportFragmentManager
.setFragmentResultListener("whatever_id_you_use", viewLifecycleOwner) {
// Your code for listener
}
requireActivity().supportFragmentManager
.setFragmentResult("whatever_id_you_use", bundle_with_results)
"whatever_id_you_use"
是文档中描述的 requestKey,它是 Activity 在为其结果分配侦听器时将查找的索引。这样做应该使侦听器与生命周期保持同步,同时简化自己的侦听器的实现。
在将数据从 Child 片段传递到 Parent 片段的情况下,在
parent 片段上设置 resultListener 时,使用
childFragmentManager
是关键。
onCreate()
):childFragmentManager.setFragmentResultListener("requestKey", this ) { requestKey, bundle ->
val resultReceived = bundle.getString("bundleKey")
// do something with the result
// ...
}
val resultToBeSent = "result"
setFragmentResult("requestKey", bundleOf("bundleKey" to resultToBeSent))
有关片段之间通信的更多有用信息可以在这篇媒体文章中找到: 在片段之间传递数据的现代方式,当然还有 Android 官方文档:与片段通信。
当您使用导航组件时,当您导航到新片段时,前一个片段会停止。根据 Fragment Result API 指南:
如果您对同一键多次调用
,并且 如果侦听器不是setFragmentResult()
,则系统会将所有待处理结果替换为您的更新结果。 如果您设置的结果没有相应的侦听器来接收它,结果存储在STARTED
中,直到您使用相同的键设置侦听器。一旦侦听器收到结果并触发FragmentManager
回调,结果就会被清除。这种行为有两个主要含义:onFragmentResult()
- 返回堆栈上的片段只有在被弹出并且
时才会收到结果。STARTED
- 如果设置结果时侦听结果的片段是
,则会立即触发侦听器的回调。STARTED
因此,预计您不会收到对片段结果侦听器的任何调用,直到您弹回到该片段并且它再次变为
STARTED
。
在我的例子中,将推送的片段结果发送到演示,我需要调用:
requireActivity().onBackPressed()
,然后setFragmentResult()
。
在父片段的
setFragmentResultListener
方法中调用 onViewCreated
。
因为根据
FragmentManager
的源码,当父fragment的FragmentResultListener
被调用时,onDestroyView
会被移除,所以当你回到父fragment时,你应该重新注册监听器以确保它被调用在父片段开始之后。