特殊需求:
如果有特殊需求,可传入两个泛型,重写onBindViewHolder搞事情:
// ★泛型D:是Bean类型,如果有就传。 泛型B:是对应的xml Layout的Binding类
mAdapter = new BaseBindingAdapter<DBSingleBean, ItemDbSingleBinding>(this, mDatas, R.layout.item_db_single) {
@Override
public void onBindViewHolder(BaseBindingVH holder, int position) {
//★super一定不要删除
super.onBindViewHolder(holder, position);
//如果有特殊需求,可传入两个泛型,重写onBindViewHolder搞事情。
ItemDbSingleBinding binding = holder.getBinding();
DBSingleBean data = mDatas.get(position);
}
};
2 多Item同种数据类型列表
一般是像IM那种列表,虽然Item不同,但是数据结构是同一个。用法,一句话~
效果如图:
用法:
-
数据结构(JavaBean)需实现
IBaseMulInterface
接口,根据情况返回不同的layout。 -
构造函数只需要传入context,datas.
mAdapter = new BaseMulTypeBindingAdapter(this, mDatas);
复杂列表依然一句话。
public class MulTypeSingleBean extends BaseObservable implements IBaseMulInterface {
private String avatar;
private String name;
private boolean receive;
@Override
public int getItemLayoutId() {
if (isReceive()) {
return R.layout.item_db_mul_1;
} else {
return R.layout.item_db_mul_2;
}
}
}
特殊需求:
如果有特殊需求,可传入数据结构的泛型,避免强转,重写onBindViewHolder()
方法,但是Binding类 不可避免的需要强转了:
mAdapter = new BaseMulTypeBindingAdapter(this, mDatas) {
@Override
public void onBindViewHolder(BaseBindingVH holder, int position) {
super.onBindViewHolder(holder, position);
//如果有特殊需求,可传入数据结构的泛型,避免强转
MulTypeSingleBean data = mDatas.get(position);
//Binding类 不可避免的需要强转了
ViewDataBinding binding = holder.getBinding();
switch (data.getItemLayoutId()) {
case R.layout.item_db_mul_1:
ItemDbMul1Binding itemDbMul1Binding = (ItemDbMul1Binding) binding;
break;
case R.layout.item_db_mul_2:
ItemDbMul2Binding itemDbMul2Binding = (ItemDbMul2Binding) binding;
break;
}
}
};
3 多Item、多种数据类型列表
各大APP首页,Banner、列表、推荐混排,数据结构肯定不同,但是依然只要一句代码搞定Adapter!
效果如图:
用法:
-
数据结构(JavaBean)需分别实现
IBaseMulInterface
接口,返回数据结构对应的layout。 -
构造函数只需要传入context,datas.
mAdapter = new BaseMulTypeBindingAdapter(this, mDatas);
public class MulTypeMulBean1 extends BaseObservable implements IBaseMulInterface {
private String avatar;
private String name;
@Override
public int getItemLayoutId() {
return R.layout.item_db_mulbean_1;
}
}
public class MulTypeMulBean2 extends BaseObservable implements IBaseMulInterface {
private String background;
@Override
public int getItemLayoutId() {
return R.layout.item_db_mulbean_2;
}
}
特殊需求:
如果有特殊需求,重写onBindViewHolder()
方法,但是数据结构 和 Binding类 都不可避免的需要强转了:
mAdapter = new BaseMulTypeBindingAdapter(this, mDatas) {
@Override
public void onBindViewHolder(BaseBindingVH holder, int position) {
super.onBindViewHolder(holder, position);
//如果有特殊需求 重写onBindViewHolder方法
// 数据结构 和 Binding类 都不可避免的需要强转了
ViewDataBinding binding = holder.getBinding();
switch (getItemViewType(position)) {
case R.layout.item_db_mul_1:
ItemDbMul1Binding itemDbMul1Binding = (ItemDbMul1Binding) binding;
MulTypeMulBean1 data1 = (MulTypeMulBean1) mDatas.get(position);
break;
case R.layout.item_db_mul_2:
ItemDbMul2Binding itemDbMul2Binding = (ItemDbMul2Binding) binding;
MulTypeMulBean2 data2 = (MulTypeMulBean2) mDatas.get(position);
break;
}
}
};
4 不能忘了上文的ViewGroup呀
对上文封装的ViewGroup类型Adapter也提供DataBinding的支持。
效果如图:
当然还是流式布局搭配史上集成最叼侧滑菜单控件。
用法:
和上文快速开发偷懒必备(一)一样,只是Adapter换成SingleBindingAdapter
mAdapter = new SingleBindingAdapter<>(this, mDatas = iniDatas(), R.layout.item_db_flow_swipe);
如果需要设置点击事件:
mAdapter.setItemPresenter(new ItemDelPresenter());
设计思路与实现
使用起来如此爽快,其实写起来也很简单。
注意类BaseBindingAdapter
和BaseMulTypeBindingAdapter
都不是abstract
的,这说明我们不需要重写任何方法。
利用DataBinding,我们在BasexxxAdapter内部和xml分别做View的创建和数据绑定的工作。
UML类图
先简要概括
-
BaseBindingVH
继承自RecyclerView.ViewHolder
,持有T extends ViewDataBinding
类型的mBinding
变量。利用ViewDataBinding
我们将不用再写任何ViewHolder
。 -
BaseBindingAdapter
,继承自RecyclerView.Adapter
,依赖BaseBindingVH
,onCreateViewHolder(ViewGroup parent, int viewType)
方法返回BaseBindingVH
作为ViewHolder
。
内部持有三个重要变量:数据对应layout,数据集,Item点击事件处理类。数据对应layout会在onCreateViewHolder(ViewGroup parent, int viewType)
用到。剩下两个变量在onBindViewHolder()
用到。对外暴漏setItemPresenter(Object itemPresenter)
供设置点击事件处理类。
-
IBaseMulInterface
接口和快速开发偷懒必备(一)提到的一样,返回某个数据结构对应的layout,除此之外,本文还有一个十分tricky之处,利用返回的R.layout.itemxxxx
作为ItemViewType
,在BaseMulTypeBindingAdapter
会用到。 -
BaseMulTypeBindingAdapter
继承自BaseBindingAdapter
,但是它不再关心mLayoutId
变量,它利用IBaseMulInterface
接口返回的R.layout.itemxxxx
作为ItemViewType
,这样在onCreateViewHolder(ViewGroup parent, int viewType)
的时候,就可以直接用viewType
构造出ItemView
。不再依赖mLayoutId
变量。这是一个我很得意的设计,我在优雅为RecyclerView增加HeaderView一文中,也曾用过这个方法。
BaseBindingVH
BaseBindingVH
算是一个核心类,但是又十分简单。它继承自RecyclerView.ViewHolder
,持有由泛型传入的T extends ViewDataBinding
类型的mBinding
变量。
唯一构造函数,需要一个T t
变量,然后调用super()
传入t.getRoot()
完成itemView
的赋值。同时对mBinding
变量赋值。
对外暴漏getBinding()
返回mBinding
变量。
利用ViewDataBinding
我们将不用再写任何ViewHolder
。
public class BaseBindingVH extends RecyclerView.ViewHolder {
protected final T mBinding;
public BaseBindingVH(T t) {
super(t.getRoot());
mBinding = t;
}
public T getBinding() {
return mBinding;
}
}
BaseBindingAdapter
BaseBindingAdapter
,继承自RecyclerView.Adapter
,依赖BaseBindingVH
,将BaseBindingVH
作为泛型传给RecyclerView.Adapter
。
同时BaseBindingAdapter
本身接受两个泛型,<D, B extends ViewDataBinding>
。
-
泛型没有特殊需求可以不传
-
泛型D:是Bean类型,如果有就传。
-
泛型B:是对应的xml Layout的Binding类
传入不传入泛型的区别已经在第二节具体用法里进行了演示,不再赘述。
内部持有三个重要变量:
-
数据对应layout
int mLayoutId;
-
数据集
List<D> mDatas;
-
Item点击事件处理类。
Object ItemPresenter;
mLayoutId
和mDatas
都由构造函数传入,没啥好说的。
对外暴漏setItemPresenter(Object itemPresenter)
供设置点击事件处理类ItemPresenter
。
ItemPresenter
是Object
类型,这样才不care你set的Item点击事件处理类是什么鬼。
onCreateViewHolder(ViewGroup parent, int viewType)
方法返回BaseBindingVH
作为ViewHolder
。
mLayoutId
会在onCreateViewHolder(ViewGroup parent, int viewType)
用到,再根据泛型B强转成对应的ViewDataBinding
:
BaseBindingVH holder = new BaseBindingVH((B) DataBindingUtil.inflate(mInfalter, mLayoutId, parent, false));
会在onBindViewHolder()
方法里,利用DataBinding动态绑定ViewDataBinding.setVariable(BR.itemP, ItemPresenter);
为每个Item设置点击事件。
同时,数据也是同样在里面绑定的:setVariable(BR.data, mDatas.get(position))
。
重点代码如下:
public class BaseBindingAdapter<D, B extends ViewDataBinding> extends RecyclerView.Adapter<BaseBindingVH> {
protected Context mContext;
protected int mLayoutId;
protected List mDatas;
protected LayoutInflater mInfalter;
//用于设置Item的事件Presenter
protected Object ItemPresenter;
public BaseBindingAdapter(Context mContext, List mDatas, int mLayoutId) {
this.mContext = mContext;
this.mLayoutId = mLayoutId;
this.mDatas = mDatas;
this.mInfalter = LayoutInflater.from(mContext);
}
@Override
public BaseBindingVH onCreateViewHolder(ViewGroup parent, int viewType) {
BaseBindingVH holder = new BaseBindingVH((B) DataBindingUtil.inflate(mInfalter, mLayoutId, parent, false));
onCreateViewHolder(holder);
return holder;
}
/**
-
如果需要给Vh设置监听器啥的 可以在这里
-
@param holder
*/
public void onCreateViewHolder(BaseBindingVH holder) {
}
/**
-
子类除了绑定数据,还要设置监听器等其他操作。
-
可以重写这个方法,不要删掉super.onBindViewHolder(holder, position);
-
@param holder
-
@param position
*/
@Override
public void onBindViewHolder(BaseBindingVH holder, int position) {
holder.getBinding().setVariable(BR.data, mDatas.get(position));
holder.getBinding().setVariable(BR.itemP, ItemPresenter);
holder.getBinding().executePendingBindings();
}
/**
-
用于设置Item的事件Presenter
-
@param itemPresenter
-
@return
*/
public BaseBindingAdapter setItemPresenter(Object itemPresenter) {
ItemPresenter = itemPresenter;
return this;
}
}
BaseBindingAdapter
内部也封装了如下方法,方便数据刷新,增删(定向刷新)调用:
/**
-
刷新数据,初始化数据
-
@param list
*/
public void setDatas(List list) {
if (this.mDatas != null) {
if (null != list) {
List temp = new ArrayList();
temp.addAll(list);
this.mDatas.clear();
this.mDatas.addAll(temp);
} else {
this.mDatas.clear();
}
} else {
this.mDatas = list;
}
notifyDataSetChanged();
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
最后
给大家送上我成功跳槽复习中所整理的资料,由于文章篇幅有限,所以只是把题目列出来了,我自己手头上整理的资料均和上面的答案可免费分享,需要这些资料和答案的朋友,可以点击这里免费领取。
成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-dZTw6tFu-1710853266085)]
[外链图片转存中…(img-vBJtXR9e-1710853266085)]
[外链图片转存中…(img-8zzoYAPF-1710853266086)]
[外链图片转存中…(img-sdR7m7HK-1710853266086)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
[外链图片转存中…(img-rKGaR1aK-1710853266086)]
最后
给大家送上我成功跳槽复习中所整理的资料,由于文章篇幅有限,所以只是把题目列出来了,我自己手头上整理的资料均和上面的答案可免费分享,需要这些资料和答案的朋友,可以点击这里免费领取。
[外链图片转存中…(img-0BVQu7NL-1710853266087)]
[外链图片转存中…(img-CNisDCc9-1710853266087)]