欢迎加入技术谈论群:714476794
一、前言
这篇文章适合了解了Mvp和DataBinding的童鞋,可以搜索相关文章查阅了解Mvp和DataBinding再来看这篇文章。
二、背景
以前开发Android就是拿起键盘就是干,就是传统的Mvc模式,毫无疑问,后期项目维护成本会很高,基本一个Activity都是成百上千行代码,及其恶心,View与Model耦合度强,所以使用Mvp可以使Model和View完全解耦,通过Presenter中间层通讯获取数据并显示,但是还是有问题,Activity在Mvp中充当View,View获取数据后还是要把数据显示在xml文件上,所以Activity代码同样恶心。有没有更好的办法呢,办法当然有,那就是Mvvm中使用的DataBinding,他可以实现数据绑定。接下来直接上代码。
三、实战
模拟从网络获取用户数据并显示在界面上:
项目结构:
UserInfo类
/**
* Author KINCAI
* .
* description TODO
* .
* Time 2016-12-12 10:01
*/
public class UserInfo extends BaseObservable {
private String name;
private String nickName;
private String sex;
private String age;
@Bindable
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
notifyPropertyChanged(BR.name);
}
@Bindable
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
notifyPropertyChanged(BR.nickName);
}
@Bindable
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
notifyPropertyChanged(BR.sex);
}
@Bindable
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
notifyPropertyChanged(BR.age);
}
@Override
public String toString() {
return "UserInfo{" +
"name='" + name + '\'' +
", nickName='" + nickName + '\'' +
", sex='" + sex + '\'' +
", age='" + age + '\'' +
'}';
}
}
IUserMode接口
/**
* Author KINCAI
* .
* description TODO
* .
* Time 2016-12-12 9:51
*/
public interface IUserModel {
/**
* 获取用户数据
*/
void loadUserData(onLoadListener listener);
interface onLoadListener{
void onError();
void onSuccess(UserInfo userInfo);
}
}
UserModel类 实现IUserModel加载数据
/**
* Author KINCAI
* .
* description TODO
* .
* Time 2016-12-12 9:53
*/
public class UserModel implements IUserModel {
@Override
public void loadUserData(onLoadListener listener) {
//模拟网络获取数据
UserInfo userInfo = new UserInfo();
userInfo.setName("张三");
userInfo.setNickName("小二");
userInfo.setSex("男");
userInfo.setAge("20");
listener.onSuccess(userInfo);
}
}
IUserView接口 用户activity实现
/**
* Author KINCAI
* .
* description TODO
* .
* Time 2016-12-12 9:54
*/
public interface IUserView {
void onError();
void onSuccess(UserInfo userInfo);
}
UserPresenter 类 负责UserModel和View的通信(中间层)
/**
* Author KINCAI
* .
* description user presenter presenter持有IUserModel 和 IUserView的引用
* .
* Time 2016-12-12 9:55
*/
public class UserPresenter {
IUserModel iUserModel = new UserModel();
IUserView iUserView;
public UserPresenter(IUserView iUserView) {
this.iUserView = iUserView;
}
/**
* 取数据
*/
public void fetchUserData(){
if(iUserModel != null) {
iUserModel.loadUserData(new IUserModel.onLoadListener() {
@Override
public void onError() {
iUserView.onError();
}
@Override
public void onSuccess(UserInfo userInfo) {
iUserView.onSuccess(userInfo);
}
});
}
}
}
UserPresenter 持有UserModel和IUserView的引用,从而实现中间层数据交接功能 View和Model并没有直接交互,已完全解耦。
Activity实现IUserView并实例化UserPresenter类 点击获取用户数据的时候 调用UserPresenter的fetchUserData方法并在presenter类中调用UserModel的loadUserData加载数据,最后回调给Activity
Activity代码:
/**
* Author KINCAI
* .
* description 用户信息
* .
* Time 2016-12-12 9:50
*/
public class UserInfoActivity extends AppCompatActivity implements IUserView {
private ActivityMainBinding mBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//使用DataBinding绑定
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
mBinding.setUserInfoListener(new UserInfoListener());
}
@Override
public void onError() {
Log.e("UserInfoActivity","error ");
}
@Override
public void onSuccess(UserInfo userInfo) {
Log.e("UserInfoActivity","success "+userInfo.toString());
//设置数据
mBinding.setUserInfo(userInfo);
}
/**
* dataBinding绑定的点击事件类
*/
public class UserInfoListener {
public void onLoadUser(View view) {
//实例化userPresenter类获取数据
new UserPresenter(UserInfoActivity.this).fetchUserData();
}
}
}
xml代码:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="userInfo"
type="com.kincai.mvpdatabinding.viewmodel.UserInfo" />
<variable
name="UserInfoListener"
type="com.kincai.mvpdatabinding.UserInfoActivity.UserInfoListener" />
</data>
<LinearLayout
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:orientation="vertical">
<!--姓名-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{`name:`+(userInfo.name ?? `未知`)}"
android:textSize="18sp" />
<!--昵称-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{`nickname:`+(userInfo.nickName ?? `未知`)}"
android:textSize="18sp" />
<!--性别-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{`sex:`+(userInfo.sex?? `未知`)}"
android:textSize="18sp" />
<!--年龄-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{`age:`+(userInfo.age ?? `未知`)}"
android:textSize="18sp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{UserInfoListener.onLoadUser}"
android:text="获取用户数据" />
</LinearLayout>
</layout>
Activity中onSuccess回调方法用dataBinding设置数据,很简单搞定,并不需要找到控件一个一个设置数据,这里已经交给ViewModel处理了。
效果演示:
demo下载
csdn:http://download.csdn.net/detail/hqiong208/9709066
四、总结
使用过mvp模式和databinding的童鞋轻而易举的就能写出来,对于不了解的可以先去了解。此文仅供学习参考,有什么问题可以留言。