在片段之间共享数据的更好方法是什么?
Which is the better way to share data between Fragments?
我想从一个片段到另一个片段共享一些整数值。我不想在设备更改配置时丢失数据。
所以我遇到并想知道哪种方式更适合我的用例的两种方式是:
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
}
}
这完全取决于您的用例、片段之间共享的数据及其使用方式。
尽管这两种情况都支持传递自定义对象,但您必须考虑一些事项。
对于导航组件,关于自定义对象:
- 数据必须是 Parcelable(首选)或 Serializable;
- 所有使用
Bundle
对象传递的数据都有其自身的局限性,并且数据量大可能会导致 TransactionTooLargeException
(more about it)。使用共享视图模型时可以轻松避免。
在共享视图模型的情况下:
- 您必须定义新的 classes 来包装您的模型;
- 您必须添加新的 class 成员才能持有共享视图模型;
- 共享视图模型将占用内存,直到 Activity 完成或清除视图模型存储。
那么答案是什么?
这样的问题会导致自以为是的答案,但我考虑在 safe argument and shared view model.
之间进行选择时遵循一组提示使用
在以下情况下使用安全参数:
- 数据少;
- 当您不需要使用此数据后return结果到前一个片段时;
- 你不关心这些数据在你用完后是否从内存中删除,每次都必须重新查询。
在以下情况下使用共享视图模型:
- 数据相对较大,或者您认为它可能很大;
- 你有多个数据models/sets;
- 当您做需要return使用此数据后将结果添加到前一个片段时;
- 当数据查询成本高昂时。共享视图模型通常与 activity.
一样长
我想从一个片段到另一个片段共享一些整数值。我不想在设备更改配置时丢失数据。
所以我遇到并想知道哪种方式更适合我的用例的两种方式是:
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
}
}
这完全取决于您的用例、片段之间共享的数据及其使用方式。
尽管这两种情况都支持传递自定义对象,但您必须考虑一些事项。
对于导航组件,关于自定义对象:
- 数据必须是 Parcelable(首选)或 Serializable;
- 所有使用
Bundle
对象传递的数据都有其自身的局限性,并且数据量大可能会导致TransactionTooLargeException
(more about it)。使用共享视图模型时可以轻松避免。
在共享视图模型的情况下:
- 您必须定义新的 classes 来包装您的模型;
- 您必须添加新的 class 成员才能持有共享视图模型;
- 共享视图模型将占用内存,直到 Activity 完成或清除视图模型存储。
那么答案是什么?
这样的问题会导致自以为是的答案,但我考虑在 safe argument and shared view model.
之间进行选择时遵循一组提示使用在以下情况下使用安全参数:
- 数据少;
- 当您不需要使用此数据后return结果到前一个片段时;
- 你不关心这些数据在你用完后是否从内存中删除,每次都必须重新查询。
在以下情况下使用共享视图模型:
- 数据相对较大,或者您认为它可能很大;
- 你有多个数据models/sets;
- 当您做需要return使用此数据后将结果添加到前一个片段时;
- 当数据查询成本高昂时。共享视图模型通常与 activity. 一样长