10

我遵循 MVVM 模式——这意味着我为每个片段都有一个 ViewModel。

我使用 ViewPager2添加了两个选项卡。

我的适配器如下所示:

@Override
public Fragment createFragment(int position) {
    switch (position) {
        case 0:
            return new MergedItemsFragment();
        case 1:     
            return new ValidatedMergedItemsFragment();
    }
    return new MergedItemsFragment();
}

选项卡正在工作。但是,我注意到我的 MergedItemsFragment 的 ViewModel 表现得很奇怪。在添加选项卡之前,我导航到 Fragment,如下所示:

NavHostFragment.findNavController(this).navigate(R.id.action_roomFragment_to_itemsFragment);

当我离开那个片段NavHostFragment.findNavController(this).popBackStack()并稍后返回那个片段时,我会得到一个新的空视图模型。这是故意的。

使用我正在导航的新方法return new MergedItemsFragment()。当我离开该片段并稍后返回时,我得到一个包含旧数据的 ViewModel 。这是一个问题,因为旧数据不再相关,因为用户在另一个片段中选择了不同的数据。


更新#1

我意识到他实际上将所有片段都保存在内存中,因为相同的打印语句被多次调用。它被调用的次数随着我离开并返回该屏幕的次数而增加。因此,如果我离开并返回 10 次并旋转我的设备,他实际上将执行一行 10 次。任何猜测如何以与 ViewModel 一起使用的方式使用导航组件实现选项卡/视图页面?


更新#2

我这样设置我的 ViewModel:

viewModel = new ViewModelProvider(this, providerFactory).get(MergedItemViewModel.class)

我得到相同的结果:

viewModel = ViewModelProviders.of(this).get(MergedItemViewModel.class);

我将 ViewModel 绑定在 Fragment 本身中。因此,this是片段。

4

2 回答 2

5

根据您的评论,您正在使用 Fragment 并且在该 Fragment 内部有您的查看器。因此,在为 ViewPager 创建适配器时,您需要传递childFragmentManager而不是getActivity()

下面是您可以使用的 viewPager 的示例适配器

class NewViewPagerAdapter(fm: FragmentManager, behavior: Int) : FragmentStatePagerAdapter(fm, behavior) {
    private val mFragmentList: MutableList<Fragment> = ArrayList()
    private val mFragmentTitleList: MutableList<String> = ArrayList()

    override fun getItem(position: Int): Fragment {
        return mFragmentList[position]
    }

    override fun getCount(): Int {
        return mFragmentList.size
    }

    fun addFragment(fragment: Fragment, title: String) {
        mFragmentList.add(fragment)
        mFragmentTitleList.add(title)
    }

    override fun getPageTitle(position: Int): CharSequence? {
        return mFragmentTitleList[position]
    }
}

并在创建适配器时将其称为

   val adapter = NewViewPagerAdapter(
        childFragmentManager,
        FragmentPagerAdapter.POSITION_UNCHANGED
    )

就好像您看到FragmentStatePagerAdapter的文档一样,它声明您应该在适配器的构造函数中传递(FragmentManager, int)

我希望这能解决您的问题,因为有一天我遇到了同样的问题。

快乐编码。

于 2020-02-20T05:20:19.783 回答
1
new ViewModelProvider(requireActivity()).get("your_key", YourViewModel.class)

使用 requireActivity 获取 ViewModel 而不是片段。

于 2020-06-08T09:26:37.857 回答