版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/suwenlai/article/details/74456664
最近打算项目重构 打算使用mvvm模式 试着写了一个recyclerview在mvvm模式下的通用adapter 用起来清爽 痛快
package demo.xinchuang.com.mvvmdemo;
import android.content.Context;
import android.databinding.DataBindingUtil;
import android.databinding.ViewDataBinding;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.List;
/**
* RecyclerView 通用的 Adapter
* <p>
* Created by suwenlai on 16-12-27.
*/
public class MvvmCommonAdapter extends RecyclerView.Adapter<MvvmCommonAdapter.CommonHolder> {
protected Context mContext;
//所有 item 的数据集合
protected List mDatas;
//item 布局文件 id
protected int mLayoutId;
protected LayoutInflater mInflater;
// mvvm绑定的viewModel引用
private int mVariableId;
//构造方法
public MvvmCommonAdapter(List datas, int variableId, Context context, int layoutId) {
mContext = context;
mDatas = datas;
mLayoutId = layoutId;
mInflater = LayoutInflater.from(mContext);
mVariableId = variableId;
}
public List getmDatas() {
return mDatas;
}
public void setmDatas(List mDatas) {
this.mDatas = mDatas;
}
@Override
public CommonHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ViewDataBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), mLayoutId, parent, false);
CommonHolder myHolder = new CommonHolder(binding.getRoot());
myHolder.setBinding(binding);
return myHolder;
}
@Override
public void onBindViewHolder(CommonHolder holder, int position) {
holder.binding.setVariable(mVariableId,mDatas.get(position));
holder.binding.executePendingBindings();
}
@Override
public int getItemCount() {
return null == mDatas ? 0 : mDatas.size();
}
class CommonHolder extends RecyclerView.ViewHolder {
private ViewDataBinding binding;
public CommonHolder(View itemView) {
super(itemView);
}
public ViewDataBinding getBinding() {
return binding;
}
public void setBinding(ViewDataBinding binding) {
this.binding = binding;
}
}
}
使用方法很简单
list.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
list.setAdapter(new MvvmCommonAdapter(mData,BR.myUser,this,R.layout.second_adapter));
刚才有评论问了BR是什么 BR 是编译阶段生成的一个类,功能与 R.java 类似
因为如果myUser的里面的数据有变化了 无法同步更新空间
所以这里使myUser继承BaseObservable,用 @Bindable 标记过 getter 方法,会在BR生成该字段标识
然后set方法里添加notifyPropertyChanged(BR.field);
当数据发生变化时还是需要手动发出通知。 通过调用notifyPropertyChanged(BR.field)来通知系统BR.field 的数据已经发生变化,需要更新view
public class myUser extends BaseObservable {
private String nickName;
private String userface;
private String userName;
private String age;
public User(String nickName, String userface, String userName, String age) {
this.nickName = nickName;
this.userface = userface;
this.userName = userName;
this.age = age;
}
public User() {
}
@Bindable
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
notifyPropertyChanged(BR.nickName);
}
@Bindable
public String getUserface() {
return userface;
}
public void setUserface(String userface) {
this.userface = userface;
notifyPropertyChanged(BR.userface);
}
@Bindable
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
notifyPropertyChanged(BR.age);
}
@Bindable
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
notifyPropertyChanged(BR.userName);
}
}
还有一种方法是 通过ObserableField来实现
public class PlainUser {
public final ObservableField<String> firstName = new ObservableField<>();
public final ObservableField<String> nickName= new ObservableField<>();
public final ObservableInt age = new ObservableInt();
}
具体使用方法可以百度一下
xml文件
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="myUser"
type="demo.xinchuang.com.mvvmdemo.UserEntity"/>
</data>
<LinearLayout
android:onClick="@{myUser.onItemClick}"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
app:imageUrl="@{myUser.userface}"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content" />
<TextView
android:text="@{myUser.nickName}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:layout_width="0dp"
android:text="@{myUser.userName}"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:layout_width="0dp"
android:text="@{String.valueOf(myUser.age)}"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
</layout>