我有一个关于android ViewModels的架构问题:
让我们说在我的应用程序中我有一个带有两个片段的活动(使用Viewpager)。这两个片段做了不同的事情(因此可能有自己的ViewModel?),但它们也需要各种类似的数据。
这是例如网络连接是否可用的状态(如果没有连接,则两个片段都显示不同的错误UI),或者来自服务器的某些用户设置来自服务器并同等地影响两个片段。
这看起来像这样:
现在我的问题是如何在使用ViewModels时处理这种情况? 视图是否观察多个ViewModel是好的,就像我有一个ViewModel用于Activity(保持两个都需要的状态)和每个片段一个,如下所示:
这被暗示here例如,但这不是一个好习惯,因为relationship in MVVM通常是
查看n - 1 ViewModel n - 1模型
但我不确定这种共享LiveData的正确位置在哪里?
答案 0 :(得分:9)
我认为ViewModel背后的概念是它应该与单个“屏幕”相关,而不是“视图”。因此,按照这种逻辑,我认为如果多个片段引用相同的ViewModel,您可以使用相同的ViewModel,因为它们在技术上属于相同的“屏幕”。
在片段中,您可以请求包含LiveData实例的ViewModel的活动,并根据需要为您提供更新。
希望这能回答你的问题。
更新:我找到了a link to a sample fragment in Google samples。查看onCreateView()方法。粘贴下面的代码以供参考:
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View root = inflater.inflate(R.layout.addtask_frag, container, false);
if (mViewDataBinding == null) {
mViewDataBinding = AddtaskFragBinding.bind(root);
}
mViewModel = AddEditTaskActivity.obtainViewModel(getActivity());
mViewDataBinding.setViewmodel(mViewModel);
setHasOptionsMenu(true);
setRetainInstance(false);
return mViewDataBinding.getRoot();
}
P.S。如果您找到了更好的解决方案/答案/练习,请知道。
答案 1 :(得分:0)
最新答案,但我问了自己同样的问题,并在Google指南中找到了答案。 特别是对于片段,它在Google文档中有明确规定:https://developer.android.com/topic/libraries/architecture/viewmodel#sharing
class SharedViewModel : ViewModel() {
val selected = MutableLiveData<Item>()
fun select(item: Item) {
selected.value = item
}
}
class MasterFragment : Fragment() {
private lateinit var itemSelector: Selector
private lateinit var model: SharedViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
model = activity?.run {
ViewModelProviders.of(this)[SharedViewModel::class.java]
} ?: throw Exception("Invalid Activity")
itemSelector.setOnClickListener { item ->
// Update the UI
}
}
}
class DetailFragment : Fragment() {
private lateinit var model: SharedViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
model = activity?.run {
ViewModelProviders.of(this)[SharedViewModel::class.java]
} ?: throw Exception("Invalid Activity")
model.selected.observe(this, Observer<Item> { item ->
// Update the UI
})
}
}