【问题标题】:Which is the better way to share data between Fragments? [closed]在 Fragment 之间共享数据的更好方法是什么? [关闭]
【发布时间】:2020-08-03 19:32:54
【问题描述】:

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

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

1。在多个片段之间共享ViewModel

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
    }
}

【问题讨论】:

  • 当你要求最好但你没有提到在什么情况下,每个即将到来的答案可能会根据每个人的看法而有所偏差。但我认为看到这个页面对你来说是一个好的开始。 developer.android.com/guide/navigation/navigation-pass-data
  • 我希望我的问题现在清楚地解释了我的用例。很抱歉之前没有正确构图。

标签: android android-fragments android-architecture-components android-viewmodel android-safe-args


【解决方案1】:

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

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

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

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

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

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

那么答案是什么?

这样的问题会导致自以为是的答案,但我考虑在safe argumentshared view model 之间进行选择时遵循一组提示。

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

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

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

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

【讨论】:

  • 很抱歉没有正确地提出问题。我想知道如何在这两种方式之间进行选择,而您的回答就是这样解释的。谢谢你的回答。
  • 我想分享几个从FragmentAFragmentB的整数值,所以我分享的数据很小。对于使用 SafeArgs,我必须分别为 FragmentB 创建一个 ViewModelFactory 和一个 ViewModel 并将整数从 Bundle 传递到 ViewModel 工厂。虽然如果我在这些片段之间共享一个 ViewModel,我会避免所有这些代码。你会建议我继续做什么?
  • 为了安全参数,您不需要任何与 ViewModel 相关的类。您需要使用导航组件,并且在导航图中您应该定义两个参数。 Example of one argument。然后在您的接收器片段中,您可以使用MyFragmentArgs.fromBundle(getArguments()).get[variable_name_here](); 来获取传入的值。
  • 为了处理我的应用程序中的配置更改,我必须使用 onSaveInstanceState()ViewModel 但由于我目前正在学习架构组件,所以我会想使用 ViewModel。在这种情况下,我有两种方法(我知道)来实现问题中提到的这一点。
  • 然后使用视图模型。使用shared view model 会更方便。该主题的链接中有一小段代码。您只需设置和访问从一个片段到另一个片段的数据。
猜你喜欢
  • 2020-04-14
  • 1970-01-01
  • 2021-07-29
  • 1970-01-01
  • 2019-03-28
  • 2018-03-25
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
相关资源
最近更新 更多