[英]Shared ViewModel in scope of parent fragment using Navigation Component
I am trying to use the same instance of ViewModel in Parent Fragment and its children, using Navigation Component.我正在尝试使用导航组件在父片段及其子片段中使用相同的 ViewModel 实例。 The hierarchy is as follows: Single Activity that has navigationHost.
层次结构如下:具有导航主机的单个活动。 This host has 3 child fragments, A, B and C. The last fragment has also navigationHost with 2 fragments: X and Y. The below graph illustrates the hierarchy.
该主机有 3 个子片段,A、B 和 C。最后一个片段也有带有 2 个片段的导航主机:X 和 Y。下图说明了层次结构。
Expected: I would like to share the same instance of fragment C ViewModel with fragment X and Y.预期:我想与片段 X 和 Y 共享片段 C ViewModel 的相同实例。
Current: The ViewModel of fragment C is initialized twice: Once when fragment C is initialized and second time when fragment X is initialized.当前:片段 C 的 ViewModel 被初始化两次:一次是片段 C 被初始化,第二次是片段 X 被初始化。 The Fragment X is set as a default destination in the fragment C nav graph.
片段 X 在片段 C 导航图中设置为默认目的地。 When I am changing the default destination to Y, the ViewModel is initialized in C and Y.
当我将默认目标更改为 Y 时,ViewModel 在 C 和 Y 中初始化。
What I tried already: In child viewModels I use this:我已经尝试过的:在子视图模型中我使用这个:
val viewModel: ParentViewModel =
ViewModelProvider(findNavController().getViewModelStoreOwner(R.id.parent_graph)).get(
ParentViewModel::class.java
)
In parent viewModel I use this:在父 viewModel 中我使用这个:
val viewModel by viewModels<ParentViewModel>()
I've also tried to inject the viewModel using Koin sharedViewModel with scope of fragment:我还尝试使用带有 scope 片段的 Koin sharedViewModel 注入 viewModel:
val viewModel by sharedViewModel<ParentViewModel>(from = { parentFragment!! })
Also no luck.也没有运气。
Is it possible or maybe it is a bug in navigation library?有可能还是导航库中的错误?
A NavHostFragment
is a fragment itself, so your structure is actually NavHostFragment
本身就是一个片段,所以你的结构实际上是
Fragment C -> NavHostFragment -> Fragment X
-> Fragment Y
Ie, the parentFragment
you get from Fragment X is not Fragment C - it is the NavHostFragment
you added in between the two.即,您从 Fragment X 获得的
parentFragment
不是Fragment C - 它是您在两者之间添加的NavHostFragment
。
Therefore if you want to get a ViewModel
from Fragment C, you'd need to use requireParentFragment().requireParentFragment()
- the parent of your NavHostFragment
is Fragment C.因此,如果您想从片段 C 获取
ViewModel
,则需要使用requireParentFragment().requireParentFragment()
的父NavHostFragment
是片段 C。
Cannot find a parameter with this name: from ------------update----------------找不到具有此名称的参数:来自 ----------update----------------
for those facing the same issue, check here koin issue discuss about, and maybe here might be helpful.对于那些面临相同问题的人,请查看此处的 koin 问题讨论,也许这里可能会有所帮助。
I'm using我在用着
//child fragment
private val viewModel: TripParentViewModel by viewModel(owner = { ViewModelOwner.Companion.from(requireParentFragment().requireParentFragment().viewModelStore)})
//parent fragment
private val parentViewModel by viewModel<TripParentViewModel>()
as solution,作为解决方案,
class TripParentViewModel:ViewModel() {
var count = 0
fun test(){
when(count){
0 -> Timber.d("first click")
1 -> Timber.d("second click")
2 -> Timber.d("third click")
}
Timber.d(count.toString())
count++
}
}
currently, I run this when change fragment, I didn't see any problem so far, if anything goes wrong, I will update here目前,我在更改片段时运行它,到目前为止我没有看到任何问题,如果有任何问题,我会在这里更新
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.