使用Android导航将数据传回上一个片段

时间:2019-05-21 16:57:15

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

我已经开始使用Android体系结构组件(导航和安全Args,视图模型)以及Koin库。

当前,我在两个片段之间传递参数时遇到了问题-我需要将一个字符串值从片段A传递到片段B,在片段B中修改此值,然后将其传递回片段A。

我找到了解决我的问题的一种可能的方法-共享视图模型。不幸的是,这种方法有一个问题,因为我可以在屏幕之间传递和修改值,但是当片段A导航到另一个目标时,共享视图模型中的值仍会存储而不清除。

在Android导航中的片段之间传递和修改数据是否有其他解决方案?我想避免手动清除此值(当碎片A被破坏时)。

4 个答案:

答案 0 :(得分:15)

Android刚刚为此发布了一个解决方案; Passing data between Destinations导航2.3.0-alpha02 ),基本上,在片段A中,您观察到变量的变化,而在片段B中,您在执行popBackStack()之前更改了该值。

片段A:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val navController = findNavController();
// We use a String here, but any type that can be put in a Bundle is supported
navController.currentBackStackEntry?.savedStateHandle?.getLiveData("key")?.observe(
    viewLifecycleOwner) { result ->
    // Do something with the result.
  }
}

片段B:

navController.previousBackStackEntry?.savedStateHandle?.set("key", result)
navController.popBackStack()

答案 1 :(得分:0)

1)使用action_A_to_B和SafeArgs将字符串从片段A传递到片段B。

2)popBackStack删除片段B。

navController.popBackStack(R.id.AFragment, false);

navController.popBackStack();

3)然后使用action_B_to_A将修改后的数据从B传递到A。

编辑。

这里您还有其他解决方案: enter link description here

答案 2 :(得分:0)

您可以尝试此解决方案

<fragment
    android:id="@+id/a"
    android:name="...">

    <argument
        android:name="text"
        app:argType="string" />

    <action
        android:id="@+id/navigate_to_b"
        app:destination="@id/b" />

</fragment>

<fragment
    android:id="@+id/b"
    android:name="...">

    <argument
        android:name="text"
        app:argType="string" />

    <action
        android:id="@+id/return_to_a_with_arguments"
        app:destination="@id/a"
        app:launchSingleTop="true"
        app:popUpTo="@id/b"
        app:popUpToInclusive="true" />

</fragment>

和导航片段

NavHostFragment.findNavController(this).navigate(BFragmentDirections.returnToAWithArguments(text))

ianhanniballake的comment帮助我解决了类似的问题

答案 3 :(得分:0)

当前,我在两个片段之间传递参数时遇到了问题-我需要将一个字符串值从片段A传递到片段B,在片段B中修改此值,然后将其传递回片段A。

理论上的解决方案实际上是将两个片段放在一个共享的<navigation标签中,然后将ViewModel的范围设置为导航标签的ID,这样您现在就可以在两个屏幕之间共享ViewModel。

为确保可靠性,最好同时使用Navigation标记的NavBackStackEntry作为ViewModelStoreOwner和SavedStateRegistryOwner,并创建一个AbstractSavedStateViewModelFactory,它将使用ViewModelProvider创建ViewModel,同时还提供一个SavedStateHandle。

您可以使用此SavedStateHandle将结果从FragmentB传递到FragmentA,该SavedStateHandle与共享的ViewModel(作用域为共享的NavGraph)关联。

相关问题