假设我们有两个片段:MainFragment和
SelectionFragment。第二个是用于选择某些对象的构建,例如整数。从第二个片段接收结果有不同的方法,如回调、总线等。
现在,如果我们决定使用导航架构组件来导航到第二个片段,我们可以使用以下代码:
NavHostFragment.findNavController(this).navigate(R.id.action_selection, bundle)
其中,bundle是bundle的一个实例(当然)。正如您所见,我们无法访问SelectionFragment,在那里我们可以放置回调。问题是,如何使用导航架构组件接收结果?
使用这些扩展功能
fun <T> Fragment.getNavigationResult(key: String = "result") =
findNavController().currentBackStackEntry?.savedStateHandle?.get<T>(key)
fun <T> Fragment.getNavigationResultLiveData(key: String = "result") =
findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<T>(key)
fun <T> Fragment.setNavigationResult(result: T, key: String = "result") {
findNavController().previousBackStackEntry?.savedStateHandle?.set(key, result)
}
所以如果你想把结果从片段B发送到片段A
内部碎片B
setNavigationResult(false, "someKey")
内部碎片A
val result = fragment.getNavigationResultLiveData<Boolean>("someKey")
result.observe(viewLifecycleOwner){ booleanValue-> doSomething(booleanValue)
重要说明
在片段B中,您需要将结果(setNavigationResult())设置为开始或恢复状态(在onStop()或onDestroy()之前),否则previousBackStackEntry将已经为空。
重要提示#2
如果只希望只处理一次结果,则必须对SavedStateHandle调用remove()以清除结果。如果不删除结果,LiveData将继续将最后一个结果返回给任何新的观察者实例。
更多信息请参阅官方指南。
由于Fragment KTX 1.3.6,Android支持在片段之间或片段与活动之间传递数据。它类似于startActivityForResult逻辑。
下面是一个导航组件的示例。你可以在这里了解更多
build.gradle
implementation "androidx.fragment:fragment-ktx:1.3.6"
碎片a。千吨
class FragmentA : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// Step 1. Listen for fragment results
setFragmentResultListener(FragmentB.REQUEST_KEY) { key, bundle ->
// read from the bundle
}
// Step 2. Navigate to Fragment B
findNavController().navigate(R.id.fragmentB)
}
}
碎片B。千吨
class FragmentB : Fragment() {
companion object {
val REQUEST_KEY = "FragmentB_REQUEST_KEY"
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
buttonA.setOnClickListener { view ->
// Step 3. Set a result
setFragmentResult(REQUEST_KEY, bundleOf("data" to "button clicked"))
// Step 4. Go back to Fragment A
findNavController().navigateUp()
}
}
}
他们在2.3.0-alpha02版本中对此进行了修复。
如果从片段A导航到片段B并且A需要来自B的结果:
findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<Type>("key")?.observe(viewLifecycleOwner) {result ->
// Do something with the result.
}
如果在片段B上,需要设置结果:
findNavController().previousBackStackEntry?.savedStateHandle?.set("key", result)
我最终为此创建了两个扩展:
fun Fragment.getNavigationResult(key: String = "result") =
findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<String>(key)
fun Fragment.setNavigationResult(result: String, key: String = "result") {
findNavController().previousBackStackEntry?.savedStateHandle?.set(key, result)
}
我正在我的应用程序中尝试导航架构组件。早些时候,我使用片段事务来实现以下功能。基本上,我想从导航。 碎片- 如果我正在使用导航组件并尝试 然后结果是FragmentA被FragmentB替换并且背景片段不可见。 我想知道一个解决方案,如果导航架构组件允许的话。 附言:我听说过嵌套导航主机,但从内部使用它好吗。 更新: FragmentB将有进一步交易的行动,例如: 碎片- 当用户按下后退按钮时,片
我正在使用BottomSheetDialogFraenge显示几个自定义设置的。 要求: 当我点击任何选项卡在BottomSheetDialogFraance我替换的片段,并将其添加到backstack,以便当用户点击的onBackPress或向上的行动,它应该回到最后设置的BottomSheetDialogFraank的片段。 我想使用导航架构组件来简化我的事务。 问题:如果我使用导航架构组件从
null 在调用之前和之后,我尝试了,但都不起作用(这是有意义的:在它没有要弹出的内容之前;在它只关闭刚刚添加的片段之后)。这是否意味着唯一的方法是重写来拦截它,并确保在这些情况下不会被调用? 谢了!
是否可以将新的导航架构组件与DialogFragment一起使用?我必须创建自定义导航器吗? 我很乐意将它们与导航图中的新功能结合使用。
在尝试导航组件之前,我曾手动执行片段事务,并使用片段标记获取当前片段。 现在在我的主要活动布局中,我有这样的东西: 如何通过导航组件检索当前显示的片段?做 返回一个,我想检索我显示的'MyFraank'。 非常感谢。
我正在使用Android的导航架构组件。 对于我的一个片段,我希望拦截“后退”和“向上”导航,以便在放弃用户未保存的任何更改之前显示一个确认对话框。(编辑事件详细信息后按back/up时的行为与默认日历应用程序相同) 我目前的方法(未经测试)如下: 对于“向上”导航,我覆盖片段上的选项ItemSelected: 为了“返回”导航,我在片段及其活动之间创建了一个自定义接口和回调系统: 对于这样一件简