recyclerview万能适配器。
不做任何封装的情况下。每一个adapter中数据都不同,都要判断viewtype。onCreateViewHolder中都要根据不同的viewtype创建不同的viewholder,并且在bindviewholder中分别进行绑定。
个人分析:最后会贴代码
看了鸿洋大神的博客。首先对viewholder做了封装,将所有viewholder用一个统一的自定义viewholder来表示,因为不知道具体layout中view的数量。所以view存储到sparseArray中,去存取。所有的viewholder,唯一不同的是创建时使用的layout。
其实每一个不同类型的item,他们只有两处不同,一处是layout,一处是具体对layout的操作,对应到recyclerAdapter。就是OnCreatViewHolder,和bindViewHolder。所以我们把这两个不同抽象出来,给每一个不同的item去实现。仔细想想还有一处不同,就是我怎么知道这个item显示在哪里呢。是第一行还是最后一行等等。所以我们还要抽取出一个方法,用来判断他的viewType。
关于adapter中的getViewType。这是判断item究竟显示在哪里,或者说,这个item应该怎么显示。他提供了一个重要的参数,position。在这里,我们可以拿到JavaBean,然后再判断这里应该怎么显示,创建什么viewholder。在onCreateViewHolder中只有两个参数 view Group partent,int viewType。
请看代码。。思路参考鸿洋大神。viewholder还可以写辅助方法,设置Text,iamge,点击时间等。其中的难点是
boolean isViewType(T obj,int position);
这里判断type。每一个不同的recyclerview中,也许判断不同。为了通用,这里得处理好。
public class ItemDelegateManager<T> {
/**
* 一个recyclerview,有不同的item。具体哪个position展现哪个item又manger来控制。
* 将key值,作为viewType。可以指定key值。
*/
/**
* 存储着这个dapter所有的item代表。
*/
private SparseArray<ItemDelegate> itemArrays;
private Context mContext;
public ItemDelegateManager(Context context){
itemArrays = new SparseArray<>();
mContext = context;
}
//判断返回哪个viewtype 根据postion和data。
public int getViewType(int position,T data){
//固定格式 如果为0 直接返回这种viewType。
//可以按照他的key做viewtype
int size = itemArrays.size();
for (int i = 0;i<size;i++){
ItemDelegate itemDelegate = itemArrays.valueAt(i);//根据角标拿到value。
if(itemDelegate.isViewType(data,position)){
return itemArrays.keyAt(i);//根据角标拿到key。
}
}
return 1;
}
public int getLayout(int viewType){
return itemArrays.get(viewType).getLayoutId();
}
public void conver(MyViewHolderWan holder, int position,T data) {
// 这里调用itemDelegate的conver方法。根据data调用不同的itemDelegate。
int size = itemArrays.size();
for (int i = 0;i<size;i++){
ItemDelegate itemDelegate = itemArrays.valueAt(i);//根据角标拿到value。
if(itemDelegate.isViewType(data,position)){
itemDelegate.conver(holder,position,data,mContext);
}
}
}
//添加itemdelegate 以长度做key
public <T> void add(ItemDelegate<T> itemDelegate) {
itemArrays.put(itemArrays.size(),itemDelegate);
}
//指定key
public<T> void add(int key,ItemDelegate<T> itemDelegate){
itemArrays.put(key,itemDelegate);
}
}
public class MyRecyclerAdapter<T> extends RecyclerView.Adapter<MyViewHolderWan> {
//管理item。
private ItemDelegateManager delegateManager;
//数据集合。
private List<T> datas;
private Context context;
public MyRecyclerAdapter(List<T> datas,Context context){
delegateManager = new ItemDelegateManager(context);
this.datas = datas;
}
@Override
public MyViewHolderWan onCreateViewHolder(ViewGroup parent, int viewType) {
//我们需要判断需要哪个layoutId
//我们在这个方法中,没办法判断是第几个item的创建,所以拿不到javabean。
//根据viewType来判断。
int layout = delegateManager.getLayout(viewType);
MyViewHolderWan myViewHolderWan = MyViewHolderWan.get(parent.getContext(),layout, parent);
return myViewHolderWan;
}
@Override
public void onBindViewHolder(MyViewHolderWan holder, int position) {
conver(holder,position);
}
public void conver(MyViewHolderWan holder, int position){
//通过manager管理
delegateManager.conver(holder,position,datas.get(position));
};
@Override
public int getItemCount() {
return datas.size();
}
//getItemViewType中最重要的参数是position。
//我们知道我们要创建viewholder,需要根据不同的item来创建不同的viewholder。
//postion我们可以判断位置,从来创建viewholder。
@Override
public int getItemViewType(int position) {
return delegateManager.getViewType(position,datas.get(position));
}
//定义为抽象类。因为这个方法必须实现。不然没有item。
public void addItemDelegate(ItemDelegate<T> itemDelegate){
delegateManager.add(itemDelegate);
};
public void addItemDelegate(int type,ItemDelegate<T> itemDelegate){
delegateManager.add(type,itemDelegate);
};
}
public interface ItemDelegate<T> {
/**
* 每个item三个独特点。第一,layout。第二,conver。第三,isViewType。
* @return
*/
int getLayoutId();
//十分重要。判断item要显示的是什么。
boolean isViewType(T obj,int position);
void conver(MyViewHolderWan holder,int position,T data,Context context);
}
public class LeftPictureItem implements ItemDelegate<TipOffBeans> {
@Override
public int getLayoutId() {
return R.layout.recycler_item_news_leftpic;
}
@Override
public boolean isViewType(TipOffBeans obj, int position) {
if(position!= 0 &&!TextUtils.isEmpty(obj.imageurl)){
//不为null 那就是有图片
return true;
}
return false;
}
@Override
public void conver(MyViewHolderWan holder, int position, TipOffBeans data, Context context) {
ImageView pic = holder.getView(R.id.iv_news_recycler_item_image);
Glide.with(context)
.load(data.imageurl)
.placeholder(R.drawable.nopic)
.dontAnimate()
.priority(Priority.HIGH)
.into(pic);
TextView titleView = holder.getView(R.id.tv_news_recycler_item_title);
titleView.setText(data.title);
}
}