1

我想从一个片段到另一个片段共享一些整数值。我不想在设备更改配置时丢失数据。

因此,我遇到并想知道哪一种更适合我的用例的两种方法是:

ViewModel1.在多个分片之间共享a

class SharedViewModel : ViewModel(){
    ...
}

class FragmentA : Fragment(){
    private val model: SharedViewModel by activityViewModels()
    ...
}

class FragmentB : Fragment(){
    private val model: SharedViewModel by activityViewModels()
    ...
}

2. 结合使用 SafeArgs 和自定义ViewModelProvider.Factory

使用 SafeArgs 将数据作为参数传递给从片段(例如 A)到另一个片段(例如 B)的导航操作。片段 B 的实现ViewModel(参数化)和ViewModelFactory类。将数据从 SafeArgs 传递到 ViewModelFactory 以创建 ViewModel(使用ViewModelProvider

像这样的东西:

class B : Fragment() {

    //Seperate classes for ViewModelB & ViewModelFactoryB
    private lateinit var viewModel: ViewModelB
    private lateinit var viewModelFactory: ViewModelFactoryB

    override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View? {

        val binding: BFragmentBinding = DataBindingUtil.inflate(
                inflater,
                R.layout.b_fragment,
                container,
                false
        )

        viewModelFactory = ViewModelFactoryB(BFragmentArgs.fromBundle(requireArguments()).data)
        viewModel = ViewModelProvider(this, viewModelFactoryB).get(ViewModelB::class.java)

        return binding.root
    }
}
4

1 回答 1

3

这完全取决于您的用例、您在片段之间共享哪些数据以及如何使用它。

尽管这两种情况都支持传递自定义对象,但您必须考虑一些事情。

对于导航组件,关于自定义对象

  • 数据必须是 Parcelable(首选)或 Serializable;
  • 所有通过使用Bundle对象传递的数据都有其自身的局限性并且大数据可以导致TransactionTooLargeException更多关于它)。使用共享视图模型时可以轻松避免。

在共享视图模型的情况下:

  • 你必须定义新的类来包装你的模型;
  • 您必须添加新的类成员来保存共享视图模型;
  • 共享视图模型将占用内存,直到 Activity 完成或视图模型存储被清除。

所以答案是什么?

这样的问题会导致固执己见的答案,但我考虑在安全参数共享视图模型之间进行选择时遵循一组提示。

在以下情况下使用安全参数:

  1. 数据小;
  2. 当您使用此数据后不需要将结果返回到上一个片段时;
  3. 您不在乎这些数据在完成后是否从内存中删除,并且您每次都必须再次查询它。

在以下情况下使用共享视图模型:

  1. 数据相对较大,或者您认为它可能很大;
  2. 您有多个数据模型/集;
  3. 当您确实需要在使用此数据后将结果返回到上一个片段时;
  4. 当数据查询成本很高时。共享视图模型通常与活动一样存在。
于 2020-08-03T20:44:13.090 回答