使用SharedViewModel在Fragment间传值时goal值为null的问题排查
问题分析
你的问题核心在于没有正确监听LiveData的变化,同时LiveData初始值为null:
- HomeFragment仅在
onCreateView时一次性获取LiveData的当前值,而此时Quiz1Fragment还未设置goal,所以拿到的是null,导致TextView显示null。 - 当后续Quiz1Fragment设置goal值时,HomeFragment没有监听LiveData的更新,因此UI不会同步变化。
解决方案
1. 在HomeFragment中监听LiveData的变化
使用LiveData.observe()方法,让HomeFragment在LiveData值发生变化时自动更新UI,而不是只获取一次即时值:
修改后的HomeFragment代码:
public class HomeFragment extends Fragment { TextView textView; SharedViewModel sharedViewModel; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_home, container, false); textView = view.findViewById(R.id.textViewCalories); sharedViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class); // 监听LiveData变化,自动更新UI sharedViewModel.getSelectedGoal().observe(getViewLifecycleOwner(), goal -> { // 处理null情况,避免空指针 if (goal != null) { textView.setText(String.valueOf(goal)); } else { textView.setText("未设置目标"); // 替换为你需要的默认提示文本 } }); return view; } }
2. 可选:给LiveData设置初始默认值
如果希望一开始就显示默认值而非null,可以在SharedViewModel中初始化LiveData时设置默认值:
修改后的SharedViewModel代码:
public class SharedViewModel extends ViewModel { // 初始化时设置默认值,比如0或者其他符合业务逻辑的数值 private MutableLiveData<Integer> selectGoal = new MutableLiveData<>(0); public void setSelectGoal(int goal){ Log.d("SharedViewModel", "Setting goal in SharedViewModel: " + goal); selectGoal.setValue(goal); } public LiveData<Integer> getSelectedGoal(){ return selectGoal; } }
关键说明
getViewLifecycleOwner():绑定Fragment的视图生命周期,既可以避免内存泄漏,又能在Fragment视图销毁时自动移除观察者。- LiveData的
observe()方法会在值变化时触发回调,包括初始值(如果设置了的话),确保UI能实时同步数据更新。
内容的提问来源于stack exchange,提问作者Vlad Duta
相关产品推荐
相关产品推荐

