You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

跨Activity的Fragment间数据传递问题:SharedViewModel赋值异常

问题排查:跨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;
}
}

问题原因

  1. ViewModel作用域不匹配:当前通过requireActivity()获取ViewModel,意味着ViewModel的生命周期绑定在各自Fragment所在的Activity上。两个不同Activity会创建独立的ViewModel实例,数据无法跨Activity共享。
  2. 未观察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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 21:12:58