在真正接触并使用MVVM架构的时候,整我的都很差了。由于我的以为,MVVM相对于MVC、MVP学习难度比较大,设计的知识点不是一点半点。因此想慢慢记录下本身的成长。若有错误但愿指正。java
从零开始搭建MVVM架构系列文章(持续更新):
Android从零开始搭建MVVM架构(1)————DataBinding
Android从零开始搭建MVVM架构(2)————ViewModel
Android从零开始搭建MVVM架构(3)————LiveData
Android从零开始搭建MVVM架构(4)————Room(从入门到进阶)
Android从零开始搭建MVVM架构(5)————Lifecycles
Android从零开始搭建MVVM架构(6)————使用玩Android API带你搭建MVVM框架(初级篇)
Android从零开始搭建MVVM架构(7) ———— 使用玩Android API带你搭建MVVM框架(终极篇)android
仍是那张图AAC(Android Architecture Components)git
这篇咱们讲LiveData组件github
首先咱们把简单介绍下LiveData极其做用和特色。后面用例子来证实。架构
简介:LiveData 是一个有生命周期感知 & 可观察的数据持有者类
做用: 持久化的观察数据的更改与变化
特色:
一、感知对应Activity的生命周期,只有生命周期处于onStart与onResume时,LiveData处于活动状态,才会把更新的数据通知至对应的Activity
二、当生命周期处于onStop或者onPause时,不回调数据更新,直至生命周期为onResume时,当即回调
三、当生命周期处于onDestory时,观察者会自动删除,防止内存溢出
四、共享资源。可使用单例模式扩展LiveData对象以包装系统服务,以即可以在应用程序中共享它们,同时有遵照了以上生命周期框架
LiveData有2个方法通知数据改变:异步
由于要作区别,我这里先用一个TextView作标题,看起来清晰些,xml以下(若是不理解DataBinding使用的建议,从前几篇文章开始看)ide
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="onlyLive" type="String" />
</data>
<LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" >
<LinearLayout android:layout_marginTop="30dp" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content">
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="单独使用LiveData设置数据:" />
<TextView android:id="@+id/txt_only_live" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{onlyLive}" />
</LinearLayout>
</LinearLayout>
</layout>
复制代码
public class LiveDataActivity extends AppCompatActivity {
ActivityLivedataBinding binding;
private MutableLiveData<String> liveData = new MutableLiveData<>();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_livedata);
binding = DataBindingUtil.setContentView(this, R.layout.activity_livedata);
binding.setOnlyLive(liveData.getValue());
//数据改变监听
liveData.observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
binding.setOnlyLive(s);
LogUtils.i("观察LiveData", "单独使用LiveData ==> " + s);
}
});
}
@Override
protected void onStop() {
super.onStop();
liveData.postValue("单独LiveData使用");
}
}
复制代码
//一、第一个参数是LifeCycleOwner。这样也是咱们另一个组件.
// 在DataBinding篇,也说了,在26版本之后的Support库中,
// AppCompatActivity和SupportActivity中都实现了LifecycleOwner,内部已经对UI界面的生命周期作了处理了。
// 这里咱们学习的是LiveData,先暂且把他忽略调
//二、
liveData.observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
binding.setOnlyLive(s);
ToastUtils.showToast(s);
}
});
复制代码
//针对他的生命周期感知,咱们在按home键,在离开视图界面的时候给他设置数据以下。而后看效果
@Override
protected void onStop() {
super.onStop();
liveData.postValue("单独LiveData使用");
}
复制代码
效果图以下(按home键,程序进入后台后再切进去):post
看到LiveData还须要经过监听给xml设置数据。这个时候咱们会不禁的想起DataBinding的数据绑定,岂不是比他方便。那么我加上DataBinding的双向数据绑定看看。建一个测试类,用到咱们的ObservableField(不清楚的去看前几篇)学习
public class TestBean {
public final ObservableField<String> name = new ObservableField<>();
private void setName(String name) {
this.name.set(name);
}
}
复制代码
xml以下:
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="onlyLive" type="String" />
<variable name="dataBsource" type="com.lihang.viewmodelstu.bean.TestBean" />
</data>
<LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" >
<LinearLayout android:layout_marginTop="30dp" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content">
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="单独使用LiveData设置数据:" />
<TextView android:id="@+id/txt_only_live" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{onlyLive}" />
</LinearLayout>
<LinearLayout android:layout_marginTop="30dp" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content">
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="DataBinding双向数据绑定设置数据:" />
<TextView android:id="@+id/txt_dataBinding" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@={dataBsource.name}" />
</LinearLayout>
</LinearLayout>
</layout>
复制代码
Activity里,由于DataBinding的数据绑定没有观察监听,那咱们就对设置数据的textView作个监听。
public class LiveDataActivity extends AppCompatActivity {
ActivityLivedataBinding binding;
private MutableLiveData<String> liveData = new MutableLiveData<>();
private TestBean testBean = new TestBean();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_livedata);
binding = DataBindingUtil.setContentView(this, R.layout.activity_livedata);
binding.setOnlyLive(liveData.getValue());
binding.setDataBsource(testBean);
addTextViewChange();
}
private void addTextViewChange() {
binding.txtOnlyLive.addTextChangedListener(new TextWatcher() {
....//省略部分代码
@Override
public void afterTextChanged(Editable s) {
LogUtils.i("TextView的变化", "单独使用LiveData ==> " + s);
}
});
binding.txtDataBinding.addTextChangedListener(new TextWatcher() {
....//省略部分代码
@Override
public void afterTextChanged(Editable s) {
LogUtils.i("TextView的变化", "DataBinding双向绑定 ==> " + s);
}
});
}
@Override
protected void onStop() {
super.onStop();
liveData.postValue("单独LiveData使用");
testBean.name.set("我是DataBinding双向绑定");
}
}
复制代码
一样在离开界面的时候设置下数据:
效果图以下(咱们看打印):
上篇提到了LifecycleOwner。即便LiveData配合ViewModel使用,也要经过它来省去每次数据改变的监听
怎么用呢?
关键就是给咱们的DataBingding设置LifecycleOwner:binding.setLifecycleOwner(this);
来看咱们的ViewModel
public class LiveDataViewModel extends ViewModel {
private MutableLiveData<String> nameLiveData = new MutableLiveData<>();
public MutableLiveData<String> getData() {
return nameLiveData;
}
}
复制代码
xml里再加上一条显示ViewModel的数据
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="onlyLive" type="String" />
<variable name="dataBsource" type="com.lihang.viewmodelstu.bean.TestBean" />
<variable name="liveViewModel" type="com.lihang.viewmodelstu.viewmodel.LiveDataViewModel" />
</data>
<LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" >
<LinearLayout android:layout_marginTop="30dp" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content">
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="单独使用LiveData设置数据:" />
<TextView android:id="@+id/txt_only_live" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{onlyLive}" />
</LinearLayout>
<LinearLayout android:layout_marginTop="30dp" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content">
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="DataBinding双向数据绑定设置数据:" />
<TextView android:id="@+id/txt_dataBinding" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@={dataBsource.name}" />
</LinearLayout>
<LinearLayout android:layout_marginTop="30dp" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content">
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="ViewModel配合LiveData设置数据:" />
<TextView android:id="@+id/txt_viewmodel_livedata" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{liveViewModel.data}" />
</LinearLayout>
</LinearLayout>
</layout>
复制代码
Activity里:
public class LiveDataActivity extends AppCompatActivity {
ActivityLivedataBinding binding;
private MutableLiveData<String> liveData = new MutableLiveData<>();
private TestBean testBean = new TestBean();
private LiveDataViewModel model;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_livedata);
binding = DataBindingUtil.setContentView(this, R.layout.activity_livedata);
binding.setOnlyLive(liveData.getValue());
binding.setDataBsource(testBean);
//本节重点是下面2句代码哦
binding.setLifecycleOwner(this);
model = ViewModelProviders.of(this).get(LiveDataViewModel.class);
binding.setLiveViewModel(model);
addLiveObserve();
addTextViewChange();
}
private void addTextViewChange() {
binding.txtOnlyLive.addTextChangedListener(new TextWatcher() {
...//省略
@Override
public void afterTextChanged(Editable s) {
LogUtils.i("TextView的变化", "单独使用LiveData ==> " + s);
}
});
binding.txtDataBinding.addTextChangedListener(new TextWatcher() {
...//省略
@Override
public void afterTextChanged(Editable s) {
LogUtils.i("TextView的变化", "DataBinding双向绑定 ==> " + s);
}
});
binding.txtViewmodelLivedata.addTextChangedListener(new TextWatcher() {
...//省略
@Override
public void afterTextChanged(Editable s) {
LogUtils.i("TextView的变化", "ViewModel配合LiveData使用 ==> " + s);
}
});
}
private void addLiveObserve() {
liveData.observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
//单独使用的仍是须要监听哦!
binding.setOnlyLive(s);
}
});
}
@Override
protected void onStop() {
super.onStop();
liveData.postValue("单独LiveData使用");
testBean.name.set("我是DataBinding双向绑定");
model.getData().postValue("ViewModel配合LiveData使用");
}
}
复制代码
咱们经过model.getData().postValue("ViewModel配合LiveData使用");去改变ViewModel里的数据,看结果: