跨Activity的Fragment间数据传递问题:SharedViewModel赋值异常
问题场景
需要将Quiz1Fragment中的goal变量传递给另一个Activity中的HomeFragment,尝试使用SharedViewModel实现,但goal始终未被正确赋值。
相关代码
Quiz1Fragment
public class Quiz1Fragment extends Fragment { private SharedViewModel sharedViewModel; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); sharedViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_quiz1, container, false); RadioGroup radioGroup = view.findViewById(R.id.radioGroup); radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { int goal = 0; if (checkedId == R.id.lose) { goal = 100; } else if (checkedId == R.id.gain) { goal = 200; } else if (checkedId == R.id.maintain) { goal = 300; } sharedViewModel.setSelectGoal(goal); } }); return view; } }
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); Integer goal = sharedViewModel.getSelectedGoal().getValue(); textView.setText(String.valueOf(goal)); return view; } }
问题原因
- ViewModel作用域不匹配:当前通过
requireActivity()获取ViewModel,意味着ViewModel的生命周期绑定在各自Fragment所在的Activity上。两个不同Activity会创建独立的ViewModel实例,数据无法跨Activity共享。 - 未观察LiveData变化:HomeFragment仅在
onCreateView时一次性获取LiveData的当前值,后续goal更新时无法触发UI刷新,即使作用域正确也无法实时显示最新值。
解决方案
1. 改用Application级别的ViewModel(实现跨Activity数据共享)
ViewModel绑定到Application生命周期,确保不同Activity的Fragment获取到同一个实例:
- 首先修改SharedViewModel继承
AndroidViewModel:
public class SharedViewModel extends AndroidViewModel { private MutableLiveData<Integer> selectedGoal = new MutableLiveData<>(); public SharedViewModel(@NonNull Application application) { super(application); } public void setSelectGoal(int goal) { selectedGoal.setValue(goal); } public LiveData<Integer> getSelectedGoal() { return selectedGoal; } }
- 在两个Fragment中修改ViewModel获取方式:
// Quiz1Fragment和HomeFragment中都用这个方式获取 sharedViewModel = new ViewModelProvider(requireActivity().getApplication()).get(SharedViewModel.class);
2. 观察LiveData实现UI实时更新
在HomeFragment中替换直接取值的逻辑,使用observe监听数据变化:
@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().getApplication()).get(SharedViewModel.class); // 监听LiveData变化,自动更新UI sharedViewModel.getSelectedGoal().observe(getViewLifecycleOwner(), goal -> { if (goal != null) { textView.setText(String.valueOf(goal)); } }); return view; }
注意事项
- 如果两个Activity是跳转关系,确保跳转前已经完成
goal的赋值操作;若需要持久化数据,可结合SharedPreferences或Room数据库补充实现。
内容的提问来源于stack exchange,提问作者Vlad Duta
相关产品推荐
相关产品推荐

