如何在 2 个选项卡片段之间共享视图模型
How to share a viewmodel between 2 fragments that are tabs
所以我有 3 个片段,fragmentA
,fragmentB
和 fragmentC
在 fragmentA 中,我创建了一个带有 2 个选项卡(fragmentB
和 fragmentC
)的 viewpager
片段A
private fun setupTabLayoutWithViewPager() {
binding.viewPager.disableUserSwipeLeftRight()
binding.viewPager.adapter = MyCustomStateAdapter(this, this)
val tabLayout = binding.tabLayout
TabLayoutMediator(tabLayout, binding.viewPager) { tab, position ->
tab.text = when (position) {
0 -> ResourceUtils.getString(R.string.firstTab)
1 -> ResourceUtils.getString(R.string.secondTab)
else -> emptyString()
}
}.attach()
tabLayout.allowEachTabWithEqualWidth()
}
现在,从使用此 MyCustomStateAdapter
创建的 fragmentB
和 fragmentC
我想在它们之间共享视图模型,所以在我的 fragmentA 中,因为它是这两个片段的父级我为 viewmodel
的实例做了这个
片段A
private val viewModel: MyViewModel by viewModels(ownerProducer = { requireParentFragment() }) {
createVMFactory {
MyViewModel(
MyRepo()
)
}
}
现在,我是否需要在 fragmentB
和 fragmentC
中粘贴完全相同的代码以访问由 fragmentA
创建的视图模型的实例?因为我想在这 3 个片段之间共享相同的视图模型
谢谢
所以在fragmentA中应该是
private val viewModel: MyViewModel by viewModels {
createVMFactory {
MyViewModel(
MyRepo()
)
}
}
以及其他片段(选项卡片段)
private val viewModel: MyViewModel by viewModels(ownerProducer = { requireParentFragment() }) {
createVMFactory {
MyViewModel(
MyRepo()
)
}
}
因为我们创建了第一个 ownerProducer 作为这个(父片段)的视图模型,它的子片段将获取父片段并获取存储在这个所有者上的视图模型实例
Now, do I need to paste this same exact code in fragmentB and fragmentC to access the instance of the viewmodel created by fragmentA ? because I want to share this same viewmodel between these 3 fragments
是的,您需要为 ViewModel 提供相同的 ViewModelProvider.Factory(可以是不同的实例),相同的 <T>
,以及与 ViewModelStoreOwner 相同的父片段。
(嗯,FragmentA是父级,所以应该是this
,而FragmentB/FragmentC是子级,所以应该是requireParentFragment()
)。
您 不 应该在这里使用 by activityViewModels
,因为 ViewModel 的生命周期不正确。
所以我有 3 个片段,fragmentA
,fragmentB
和 fragmentC
在 fragmentA 中,我创建了一个带有 2 个选项卡(fragmentB
和 fragmentC
)的 viewpager
片段A
private fun setupTabLayoutWithViewPager() {
binding.viewPager.disableUserSwipeLeftRight()
binding.viewPager.adapter = MyCustomStateAdapter(this, this)
val tabLayout = binding.tabLayout
TabLayoutMediator(tabLayout, binding.viewPager) { tab, position ->
tab.text = when (position) {
0 -> ResourceUtils.getString(R.string.firstTab)
1 -> ResourceUtils.getString(R.string.secondTab)
else -> emptyString()
}
}.attach()
tabLayout.allowEachTabWithEqualWidth()
}
现在,从使用此 MyCustomStateAdapter
创建的 fragmentB
和 fragmentC
我想在它们之间共享视图模型,所以在我的 fragmentA 中,因为它是这两个片段的父级我为 viewmodel
片段A
private val viewModel: MyViewModel by viewModels(ownerProducer = { requireParentFragment() }) {
createVMFactory {
MyViewModel(
MyRepo()
)
}
}
现在,我是否需要在 fragmentB
和 fragmentC
中粘贴完全相同的代码以访问由 fragmentA
创建的视图模型的实例?因为我想在这 3 个片段之间共享相同的视图模型
谢谢
所以在fragmentA中应该是
private val viewModel: MyViewModel by viewModels {
createVMFactory {
MyViewModel(
MyRepo()
)
}
}
以及其他片段(选项卡片段)
private val viewModel: MyViewModel by viewModels(ownerProducer = { requireParentFragment() }) {
createVMFactory {
MyViewModel(
MyRepo()
)
}
}
因为我们创建了第一个 ownerProducer 作为这个(父片段)的视图模型,它的子片段将获取父片段并获取存储在这个所有者上的视图模型实例
Now, do I need to paste this same exact code in fragmentB and fragmentC to access the instance of the viewmodel created by fragmentA ? because I want to share this same viewmodel between these 3 fragments
是的,您需要为 ViewModel 提供相同的 ViewModelProvider.Factory(可以是不同的实例),相同的 <T>
,以及与 ViewModelStoreOwner 相同的父片段。
(嗯,FragmentA是父级,所以应该是this
,而FragmentB/FragmentC是子级,所以应该是requireParentFragment()
)。
您 不 应该在这里使用 by activityViewModels
,因为 ViewModel 的生命周期不正确。