让我坐在这样的目的地
从片段A->到片段B->到片段C
我可以使用安全Args将数据从片段A传递到片段B,也可以使用安全args从片段B传递到片段C。
如果我要将片段C中生成的字符串带回到片段B或片段A会怎样?
要从片段C导航到片段B,我使用代码:
Navigation.findNavController(fragmentView).navigateUp()
并从片段C导航到片段A,我使用代码:
Navigation.findNavController(view).popBackStack(R.id.fragmentA, false)
那么如何将值传递回先前的片段目标?我必须从片段C返回片段B并通过安全args传递值吗?
真的需要您的帮助。非常感谢:)
答案 0 :(得分:3)
您可以使用以下代码片段将数据发送到上一个片段。
片段A观察数据:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<String>("key")?.observe(viewLifecycleOwner) { data ->
// Do something with the data.
}
}
片段B发送数据:
findNavController().previousBackStackEntry?.savedStateHandle?.set("key", data)
findNavController().popBackStack()
我也为此写了扩展名。
fun <T : Any> Fragment.setBackStackData(key: String,data : T, doBack : Boolean = true) {
findNavController().previousBackStackEntry?.savedStateHandle?.set(key, data)
if(doBack)
findNavController().popBackStack()
}
fun <T : Any> Fragment.getBackStackData(key: String, result: (T) -> (Unit)) {
findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<T>(key)?.observe(viewLifecycleOwner) {
result(it)
}
}
用法:
片段A:
getBackStackData<String>("key") { data ->
// Do something with the data.
}
片段B:
setBackStackData("key",data)
注意:我正在使用String作为数据。您可以使用任何其他类型的变量。
注意:如果要使用Class作为数据,请不要忘记添加@Parcelize
注释并扩展Parcelable
。
答案 1 :(得分:0)
我刚遇到相同的问题,可以提出几种选择(目前正在考虑自己最适合我的用例)。
popUpTo
和PopUpToInclusive
。参见documentation。此方法的缺点是无论如何片段A都会被清除,并且必须重新加载(并再次获取其所有数据)。
在片段之间使用共享的ViewModel
,并使用LiveData
观察所需的值。在这种情况下,片段C将更新共享A LiveData
中的ViewModel
值。现在,当您返回片段A时,您的observer
将被片段C设置的值触发。
类似于选项2,如果您使用外部数据源(例如Room
数据库),则可以在片段A中使用LiveData
来观察更改。所有片段C都必须在这种情况是更新数据源,并且片段A将通过LiveData
答案 2 :(得分:-2)
您可以在每个片段中创建两个按钮,一个按钮移至下一个片段(FragmentA至FragmentB),其他按钮向后移(FragmentB至FragmentA)。然后,您可以使用按钮onClick()方法中的安全参数将数据从A传递到B,然后将B传递回A,例如
@Override
public void onClick(View view) {
int amount = 20;
ConfirmationAction action = SpecifyAmountFragmentDirections.confirmationAction();
action.setAmount(amount);
Navigation.findNavController(view).navigate(action);
}