多个ViewModel进行observe监听无效不执行的bug

废话不多说直接上代码:

第一个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);

 参考资料:与fragment通信

 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:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
多个Fragment之间共享ViewModel,可以使用以下步骤: 1. 创建一个ViewModel类,该类包含需要共享的数据和方法。 ```java public class SharedViewModel extends ViewModel { private MutableLiveData<String> selected = new MutableLiveData<String>(); public void select(String item) { selected.setValue(item); } public LiveData<String> getSelected() { return selected; } } ``` 2. 在需要共享ViewModel的Fragment中,通过ViewModelProvider获取ViewModel实例。 ```java public class Fragment1 extends Fragment { private SharedViewModel model; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class); } // ... } ``` 3. 在其他需要访问ViewModel的Fragment中,也通过ViewModelProvider获取同一个ViewModel实例。 ```java public class Fragment2 extends Fragment { private SharedViewModel model; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class); } // ... } ``` 4. 在Fragment中使用ViewModel中的数据和方法。这样就可以在多个Fragment之间共享ViewModel了。 ```java public class Fragment1 extends Fragment { private SharedViewModel model; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment1, container, false); Button button = view.findViewById(R.id.button); final EditText editText = view.findViewById(R.id.editText); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { model.select(editText.getText().toString()); } }); return view; } } public class Fragment2 extends Fragment { private SharedViewModel model; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment2, container, false); final TextView textView = view.findViewById(R.id.textView); model.getSelected().observe(getViewLifecycleOwner(), new Observer<String>() { @Override public void onChanged(String item) { textView.setText(item); } }); return view; } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值