简体   繁体   English

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

[英]how to pass a value back to previous fragment destination using Android navigation component?

let sat I have some destinations like this让坐吧 我有一些这样的目的地

from fragment A --> to fragment B --> to fragment C从片段 A --> 到片段 B --> 到片段 C

I can use Safe Args to pass data from fragment A to fragment B. and also using safe args from fragment B to fragment C.我可以使用 Safe Args 将数据从片段 A 传递到片段 B,也可以使用从片段 B 到片段 C 的安全参数。

what if I want to bring a string that generated in fragment C back to fragment B or to fragment A ?如果我想将片段 C 中生成的字符串带回片段 B 或片段 A 怎么办?

to navigate from fragment C to fragment B, I use code:要从片段 C 导航到片段 B,我使用代码:

Navigation.findNavController(fragmentView).navigateUp()

and to navigate from fragment C to fragment A, I use code:并从片段 C 导航到片段 A,我使用代码:

Navigation.findNavController(view).popBackStack(R.id.fragmentA, false)

so how to pass a value back to previous fragment destination ?那么如何将值传递回之前的片段目的地? do I have to make an action back from fragment C to fragment B and pass the value through safe args ?我是否必须从片段 C 返回到片段 B 并通过安全参数传递值?

really need your help.真的需要你的帮助。 Thank you very much :)非常感谢 :)

You can use the below snippet for sending data to previous fragment.您可以使用以下代码段将数据发送到前一个片段。

Fragment A observing the data:观察数据的片段A:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<String>("key")?.observe(viewLifecycleOwner) { data ->
        // Do something with the data.
    }
}

Fragment B sending the data:发送数据的片段B:

findNavController().previousBackStackEntry?.savedStateHandle?.set("key", data)
findNavController().popBackStack()

I also wrote extensions for this.我还为此编写了扩展程序。

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)
    }
}

Usage:用法:

Fragment A:片段A:

getBackStackData<String>("key") { data ->
    // Do something with the data.
}

Fragment B:片段B:

setBackStackData("key",data)

    

Note: I am using String as data.注意:我使用 String 作为数据。 You may use any other type of variable.您可以使用任何其他类型的变量。

Note: If you are going to use a Class as data, don't forget to add @Parcelize annotation and extend Parcelable .注意:如果你要使用一个类的数据,不要忘记添加@Parcelize注释和扩展Parcelable

You can create two buttons in every fragment, one to move to the next fragment (FragmentA to FragmentB) and others to move back (FragmentB to FragmentA). 您可以在每个片段中创建两个按钮,一个按钮移至下一个片段(FragmentA至FragmentB),其他按钮向后移(FragmentB至FragmentA)。 Then you'll be able to pass data from A to B and B to A back using safe args in the button onClick() method like 然后,您可以使用按钮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);
}

i have just came across the same problem and have several options i can propose (currently considering myself which ones is best for my use case).我刚刚遇到了同样的问题,并且有几个我可以提出的选项(目前正在考虑哪些最适合我的用例)。

  1. create a navigation action from fragment C back to fragment A. note that if that's all you do, your stack will now be: ABCA.创建一个从片段 C 返回到片段 A 的导航操作。请注意,如果这就是你所做的,你的堆栈现在将是:ABCA。 to avoid this, you can use popUpTo and PopUpToInclusive .为避免这种情况,您可以使用popUpToPopUpToInclusive see the documentation .请参阅文档

the disadvantage of this method is that fragment A will be cleared no matter what, and would have to re-load (and fetch all its' data again).这种方法的缺点是无论如何都会清除片段 A,并且必须重新加载(并再次获取其所有数据)。

  1. use a shared ViewModel between for your fragments, and observe the required value with LiveData .在片段之间使用共享的ViewModel ,并使用LiveData观察所需的值。 in this scenario, fragment C will update a LiveData value in the shared ViewModel , which fragment A observes.在这种情况下,片段 C 将更新共享ViewModelLiveData值,片段 A 观察到该值。 now when you go back to fragment A, your observer will be triggered with the value set by fragment C.现在当你回到片段 A 时,你的observer将被片段 C 设置的值触发。

  2. similar to option 2, if you are using an external data source (like a Room database) you can observe changes using LiveData in fragment A. all fragment C has to do in this case is update the data source, and fragment A will automatically be updated through the LiveData与选项 2 类似,如果您使用外部数据源(如Room数据库),您可以使用片段 A 中的LiveData观察更改。在这种情况下,片段 C 要做的就是更新数据源,片段 A 将自动更新通过LiveData更新

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用Android导航将长值传递给目标片段? - How to pass a long value to a destination fragment using Android Navigation? 如何将 function 作为参数传递给目标片段 - Android 导航组件 - How to pass a function as an argument to a destination fragment - Android Navigation Component 使用 Android 导航将数据传回前一个片段 - Pass data back to previous fragment using Android Navigation 如何使用Android中的导航控制器以编程方式返回上一个目的地? - how to back to previous destination programatically using navigation controller in Android? 如何使用导航组件导航回上一个片段 - How to navigate back to previous fragment using Navigation component 导航组件:如何在使用深度链接导航到目的地后弹出回到之前的目的地? - Navigation Component: How to pop back to previous destination after navigate to a destination using deep link? 导航组件片段没有回到上一个片段 - Navigation component fragment does not back to previous fragment 如何使用Android中的导航控制器组件检测片段是来自先前的片段还是来自随后的片段? - how to detect if a fragment comes from previous fragment or comes from the fragment afterwards using navigation controller component in Android? 如何使用 Android Jetpack 的导航组件禁用后退导航并删除 Fragment 上的后退箭头? - How do I disable back navigation and remove the back arrow on a Fragment, using Android Jetpack's Navigation component? 如何 go 在 Jetpack 导航中单击按钮从片段二到片段一回到先前的目的地 - how to go back to previous destination from fragment two to fragment one on button click in Jetpack Navigation
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM