MVVM模式下RecyclerView与databinding的结合
2018-01-11 18:16
218 查看
如果不知道databinding的小伙伴,建议去了解下,非常实用,尤其是与RecyclerView等控件结合的时候,方便快捷,爱不释手。
首先看一下,传统RecyclerView和Adapter如何设置及处理数据的
User类就是一个name和age属性,R.layout.adapter_data_binding 就两个TextView展示name和age,很简单,就不展示了。
一般传统的adapter写法,就是在传入一个context和一个list,然后在自己建的ViewHolder中通过findViewById找到相关的TextView、ImageView等控件,再在onBindViewHolder中设置各种信息。如果控件多了的话,findViewById就很痛苦,虽然有ButterKnife可以减少工作量,但是还是比较麻烦。
但是如果RecyclerView是用dataBinding来处理的话,事半功倍,下面附上使用后的代码:
是不是觉得特别简洁?瞬间感觉清爽很多。使用的方式很简单,建立一个自己的adapter,继承BaseBindingAdapter,并传入两个参数,一个是list要处理的对象类User,另一个则是dataBinding所对应的R.layout.xxxx文件。通过onBindItem方法,就可以返回对应的布局和对象数据。
下面我们看看BaseBindingAdapter这个类的“庐山真面目”
其中RecyclerView最核心的两个方法onCreateViewHolder,onBindViewHolder
这个B就是传进来的R.layout.xxxx对应的dataBinding类,getLayoutResId方法返回值就是设置的R.layout.xxxx,之后触发onBindItem进行回调,返回对应的adapter布局和对象类。
这样,一个最简单的RecyclerView与databinding的结合的adapter就完成了,小伙伴们,可以直接复制BaseBindingAdapter这个类去使用。
补充说明:
在实际操作中,我们还会经常对adapter的List数据进行增删改操作,然后使用notifyDataSetChanged()方法进行更新,为了更方便的进行数据实时更新,BaseBindingAdapter中使用了ObservableArrayList这个类,这个类可以进行数据的更新监听,具体操作我附上代码
以上这段代码是我复制网上一位大神的源码,在实际的操作中,我发现notifyDataSetChanged()比notifyItemRangeChanged、notifyItemRangeInserted等方法更加实用,为此我更改了一下源码,将里面的更新item的操作都用notifyDataSetChanged取代了,小伙伴们可以根据自己的需求进行具体操作
参考资料:http://www.cnblogs.com/DoNetCoder/p/7243878.html?utm_source=tuicool&utm_medium=referral
首先看一下,传统RecyclerView和Adapter如何设置及处理数据的
RecyclerView recyclerView = dataBindingBinding.recyclerView; recyclerView.setLayoutManager(new LinearLayoutManager(this)); mList.add(new User("张三", "21")); mList.add(new User("李四", "22")); mList.add(new User("王五", "23")); mList.add(new User("赵六", "24")); MySimpleAdapter adapter = new MySimpleAdapter(this,mList); recyclerView.setAdapter(adapter);
public class MySimpleAdapter extends RecyclerView.Adapter{ private Context mContext; private List<User> mList; public MySimpleAdapter(Context context, List<User> list){ mContext = context; mList = list; } public static class SimpleViewHolder extends RecyclerView.ViewHolder { TextView name,age; SimpleViewHolder(View view) { super(view); name = (TextView) view.findViewById(R.id.textView); age = (TextView) view.findViewById(R.id.textView7); } } @Override public SimpleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { final View view = LayoutInflater.from(mContext).inflate(R.layout.adapter_data_binding, parent, false); return new SimpleViewHolder(view); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { final SimpleViewHolder mSimpleViewHolder = ((SimpleViewHolder) holder); mSimpleViewHolder.name.setText(mList.get(position).getName()); mSimpleViewHolder.age.setText(mList.get(position).getAge()); } @Override public int getItemCount() { return mList.size(); } }
User类就是一个name和age属性,R.layout.adapter_data_binding 就两个TextView展示name和age,很简单,就不展示了。
一般传统的adapter写法,就是在传入一个context和一个list,然后在自己建的ViewHolder中通过findViewById找到相关的TextView、ImageView等控件,再在onBindViewHolder中设置各种信息。如果控件多了的话,findViewById就很痛苦,虽然有ButterKnife可以减少工作量,但是还是比较麻烦。
但是如果RecyclerView是用dataBinding来处理的话,事半功倍,下面附上使用后的代码:
RecyclerView recyclerView = dataBindingBinding.recyclerView; recyclerView.setLayoutManager(new LinearLayoutManager(this)); SimpleDataBindingAdapter simpleDataBindingAdapter = new SimpleDataBindingAdapter(this); simpleDataBindingAdapter.getItems().add(new User("张三", "21")); simpleDataBindingAdapter.getItems().add(new User("李四", "22")); simpleDataBindingAdapter.getItems().add(new User("王五", "23")); simpleDataBindingAdapter.getItems().add(new User("赵六", "24")); recyclerView.setAdapter(simpleDataBindingAdapter);
public class SimpleDataBindingAdapter extends BaseBindingAdapter<User,AdapterDataBindingBinding> { public SimpleDataBindingAdapter(Context context) { super(context); } @Override protected int getLayoutResId(int viewType) { return R.layout.adapter_data_binding; } @Override protected void onBindItem(AdapterDataBindingBinding binding, User item) { binding.setUser(item); } }
是不是觉得特别简洁?瞬间感觉清爽很多。使用的方式很简单,建立一个自己的adapter,继承BaseBindingAdapter,并传入两个参数,一个是list要处理的对象类User,另一个则是dataBinding所对应的R.layout.xxxx文件。通过onBindItem方法,就可以返回对应的布局和对象数据。
下面我们看看BaseBindingAdapter这个类的“庐山真面目”
public abstract class BaseBindingAdapter<M, B extends 4000 ViewDataBinding> extends RecyclerView.Adapter { protected Context context; protected ObservableArrayList<M> items; public BaseBindingAdapter(Context context) { this.context = context; this.items = new ObservableArrayList<>(); } public ObservableArrayList<M> getItems() { return items; } public class BaseBindingViewHolder extends RecyclerView.ViewHolder { public BaseBindingViewHolder(View itemView) { super(itemView); } } @Override public int getItemCount() { return this.items.size(); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { B binding = DataBindingUtil.inflate(LayoutInflater.from(this.context), this.getLayoutResId(viewType), parent, false); return new BaseBindingViewHolder(binding.getRoot()); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { B binding = DataBindingUtil.getBinding(holder.itemView); this.onBindItem(binding, this.items.get(position)); } @LayoutRes protected abstract int getLayoutResId(int viewType); protected abstract void onBindItem(B binding, M item); }
其中RecyclerView最核心的两个方法onCreateViewHolder,onBindViewHolder
@Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { B binding = DataBindingUtil.inflate(LayoutInflater.from(this.context), this.getLayoutResId(viewType), parent, false); return new BaseBindingViewHolder(binding.getRoot()); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { B binding = DataBindingUtil.getBinding(holder.itemView); this.onBindItem(binding, this.items.get(position)); }
这个B就是传进来的R.layout.xxxx对应的dataBinding类,getLayoutResId方法返回值就是设置的R.layout.xxxx,之后触发onBindItem进行回调,返回对应的adapter布局和对象类。
这样,一个最简单的RecyclerView与databinding的结合的adapter就完成了,小伙伴们,可以直接复制BaseBindingAdapter这个类去使用。
补充说明:
在实际操作中,我们还会经常对adapter的List数据进行增删改操作,然后使用notifyDataSetChanged()方法进行更新,为了更方便的进行数据实时更新,BaseBindingAdapter中使用了ObservableArrayList这个类,这个类可以进行数据的更新监听,具体操作我附上代码
public abstract class BaseBindingAdapter<M, B extends ViewDataBinding> extends RecyclerView.Adapter {
protected Context context;
protected ObservableArrayList<M> items;
protected ListChangedCallback itemsChangeCallback;
public BaseBindingAdapter(Context context) {
this.context = context;
this.items = new ObservableArrayList<>();
this.itemsChangeCallback = new ListChangedCallback();
}
public ObservableArrayList<M> getItems() {
return items;
}
public class BaseBindingViewHolder extends RecyclerView.ViewHolder {
public BaseBindingViewHolder(View itemView) {
super(itemView);
}
}
@Override
public int getItemCount() {
return this.items.size();
}
@Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { B binding = DataBindingUtil.inflate(LayoutInflater.from(this.context), this.getLayoutResId(viewType), parent, false); return new BaseBindingViewHolder(binding.getRoot()); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { B binding = DataBindingUtil.getBinding(holder.itemView); this.onBindItem(binding, this.items.get(position)); }
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
this.items.addOnListChangedCallback(itemsChangeCallback);
}
@Override
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
super.onDetachedFromRecyclerView(recyclerView);
this.items.removeOnListChangedCallback(itemsChangeCallback);
}
//region 处理数据集变化
protected void onChanged(ObservableArrayList<M> newItems) {
resetItems(newItems);
notifyDataSetChanged();
}
protected void onItemRangeChanged(ObservableArrayList<M> newItems, int positionStart, int itemCount) {
resetItems(newItems);
notifyItemRangeChanged(positionStart, itemCount);
}
protected void onItemRangeInserted(ObservableArrayList<M> newItems, int positionStart, int itemCount) {
resetItems(newItems);
notifyItemRangeInserted(positionStart, itemCount);
}
protected void onItemRangeMoved(ObservableArrayList<M> newItems) {
resetItems(newItems);
notifyDataSetChanged();
}
protected void onItemRangeRemoved(ObservableArrayList<M> newItems, int positionStart, int itemCount) {
resetItems(newItems);
notifyItemRangeRemoved(positionStart, itemCount);
}
protected void resetItems(ObservableArrayList<M> newItems) {
this.items = newItems;
}
@LayoutRes
protected abstract int getLayoutResId(int viewType);
protected abstract void onBindItem(B binding, M item);
private class ListChangedCallback extends ObservableArrayList.OnListChangedCallback<ObservableArrayList<M>> {
@Override
public void onChanged(ObservableArrayList<M> newItems) {
BaseBindingAdapter.this.onChanged(newItems);
}
@Override
public void onItemRangeChanged(ObservableArrayList<M> newItems, int i, int i1) {
BaseBindingAdapter.this.onItemRangeChanged(newItems, i, i1);
}
@Override
public void onItemRangeInserted(ObservableArrayList<M> newItems, int i, int i1) {
BaseBindingAdapter.this.onItemRangeInserted(newItems, i, i1);
}
@Override
public void onItemRangeMoved(ObservableArrayList<M> newItems, int i, int i1, int i2) {
BaseBindingAdapter.this.onItemRangeMoved(newItems);
}
@Override
public void onItemRangeRemoved(ObservableArrayList<M> sender, int positionStart, int itemCount) {
BaseBindingAdapter.this.onItemRangeRemoved(sender, positionStart, itemCount);
}
}
}
以上这段代码是我复制网上一位大神的源码,在实际的操作中,我发现notifyDataSetChanged()比notifyItemRangeChanged、notifyItemRangeInserted等方法更加实用,为此我更改了一下源码,将里面的更新item的操作都用notifyDataSetChanged取代了,小伙伴们可以根据自己的需求进行具体操作
参考资料:http://www.cnblogs.com/DoNetCoder/p/7243878.html?utm_source=tuicool&utm_medium=referral
相关文章推荐
- 如何通过Databinding的观察者模式自动刷新RecyclerView.Adapter
- DataBinding结合RecyclerView动态加载网络数据
- android MVVM开发框架——(3)DataBinding 应用于RecyclerView
- MVVM模式下,ViewModel和View,Model有什么区别
- 安卓——RecyclerView的GridView模式如何合并grid格
- Data Binding的报错集合: 例如Error:(10, 54) 错误: 程序包com.kodulf.recyclerviewdatabinding.databinding不存在
- MVVM模式通过ViewModel实现view和model的低耦合
- AvalonDock结合MVVM模式的应用
- MVVM模式之:ViewModel Factory与注入
- wpf中使用MVVM模式进行开发,View与ViewModule的交互个人总结
- WPF学习笔记:MVVM模式下,ViewModel如何关闭View?
- MVVM模式下,ViewModel和View,Model有什么区别
- PopupWindow的简单使用(结合RecyclerView)
- RecyclerView 和 DataBinding
- SwipeRefreshLayout和RecyclerView的结合使用
- RecyclerView 结合 CardView 使用
- MVP模式的RecyclerView案例
- 如何让RAC框架融入到工程中的MVVM模式(MVVM中View和VM职责划分)
- 使用RecyclerView结合jiaozivideoplayer去加载不同类型的布局
- Android 解决RecyclerView瀑布流效果结合Glide使用时图片变形的问题