Viewmodel可以更好地帮助我们将页面与数据从代码上层面上分离开来。使用ViewModel不再需要关心屏幕旋转带来的数据丢失问题。

livedata是一个可被观察的数据容器类,使得数据变成变成被观察者,当数据发生变化时,观察者能够获得通知。

基本使用

添加依赖

    def lifecycle_version = "2.5.1"

    implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
    // LiveData
    implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"

创建ViewModel与LiveData

public class MyViewModel extends ViewModel {

    private MutableLiveData<Integer> progress;


    public LiveData<Integer> getCurProgress() {


        if (progress == null) {

            progress = new MutableLiveData<>();
        }
        return progress;
    }


}

在activity使用,当progress改变时,调用onChanged。

        MyViewModel myViewModel = new ViewModelProvider(this).get(MyViewModel.class);
        MutableLiveData<Integer> data = (MutableLiveData<Integer>) myViewModel.getCurProgress();
        data.observe(this, new Observer<Integer>() {
            @Override
            public void onChanged(Integer integer) {

            }
        });

    }

onChanged会不会在页面销毁后执行?LiveData能够感知页面的声明周期,所以只有页面处于激活状态才会触发
onChanged,在页面销毁时,onChanged不会触发。但使用LiveData.observeForever是个特例,不过页面处于哪种状态,都会调用onChanged方法,所以使用observeForever,得调用removeObserver()来移除观察。

利用ViewModel和LiveData实现fragment间通信

同一个activity中的fragment共享数据。在布局文件中放置两个fragment,这两个fragment的功能是一样的,都是放置了seekbar。控制其中一个另一个也变化,需要注意的是,ViewModelProvider中的第一个参数要 传requireActivity()。

   两个fragment功能是一样的,
    SeekBar seekBar = view.findViewById(R.id.a_sb);


        MyViewModel myViewModel = new ViewModelProvider(requireActivity()).get(MyViewModel.class);
        MutableLiveData<Integer> progressLiveData = (MutableLiveData<Integer>) myViewModel.getCurProgress();
        progressLiveData.observe(getViewLifecycleOwner(), new Observer<Integer>() {
            @Override
            public void onChanged(Integer integer) {

                seekBar.setProgress(integer);
            }
        });


        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

                progressLiveData.setValue(progress);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

效果
在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐