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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_31093133/article/details/81457535

学习地址:

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
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

viewModel生命周期图:
viewModel

猜你喜欢

转载自blog.csdn.net/baidu_31093133/article/details/81457535