如何在作为选项卡的 2 个片段之间共享视图模型

Posted

技术标签:

【中文标题】如何在作为选项卡的 2 个片段之间共享视图模型【英文标题】:How to share a viewmodel between 2 fragments that are tabs 【发布时间】:2021-12-17 08:39:44 【问题描述】:

所以我有 3 个片段,fragmentAfragmentBfragmentC

在 FragmentA 中,我创建了一个带有 2 个选项卡(fragmentBfragmentC)的浏览器

片段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()
    

现在,从fragmentBfragmentC 用这个MyCustomStateAdapter 创建我想在它们之间共享视图模型,所以在我的fragmentA 中,因为它是这两个片段的父级,所以我为视图模型

片段A

 private val viewModel: MyViewModel by viewModels(ownerProducer =  requireParentFragment() ) 
        createVMFactory 
            MyViewModel(
                MyRepo()
            )
        
    

现在,我是否需要在 fragmentBfragmentC 中粘贴相同的代码才能访问由 fragmentA 创建的视图模型实例?因为我想在这 3 个片段之间共享相同的视图模型

谢谢

【问题讨论】:

@Tenfour04 如果要将 ViewModel 范围限定为父片段,则无需使用 activityViewModels。你给出了不好的建议。 @EpicPandaForce 谢谢,我看错了问题。 【参考方案1】:

现在,我是否需要在 fragmentB 和 fragmentC 中粘贴相同的代码才能访问由 fragmentA 创建的视图模型的实例?因为我想在这 3 个片段之间共享相同的视图模型

是的,您需要为 ViewModel 提供相同的 ViewModelProvider.Factory(可以是不同的实例)、相同的 <T>,以及作为 ViewModelStoreOwner 的父片段。

(嗯,FragmentA 是父级,所以应该是this,FragmentB/FragmentC 是子级,所以应该是requireParentFragment())。


您特别应该在这里使用by activityViewModels,因为 ViewModel 的生命周期不正确。

【讨论】:

【参考方案2】:

所以在fragmentA中应该是

private val viewModel: MyViewModel by viewModels 
        createVMFactory 
            MyViewModel(
                MyRepo()
            )
        
    

在其他片段中(标签片段)

 private val viewModel: MyViewModel by viewModels(ownerProducer =  requireParentFragment() ) 
        createVMFactory 
            MyViewModel(
                MyRepo()
            )
        
    

因为我们使用 ownerProducer 作为 this(父片段)创建了第一个视图模型,它的子片段将获取父片段并获取存储在此所​​有者上的视图模型实例

【讨论】:

以上是关于如何在作为选项卡的 2 个片段之间共享视图模型的主要内容,如果未能解决你的问题,请参考以下文章

带有 UINavigationController 作为选项卡的 UITabViewController

在带有选项卡的 Winforms 的模型视图演示器中应该使用多少个演示器?

当页面通过ajax作为部分加载时,如何重新绑定淘汰视图模型?

使用 koin 2.2.3 和 jetpack 导航在 2 个片段之间限定视图模型

片段和活动之间没有传递值

Android - 选项卡式片段