如何使用Android导航组件将值传递回先前的片段目标?

时间:2019-08-18 01:40:24

标签: android android-fragments android-jetpack android-navigation android-architecture-navigation

让我坐在这样的目的地

从片段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传递值吗?

真的需要您的帮助。非常感谢:)

3 个答案:

答案 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)

我刚遇到相同的问题,可以提出几种选择(目前正在考虑自己最适合我的用例)。

  1. 创建一个从片段C到片段A的导航动作。请注意,如果这就是您要做的一切,那么您的堆栈现在将是:A-B-C-A。为避免这种情况,可以使用popUpToPopUpToInclusive。参见documentation

此方法的缺点是无论如何片段A都会被清除,并且必须重新加载(并再次获取其所有数据)。

  1. 在片段之间使用共享的ViewModel,并使用LiveData观察所需的值。在这种情况下,片段C将更新共享A LiveData中的ViewModel值。现在,当您返回片段A时,您的observer将被片段C设置的值触发。

  2. 类似于选项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);
}