使用导航组件在父片段范围内共享 ViewModel

Pio*_*rus 5 android viewmodel android-fragments android-jetpack android-jetpack-navigation

我正在尝试使用导航组件在父片段及其子片段中使用相同的 ViewModel 实例。层次结构如下: 具有 navigationHost 的单个 Activity。这个主机有 3 个子片段,A、B 和 C。最后一个片段也有带有 2 个片段的 navigationHost:X 和 Y。下图说明了层次结构。

片段层次结构

预期:我想与片段 X 和 Y 共享片段 C ViewModel 的相同实例。

当前:片段 C 的 ViewModel 被初始化两次:一次是在片段 C 被初始化时,第二次是在片段 X 被初始化时。片段 X 被设置为片段 C 导航图中的默认目的地。当我将默认目标更改为 Y 时,ViewModel 在 C 和 Y 中初始化。

我已经尝试过:在子视图模型中我使用这个:

        val viewModel: ParentViewModel =
        ViewModelProvider(findNavController().getViewModelStoreOwner(R.id.parent_graph)).get(
            ParentViewModel::class.java
        )
Run Code Online (Sandbox Code Playgroud)

在父 viewModel 我使用这个:

    val viewModel by viewModels<ParentViewModel>()
Run Code Online (Sandbox Code Playgroud)

我还尝试使用具有片段范围的 Koin sharedViewModel 注入 viewModel:

val viewModel by sharedViewModel<ParentViewModel>(from = { parentFragment!! })
Run Code Online (Sandbox Code Playgroud)

也没有运气。

是否有可能或者它可能是导航库中的错误?

ian*_*ake 9

ANavHostFragment本身就是一个片段,所以你的结构实际上是

Fragment C -> NavHostFragment -> Fragment X
                              -> Fragment Y
Run Code Online (Sandbox Code Playgroud)

即,parentFragment您从 Fragment X 获得的不是Fragment C - 它是NavHostFragment您在两者之间添加的。

因此,如果您想ViewModel从 Fragment C获取 a ,则需要使用requireParentFragment().requireParentFragment()- 您的父项NavHostFragment是 Fragment C。