Activity 中的两个或更多 Fragment 须要互相通信是一种很常见的状况。
设想一下主从 Fragment 的常见状况,假如有一个 Fragment,在该 Fragment 中,用户从列表中抉择一项,还有另一个 Fragment,用于显示选定项的内容。
这种状况不太容易解决,因为这两个 Fragment 都须要定义某种接口形容,并且所有者 Activity 必须将两者绑定在一起。此外,这两个 Fragment 都必须解决另一个 Fragment 尚未创立或不可见的状况。
能够应用 ViewModel 对象解决这一常见的难点。这两个 Fragment 能够应用其 Activity 范畴共享 ViewModel 来解决此类通信,如以下示例代码所示:
public class SharedViewModel extends ViewModel {private final MutableLiveData<Item> selected = new MutableLiveData<Item>();
public void select(Item item) {selected.setValue(item);
}
public LiveData<Item> getSelected() {return selected;}
}
public class MasterFragment extends Fragment {
private SharedViewModel model;
public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
itemSelector.setOnClickListener(item -> {model.select(item);
});
}
}
public class DetailFragment extends Fragment {public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
model.getSelected().observe(this, { item ->
// Update the UI.
});
}
}
请留神,这两个 Fragment 都会检索蕴含它们的 Activity。这样,当这两个 Fragment 各自获取 ViewModelProvider 时,它们会收到雷同的 SharedViewModel 实例(其范畴限定为该 Activity)。
此办法具备以下劣势:
- Activity 不须要执行任何操作,也不须要对此通信有任何理解。
- 除了 SharedViewModel 约定之外,Fragment 不须要相互了解。如果其中一个 Fragment 隐没,另一个 Fragment 将持续照常工作。
- 每个 Fragment 都有本人的生命周期,而不受另一个 Fragment 的生命周期的影响。如果一个 Fragment 替换另一个 Fragment,界面将持续工作而没有任何问题。
ViewModelProviders 示例
注:ViewModelProviders 已 Deprecated
activity
MyAppViewModelFactory factory = MyAppViewModelFactory.getInstance(getApplication());
ViewModelProviders.of(this, factory).get(VM.class);
fragment
MyAppViewModelFactory factory = MyAppViewModelFactory.getInstance(getActivity().getApplication());
ViewModelProviders.of(getActivity(), factory).get(VM.class);
activity 和 fragment 拿到的是同一个 vm。这表明一个 activity 和多个 fragment 能够应用同一个 vm,由同一个 vm 来治理数据。
Fragment 相干面试题
【Android 框架源码解析视频】
【Android 大厂面试题精讲视频】