提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
提到双向绑定,就不得不提DataBingding,在android中,讲究视图分离,布局文件通常只负责UI控件的布局工作,页面通过setContentView方法关联布局文件,最通过UI控件的id找到控件,接着在页面中通过代码对控件进行操作,其实这也是一种最基本的MVC模式,随着业务的庞大,activity扮演了controller和view的工作,所以后来推出了MVP,MVVM模式,其中的厉害关系可以参考这篇文章,讲的尤为详细:
MVC、MVP、MVVM,我到底该怎么选?
Google在2015年I/O大会提出DataBinding,DataBinding的出现让布局文件承担了原本属于页面的工作,而LiveData和ObservableField其实就是可观察类,事实上二者可以互相替换使用,二者的区别在于:
- ObservableField只有在数据发生改变时UI才会收到通知,而LiveData不同,只要你postValue或者setValue,UI都会收到通知,不管数据有无变化。
- LiveData能感知Activity的生命周期,并在其关联的生命周期遭到销毁后进行自我清理,避免了内存泄漏。
一、LiveData实现双向绑定
关于retrofit的封装可以参考上篇文章直接使用。
LiveData+retrofit封装(Java版本)附源码
二、使用步骤
1.引入库
buildFeatures{
dataBinding = true
}
2.用LiveData观察接口,替代Call
@GET("index/login")
LiveData<LoginEntity> loginLiveData(
@Query("username") String username,
@Query("encryptPwd") String encryptPwd
);
3.写model类
public class LiveDataLoginModel {
private String username;
private String encryptPwd;
public LiveDataLoginModel(String username, String encryptPwd) {
this.username = username;
this.encryptPwd = encryptPwd;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEncryptPwd() {
return encryptPwd;
}
public void setEncryptPwd(String encryptPwd) {
this.encryptPwd = encryptPwd;
}
}
4.创建LiveData的ViewModel类
public class LiveDataViewModel extends ViewModel {
//将字段用MutableLiveData包装
public MutableLiveData<String> username = new MutableLiveData<>();
public MutableLiveData<String> encryptPwd = new MutableLiveData<>();
private MutableLiveData<LiveDataLoginModel> loginModelMutableLiveData;
//初始化获取相关LiveData对象
public MutableLiveData<LiveDataLoginModel> getLoginModelMutableLiveData() {
if (loginModelMutableLiveData == null) {
loginModelMutableLiveData = new MutableLiveData<>();
}
return loginModelMutableLiveData;
}
@Override
protected void onCleared() {
super.onCleared();
}
// 定义点击事件
public void LiveDataOnClick(View view) {
LiveDataLoginModel liveDataLoginModel = new LiveDataLoginModel(username.getValue(), encryptPwd.getValue());
//postValue和setValue区别,postValue()方法用在非UI线程,setValue用在UI线程,通过LiveData.postValue/setValue方法来修改LiveData包装的数据
loginModelMutableLiveData.postValue(liveDataLoginModel);
}
//返回retrofit接口数据
public LiveData<LoginEntity> getLiveDataLoginEntity() {
return ApiService.create(Api.class).loginLiveData(username.getValue(), RxTool.Md5(encryptPwd.getValue()));
}
}
5.修改布局文件,引入ViewModel
将最外层改为 layout布局,通过 variable引入ViewModel,将Button的 onClick属性改为:
<data>
<variable
name="liveDataViewModel"
type="com.example.mvvmgithub.viewmodel.LiveDataViewModel" />
</data>
android:onClick="@{(v)->liveDataViewModel.LiveDataOnClick(v)}"
6.修改LiveDataActivity,绑定ViewModel
activityLiveDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_live_data);
//通过ViewModelProvider得到ViewModel
liveDataViewModel = new ViewModelProvider(this).get(LiveDataViewModel.class);
activityLiveDataBinding.setLiveDataViewModel(liveDataViewModel);
然后通过LiveData.observer方法对所包装的数据进行观察
//得到ViewModel中的LiveData
final MutableLiveData<LiveDataLoginModel> liveData = liveDataViewModel.getLoginModelMutableLiveData();
//liveData.observe()观察ViewModel中数据的变化
liveData.observe(this, new Observer<LiveDataLoginModel>() {
@Override
public void onChanged(LiveDataLoginModel liveDataLoginModel) {
if (!TextUtils.isEmpty(activityLiveDataBinding.psdNicknameEdit.getText()) && !TextUtils.isEmpty(activityLiveDataBinding.psdEdit.getText())) {
LiveData<LoginEntity> liveDataLoginEntity = liveDataViewModel.getLiveDataLoginEntity();
liveDataLoginEntity.observe(LiveDataActivity.this, new Observer<LoginEntity>() {
@Override
public void onChanged(LoginEntity loginEntity) {
}
});
}
}
});
至此LiveData双向绑定功能已经实现,接下来简单介绍ObservableField双向绑定,由于我的retrofit是用LiveData封装,所以此处直接使用Call进行观察
- List item
Api如下:
@GET("index/login")
Call<LoginEntity> loginObservableField(
@Query("username") String username,
@Query("encryptPwd") String encryptPwd
);
- 修改model类
public class ObservableFieldLoginModel {
public String username;
public String encryptPwd;
}
3.修改ViewModel类
public class ObservableFieldViewModel extends ViewModel {
private ObservableField<ObservableFieldLoginModel> observableFieldLoginModelObservableField;
private static final String TAG = "PsdViewModel";
public ObservableFieldViewModel() {
ObservableFieldLoginModel ObservableFieldLoginModel = new ObservableFieldLoginModel();
observableFieldLoginModelObservableField = new ObservableField<>();
observableFieldLoginModelObservableField.set(ObservableFieldLoginModel);
}
public String getNickName() {
Log.e(TAG, "getNickName()");
return observableFieldLoginModelObservableField.get().username;
}
public String setNickName(String username) {
Log.e(TAG, "setNickName()->" + username);
return observableFieldLoginModelObservableField.get().username = username;
}
public String getPassword() {
Log.e(TAG, "getPassword()");
return observableFieldLoginModelObservableField.get().encryptPwd;
}
public String setPassword(String encryptPwd) {
Log.e(TAG, "setPassword()->" + encryptPwd);
return observableFieldLoginModelObservableField.get().encryptPwd = encryptPwd;
}
}
4.修改xml文件,并修改Activity引入ViewModel
<data>
<variable
name="observableFieldViewModel"
type="com.example.mvvmgithub.viewmodel.ObservableFieldViewModel" />
</data>
//双向绑定将@{}改为@={}
android:text="@={observableFieldViewModel.nickName}"
android:text="@={observableFieldViewModel.password}"
Activity引入ViewModel
activityPsdLoginBinding = DataBindingUtil.setContentView(this, R.layout.activity_observable_field);
observableFieldViewModel = new ObservableFieldViewModel();
activityPsdLoginBinding.setObservableFieldViewModel(observableFieldViewModel);
Demo源码
github项目地址: https://github.com/zcyyouminghuo/mvvmRetrofit
CSDN资源地址:https://download.csdn.net/download/qq_42625299/13022662