在 Last Google IO 上,Google 发布了一些新架构组件的预览,其中之一是 ViewModel。
在 文档 中,谷歌显示了该组件的一种可能用途:
一个活动中的两个或多个片段需要相互通信是很常见的。这绝不是微不足道的,因为两个片段都需要定义一些接口描述,并且所有者活动必须将两者绑定在一起。此外,两个片段都必须处理另一个片段尚未创建或不可见的情况。
这个常见的痛点可以通过使用 ViewModel 对象来解决。想象一个主从片段的常见情况,我们有一个片段,其中用户从列表中选择一个项目,另一个片段显示所选项目的内容。
这些片段可以使用它们的活动范围共享一个 ViewModel 来处理这种通信。
并展示了一个实现示例:
public class SharedViewModel extends ViewModel {
private final SavedStateHandle state;
public SharedViewModel(SavedStateHandle state) {
this.state = state;
}
private final MutableLiveData<Item> selected = state.getLiveData("selected");
public void select(Item item) {
selected.setValue(item);
}
public LiveData<Item> getSelected() {
return selected;
}
}
public class MasterFragment extends Fragment {
private SharedViewModel model;
@Override
protected void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
model = new ViewModelProvider(getActivity()).get(SharedViewModel.class);
itemSelector.setOnClickListener(item -> {
model.select(item);
});
}
}
public class DetailFragment extends Fragment {
@Override
protected void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
SharedViewModel model = new ViewModelProvider(getActivity()).get(SharedViewModel.class);
model.getSelected().observe(this, { item ->
// update UI
});
}
}
我对不需要那些用于片段的接口通过活动进行通信的可能性感到非常兴奋。
但谷歌的例子并没有准确地显示我将如何从主控中调用细节片段。
我仍然必须使用将由活动实现 的接口,该接口将调用 fragmentManager.replace(…),或者还有另一种使用新架构的方法来做到这一点?
原文由 alexpfx 发布,翻译遵循 CC BY-SA 4.0 许可协议
于 2017 年 6 月 12 日更新,
Android 官方提供了一个简单、精确的例子来说明 ViewModel 如何在 Master-Detail 模板上工作,你应该先看看它。 在片段之间共享数据
正如@CommonWare,@Quang Nguyen 所说,Yigit 的目的不是从大师到细节的调用,而是更好地使用中间人模式。但是如果你想做一些片段事务,应该在活动中完成。此时,ViewModel 类应该是 Activity 中的静态类,并且可能包含一些 Ugly Callback 来回调 Activity 以进行 Fragment 事务。
我试图实现这一点并为此做了一个简单的项目。你可以看看它。大部分代码引用自 Google IO 2017,结构也是如此。 https://github.com/charlesng/SampleAppArch
我不使用Master Detail Fragment来实现组件,而是旧的(ViewPager中的fragment之间的通信。)逻辑应该是一样的。
但我发现使用这些组件很重要
1.寻呼机活动
2.PagerAgentViewModel (它应该有一个更好的名字而不是这个)
3.空白片段A
4.空白片段B