【问题标题】:Reusing ViewModel between fragments在片段之间重用 ViewModel
【发布时间】:2021-06-22 02:49:55
【问题描述】:

我正在使用导航组件编写一个应用程序,它是一个活动多片段架构并使用 ShareViewModel 传递数据(类对象)。我的问题是在片段之间传递数据工作正常,但是当我回到上一个片段时,数据更改为 ShareViewModel 中的最新对象存储。

流程如下:
characterListFragment -> characterDetailFragmentA -> episodeFragment -> characterDetailFragmentB
从头到尾导航:
characterDetailFragmentB -> episodeFragment -> characterDetailFragmentA(显示的数据与characterDetailFragmentB相同)-> characterListFragment

这是我的导航图:​

  1. characterListFragment显示数据列表。
  2. characterDetailFragmentwhich 显示从 characterListFragment 中选择的数据。
  3. episodeFragment 显示所选剧集中的所有数据。

我正在使用 shareViewModel 在 characterListFragmentcharacterDetailFragment 之间传递数据。我还重用了 shareViewModel 在episodeFragmentcharacterDetailFragment 之间传递数据
这是shareViewModel代码

class ShareSelectedCharacterViewModel : ViewModel() {
    val selected = MutableLiveData<Character>()

    fun select(item: Character) {
        selected.value = item
    }
}

然后我像这样将 shareViewModel 连接到活动生命周期

private val shareViewModel: ShareSelectedCharacterViewModel by activityViewModels()

当我选择characterDetailFragmentepisodeFragment中的数据时,我会将数据设置为shareViewModel并使用相同的生命周期范围shareViewModel获取characterDetailFragment中的数据。

// Set selected data
shareViewModel.select(character)
 
sharedModel.selected.observe(viewLifecycleOwner, Observer { 
        // Observe the data
})

我的问题是在片段之间传递数据工作正常,但是当我回到上一个片段时,数据更改为 ShareViewModel 中的最新对象存储。我知道由于使用相同的视图模型,数据会发生变化。所以我想知道有没有办法处理这种情况?

【问题讨论】:

    标签: android android-fragments navigation android-viewmodel


    【解决方案1】:

    我找到了解决这个问题的方法。在ShareViewModel中添加栈结构,在characterDetailFragment 中检测后退导航。

    /**
     * Using stack to store the sharedData and pop the stored data
     * when user pressBack.
     */
    class ShareSelectedCharacterViewModel : ViewModel() {
        private val stack = Stack<Character>()
        val selected = MutableLiveData<Character>()
    
        fun select(item: Character) {
            selected.value = item
            stack.add(item)
        }
    
        fun pop() {
            stack.pop()
            if(stack.isNotEmpty()) {
                selected.value = stack.peek()
            }
    
        }
    }
    

    当我按下characterDetailFragment 中的返回按钮时,我调用viewModel.pop 方法将以前的数据设置为selected

             /**
             *   Implement Custom Back Navigation:
             *   when user pressBack in CharacterDetailFragment, we also need to pop out the data
             *   that stored in the ShareSelectedCharacterViewModel to retrieve previous one.
             */
            requireActivity().onBackPressedDispatcher.addCallback(this) {
                findNavController().popBackStack()
                sharedModel.pop()
            }         
    

    有没有更好的方法来处理这种情况?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-31
      • 1970-01-01
      相关资源
      最近更新 更多