废话不多说直接上代码:
第一个ViewModel以及监听的地方
public RGMMControlPanelView(Context c, ViewGroup p, OnRGSubViewListener lis, Fragment fragment) {
super(c, p, lis);
mControlPanelViewModel = new ViewModelProvider(fragment).get(ControlPanelViewModel.class);
registerObserver(fragment);
}
public void registerObserver(Fragment fragment) {
mControlPanelViewModel
.getUpdateRoadConditionBtn()
.observe(
fragment,
new Observer<Boolean>() {
@Override
public void onChanged(Boolean show) {
updateRoadConditionBtn(show);
}
});
}
第二个ViewModel以及监听的地方,不生效的地方
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mControlPanelViewModel = new ViewModelProvider(this).get(ControlPanelViewModel.class);
mControlPanelViewModel
.getUpdateRoadConditionBtn()
.observe(
getViewLifecycleOwner(),
new Observer<Boolean>() {
@Override
public void onChanged(Boolean show) {
if (mMapControlPanel != null) {
mMapControlPanel.updateTrafficBtn();
}
}
});
}
不生效原因:初始化的方法中限定了范围
解决方法:在fragment中使用ViewModel,初始化的参数统一使用requireActivity()统一ViewModel的传递范围
mControlPanelViewModel = new ViewModelProvider(requireActivity()).get(ControlPanelViewModel.class);
ViewModelProvider 构造函数来使用 activity 范围检索
请将适当的范围与 ViewModelProvider 一起使用。在前面的示例中,MainActivity 用作 MainActivity 和 ListFragment 中的范围,因此为它们提供了相同的 ViewModel。如果 ListFragment 以自身作为范围,则其提供的 ViewModel 将与 MainActivity 不同。
注意:ViewModel 会一直在内存中,直到其范围限定到的 ViewModelStoreOwner 永久消失。在一个 activity 架构中,如果 ViewModel 的范围限定为 activity,那么它本质上是单例。首次实例化 ViewModel 之后,使用 activity 范围检索 ViewModel 的后续调用始终返回相同的现有 ViewModel 以及现有数据,直到 activity 的生命周期永久结束。
将 ViewModel 的范围限定为导航图
如果您使用的是 Navigation 库,还可以将 ViewModel 的范围限定为目的地的 NavBackStackEntry 的生命周期。例如,可以将 ViewModel 的范围限定为 ListFragment 的 NavBackStackEntry: