如何在 Android 中通过 ViewModel 类在 Activity 和 Fragment 之间共享数据?

3 android mvvm viewmodel android-livedata mutablelivedata

我想知道是否可以传递在 Activity 类中声明的 String 数据并将 String 数据传递给 ViewModel 类,然后将数据传递给 Fragment 类。

视图模型类

class TimeTableViewModel extends ViewModel {

private MutableLiveData<String> start_time_str = new MutableLiveData<>();

void send_StartTime(String start_Time){
    start_time_str.setValue(start_Time);
}

LiveData<String> get_StartTime(){
    return start_time_str;
}}
Run Code Online (Sandbox Code Playgroud)

在 ViewModel 类中,我MutableLiveData<String> start_time_str已经初始化为new MutableLiveData<>();

我想void send_StartTime(String start_Time)在 Activity 类中使用函数来设置参数的值String start_Time并调用start_time_strFragment 类。

活动课

@Override
public boolean onOptionsItemSelected(MenuItem item){
    switch (item.getItemId()){
        case android.R.id.home:
            finish();
            break;
        case R.id.add_schedule_save:
            String start_time_str = startTime.getText().toString();
            Intent intent_restart0 = new Intent(TimeTable_Add_New_Schedule.this, MainActivity.class);
            startActivity(intent_restart0);
            TimeTableViewModel timeTableViewModel = new TimeTableViewModel();
            timeTableViewModel.send_StartTime(start_time_str);
            Toast.makeText(this,""+start_time_str,Toast.LENGTH_LONG).show();
            break;
    }
    return super.onOptionsItemSelected(item);
}
Run Code Online (Sandbox Code Playgroud)

片段类

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    TimeTableViewModel timeTableViewModel = new TimeTableViewModel();
    timeTableViewModel.get_StartTime().observe(getViewLifecycleOwner(), new Observer<String>() {
        @Override
        public void onChanged(String s) {
            mon_textView_11.setText(s);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

在 Fragment 类中,我调用get_StartTime()函数来获取start_time_str并将 String 值设置为我的 TextView。我认为Activity 类中的start_time_str函数已成功设置,timeTableViewModel.send_StartTime(start_time_str);因为 Toast.maketext 就像一个魅力。但是 TextView 没有显示任何内容。我已经测试过文本颜色不是白色,因此如果正确调用字符串值,它应该出现在屏幕上。如果您有任何建议,我很想听听您的建议。非常感谢。

在此处输入图片说明

BVa*_*tur 10

这实际上取决于您如何创建ViewModel实例。现在您正在ViewModel通过其构造函数创建,但这不是正确的方法。您应该使用ViewModelProvider或扩展由 Google 团队创建的方法。

如果你和你一起去,ViewModelProvider你应该这样做:

TimeTableViewModel viewModel = new ViewModelProvider(this).get(TimeTableViewModel.class);
Run Code Online (Sandbox Code Playgroud)

将正确的上下文传递给ViewModelProvider构造函数调用很重要。如果您在片段中并且您将只使用getContext()而不是getActivity(),您将不会获得与在活动中创建的实例相同的实例。您将创建一个 的新实例ViewModel,该实例的范围仅在片段生命周期内。因此,重要的是在两个部分的活动上下文中使用以获取相同的实例。

活动部分:

TimeTableViewModel viewModel = new ViewModelProvider(this).get(TimeTableViewModel.class);
Run Code Online (Sandbox Code Playgroud)

片段部分:

TimeTableViewModel viewModel = new ViewModelProvider(getActivity()).get(TimeTableViewModel.class);
Run Code Online (Sandbox Code Playgroud)

重要的是您的片段位于使用 this 的同一活动中ViewModel

但是谷歌的人通过一些扩展方法让我们更容易。但据我所知,他们只在 Kotlin 课程中工作。所以如果你有 Kotlin 代码,你可以ViewModel像这样声明你的:

private val quizViewModel: TimeTableViewModel by activityViewModels()
Run Code Online (Sandbox Code Playgroud)

对于片段范围,ViewModel您需要编写如下内容:

private val quizViewModel: TimeTableViewModel by viewModels()
Run Code Online (Sandbox Code Playgroud)

但是您必须将 Kotlin ktx 依赖项添加到您的项目build.gradle文件中。例如像这样:

implementation 'androidx.fragment:fragment-ktx:1.1.0'
Run Code Online (Sandbox Code Playgroud)

  • 如果您使用导航组件,您还可以通过导航图来确定 ViewModel 的范围,如下所示:“val myViewModel: TimeTableViewModel by navGraphViewModels(R.id.navigation_graph)”。很高兴我能帮上忙。:) (2认同)

mhK*_*ami 8

如果您正在使用 Android 架构并希望activityViewModel在您的fragments.

viewModels使用fragment以下代码:

private val fragmentViewModel: Fragment1ViewModel by viewModels()
private val activityViewModel: MainActivityViewModel by activityViewModels()
Run Code Online (Sandbox Code Playgroud)

MainActivity使用下面的代码:

private val activityViewModel: MainActivityViewModel by viewModels()
Run Code Online (Sandbox Code Playgroud)

  • 第一行代码是否有误导性?您将无法使用“private valfragmentViewModel: Fragment1ViewModel by viewModels()”访问 Activity 中的 ViewModel 设置 (2认同)