欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ViewModel和LiveData存储数据和传递数据

程序员文章站 2022-06-07 16:46:10
...

学习地址:

ViewModel Overview | Android Developers
https://developer.android.google.cn/topic/libraries/architecture/viewmodel

demo下载:

viewModel,liveData,lifecycle的简单使用demo-CSDN下载
https://download.csdn.net/download/baidu_31093133/10586939

开发中可能会遇到下面的问题:

1、当activity旋转屏幕的时候,我们需要重新加载数据
2、fragment之间传递数据

而使用viewModel可以很方便的解决这些问题,因为Activity重复创建的时候,持有的是同一个viewModel实例

viewModel使用:

1、创建一个类继承viewModel
2、使用liveData存储数据
3、在需要的地方接受数据变化
4、数据变化的时候在需要的地方设置新数据

下面是代码示例:
NameViewModel:

/**
 * Created by  HONGDA on 2018/8/6.
 *  A ViewModel must never reference a view, Lifecycle, or any class that may hold a reference to the activity context.
 *  viewModel不可持有view的引用或者任何持有activity上下文的类的引用
 *  如果需要Application的context的话可以继承AndroidViewModel
 *  Activity重复创建的时候,持有的是同一个viewModel实例
 */
public class NameViewModel extends ViewModel {

    //liveData通常和viewModel一起使用
    private MutableLiveData<String> mCurrentName;

    public MutableLiveData<String> getmCurrentName() {
        if (mCurrentName == null) {
            mCurrentName = new MutableLiveData<String>();
        }
        return mCurrentName;
    }

    //如果需要可以在这里释放资源
    @Override
    protected void onCleared() {
        super.onCleared();

    }

在activity里使用viewModel:

        //是ViewModelProviders而不是ViewModelProvider
        //1、获取ViewModel
        nameViewModel = ViewModelProviders.of(this).get(NameViewModel::class.java)//传入自定义viewModel的类
        //2、创建观察者
        var nameObserver: Observer<String> = Observer<String> { t -> tvName.text = t ?: "不知道" }
        //3、观察liveData的变化
        nameViewModel.getmCurrentName().observe(this, nameObserver)

当数据变化的时候,改变textview的值

效果图:hello world!是初始值,然后点击另外两个按钮使用viewModel传递不同的值
ViewModel和LiveData存储数据和传递数据
Fragment之间传值:

public class FragmentOne extends Fragment {

    private EditText edContent;
    private Button btnSend;
    private NameViewModel model;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_one, container, false);
        edContent = view.findViewById(R.id.ed_content);
        btnSend = view.findViewById(R.id.btn_send);
        //获取viewModel
        model = ViewModelProviders.of(getActivity()).get(NameViewModel.class);
        btnSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //获取到liveData后设置liveData的值
                model.getmCurrentName().setValue(edContent.getText().toString());
            }
        });
        return view;
    }
}


public class FragmentTwo extends Fragment {

    private TextView textName;
    private NameViewModel model;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_two, container, false);
        textName = view.findViewById(R.id.tv_fragment2_name);
        //获取viewModel
        model = ViewModelProviders.of(getActivity()).get(NameViewModel.class);
        //监听值的变化
        model.getmCurrentName().observe(getActivity(), new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
                if (TextUtils.isEmpty(s)) s = "哦,是个null";
                textName.setText(s);
            }
        });
        return view;
    }
}
注意,这两个fragment都在同一个activity里,ViewModelProviders.of(getActivity()),这样获取到的就是同一个viewModel,也就可以传递或保存同一份数据了

效果图:横竖屏转换,数据也不会丢失,也不需要自己手动加载数据,viewModel会把数据保存在内存里直到activity销毁。
ViewModel和LiveData存储数据和传递数据

viewModel生命周期图:
ViewModel和LiveData存储数据和传递数据

相关标签: viewModel