打造通用Adapter 让RecyclerView更加好用

一丶概述

实现RecyclerView的通用的Adapter。

1、单一的ItemViewType,不同的数据源。

2、多个的ItemViewType。

二、通用的ViewHodler

首先来看一下RecyclerView的Adapter是怎么一回事。

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//实现RecyclerView.ViewHolder
        return null;
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
//绑定数据源
    }

    @Override
    public int getItemCount() {
        return 0;//Item的个数
    }
}

我们可以看到RecyclerView的adapter要会有上面三个方法要实现。而且有个RecyclerView.ViewHolder类的作用就是初始化Item中的控件。不同的item中有着不同控件。要想实现RecyclerView的adapter的通用,那么ViewHolder就要是一个通用的。通过传不同的LayoutId来实现有着不同的控件的ViewHolder。

 

/**
 * 通用的ViewHolder
 */
public class ViewHolder extends RecyclerView.ViewHolder {
    private Context mContext;
    private SparseArray<View> viewSparseArray;
    private View mItemView;

    public ViewHolder(@NonNull View itemView, Context mContext) {
        super(itemView);
        this.mContext = mContext;
        this.viewSparseArray=new SparseArray<>();
        this.mItemView=itemView;
    }

    /**
     * 根据不同的layoutId创建有着不同的View的ViewHolder
     * @param mContext
     * @param parent
     * @param layoutId
     * @return
     */
    public static ViewHolder get(Context mContext,ViewGroup parent,int layoutId){
        View itemview= LayoutInflater.from(mContext).inflate(layoutId,parent,false);
        ViewHolder viewHolder=new ViewHolder(itemview,mContext);
        return viewHolder;
    }

    /**
     * 实例View通过ViewId来
     * @param viewId
     * @param <T>
     * @return
     */
    public  <T extends View>T getView(int viewId){
        View view=viewSparseArray.get(viewId);
        if (view==null){
            view=mItemView.findViewById(viewId);
            viewSparseArray.put(viewId,view);
        }
        return (T) view;
    }
    
//辅助方法,根据自己的需要自己定义
    /**
     * 实现TextView的setText()方法
     * @param viewId 
     * @param msg
     * @return
     */
    public ViewHolder setText(int viewId,String msg){
        TextView tv_content=getView(viewId);
        tv_content.setText(msg);
        return this;
    }
}

三、通用的Adapter

我们在使用Adapter的时候,使用不同数据源而使用的Adapter,所以在这里我们有泛型来代表引入的数据源。


public abstract class CommonAdapter<T> extends RecyclerView.Adapter<ViewHolder> {
    private List<T> mdatas;//数据源
    private Context mContext;
    private int layoutId;//Layout的id

    public CommonAdapter(List<T> mdatas, Context mContext, int layoutId) {
        this.mdatas = mdatas;
        this.mContext = mContext;
        this.layoutId = layoutId;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        ViewHolder viewHolder=ViewHolder.get(mContext,parent,layoutId);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        convert(holder,position,mdatas.get(position));
    }

    public abstract void convert(ViewHolder holder,int position,T t);//实现数据与View的绑定

    @Override
    public int getItemCount() {
        return mdatas.size();
    }
}

四、单一的Item的adapter的使用

  commonAdapter=new CommonAdapter<String>(mDatas,this,R.layout.item_refresh_recylerview) {
            @Override
            public void convert(ViewHolder holder, String s, int position) {
                holder.setText(R.id.tv_content,s);
            }
        };

五、多种的ItemType的adapter

我们一般都是复写getItemViewType(),根据返回的值,用不同的layoutId来创建不同的ViewHolder。

于是,就有了一个接口:

public interface MultipleItemTypeSupport<T> {
    int getLayoutId(int itemViewType);//返回layoutId
    int getItemViewType(int position,T t);//返回itemview的type的值
}

通过个接口,我们就可以很清楚的知道怎么做了。getItemViewType()方法里就可以判断用那个LayoutId了。

于是,MultipleItemTypeAdapter

public abstract class MultipleItemTypeAdapter<T> extends CommonAdapter<T>{
    private MultipleItemTypeSupport multipleItemTypeSupport;

    public MultipleItemTypeAdapter(List<T> mdata, Context mContext, MultipleItemTypeSupport<T> multipleItemTypeSupport) {
        super(mdata, mContext, -1);
        this.multipleItemTypeSupport=multipleItemTypeSupport;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        int layoutId=multipleItemTypeSupport.getLayoutId(viewType);
        ViewHolder holder=ViewHolder.get(mContext,parent,layoutId);
        return holder;
    }

    @Override
    public int getItemViewType(int position) {
        return multipleItemTypeSupport.getItemViewType(position,mdata.get(position));
    }

    @Override
    public void convert(ViewHolder holder, T t, int position) {
        converts(holder,t,position);
    }
    public abstract void converts(ViewHolder holder, T t,int position);
}

那么这篇博客就这样先结束了。希望大家能看得懂。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值