RecyclerView通用adapter,holder封装

RecyclerIView作为ListView的替代者,优势在此就不做充分说明了,相信使用过RecyclerView的人来说,已经爱不释手了,一个控件可以解决这种列表,不管横向、纵向还是瀑布流,都可以很轻易即可实现,此处就通用的封装简单随笔记录。
通用holder的封装如下

package com.example.recyclerview.recyclerview;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * Created by Administrator on 2018/5/25.
 */

public class RecyclerViewBaseHolder extends RecyclerView.ViewHolder{
    private View mContentView;
    //内存中缓存的view
    private SparseArray<View> views;
    private Context mContext;

    public RecyclerViewBaseHolder(Context context,View itemView) {
        super(itemView);
        mContentView=itemView;
        views=new SparseArray<>();
        mContext=context;
    }


    public static RecyclerViewBaseHolder getHolder(Context context, ViewGroup parent,int layoutId){
        View itemView= LayoutInflater.from(context).inflate(layoutId,parent,false);
        return new RecyclerViewBaseHolder(context,itemView);
    }

    /**
     * 
     * @param viewId 控件的id
     * @param <T>
     * @return  返回经强转成实际类型之后的view类型
     * 本方法一般是在具体adapter中comvert()方法通过id查找对应控件所用
     */
    public <T extends View> T get(int viewId){
       View view=views.get(viewId);
        if(view==null){
            view=mContentView.findViewById(viewId);
            views.put(viewId,view);
        }
        return (T)view;
     }

    /**
     * 用于获取特定情况获取复用的itemView
     * @return
     */
    public View getContentView(){
        return mContentView;
    }
}

以上是一个通用的holder,改类中没有需要去复写的方法,只有一个getView方法在子类adapter中进行数据绑定时,对控件进行初始化才使用该方法。
通用adapter封装如下:

package com.example.recyclerview.recyclerview;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;

import java.util.ArrayList;

/**
 * Created by Administrator on 2018/5/25.
 */

public abstract class RecyclerViewBaseAdapter<T> extends RecyclerView.Adapter<RecyclerViewBaseHolder> {

    private ArrayList<T>  datas;
    private Context context;
    private int layoutId;

    public RecyclerViewBaseAdapter(ArrayList<T> datas, Context context, int layoutId) {
        this.datas = datas;
        this.context = context;
        this.layoutId = layoutId;
    }

    @Override
    public RecyclerViewBaseHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        RecyclerViewBaseHolder holder=RecyclerViewBaseHolder.getHolder(context,parent,layoutId);
        return holder;
    }

    @Override
    public void onBindViewHolder(RecyclerViewBaseHolder holder, int position) {
        convert(holder,datas.get(position),position);
    }


    @Override
    public int getItemCount() {
        return datas==null ? 0:datas.size();
    }
    public abstract void convert(RecyclerViewBaseHolder holder,T t,int postion);
}

封装好通用的adapter之后,我们实际业务子类adapter只需要集成通用adapter然后重写convert方法完成控件的初始化及数据绑定即可。
封装了通用的adapter,但是上面的adapter只是单视图类型,假如我们需要一个多类型条目的通用adapter该如何封装,下面我们可以思考一下,多条目类型跟单条目类型的不同,本质的不同其实就是视图的不同,而我们单条目通用的adapter是通过将layoutId传进来,然后返回不同的holder,而对于多条目来说,我们的视图具体展示是要通过viewtype类型决定的,而在onCreateVeiwHolder中有一个字段viewType正是我们的视图类型,所以这里我们可以提取一个抽象方法getLayoutId(int viewType)让子类具体去重写,重写的目的是根据viewType返回不同的layoutId,拿到layoutId之后的逻辑,就跟单条目是一样的,将layoutId传给holder去创建对应holder.那么如何拿到viewType,我们只需要重写getItemViewType即可,但是由于是封装通用的adapter,在adapter中我们无法去重写,所以也可以将这个方法封装成抽象,封装完了之后在通用adapter中的getItemViewType中去调用即可。考虑到定义两个抽象方法,我们此处不妨定义成接口,具体代码如下;
多条目类型接口:

package com.example.recyclerview.recyclerview;

import java.util.ArrayList;

/**
 * Created by Administrator on 2018/5/25.
 * 多条目类型的通用接口
 */

public interface MultiTypeSupportImp<T> {
    /**
     * 根据position对应的数据 判断返回对应的具体item的类型
     */
     int  getViewItemType(ArrayList<T> datas, int position);

     /**
      * 根据不同的类型返回不同布局id
     */
     int getLayoutId(int viewType);
}

多条目类型的通用adapter

 package com.example.recyclerview.recyclerview;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;

import java.util.ArrayList;

/**
 * Created by Administrator on 2018/5/25.
 * 多种条目类型的RecyclerView
 */

public abstract class MultiTypeViewBaseAdapter<T> extends RecyclerView.Adapter<RecyclerViewBaseHolder> implements MultiTypeSupportImp<T> {
    private ArrayList<T> datas;
    private Context context;

    public MultiTypeViewBaseAdapter(ArrayList<T> datas, Context context) {
        this.datas = datas;
        this.context = context;
    }

    @Override
    public RecyclerViewBaseHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        int layoutId=getLayoutId(viewType);
        RecyclerViewBaseHolder holder=RecyclerViewBaseHolder.getHolder(context,parent,layoutId);
        return holder;
    }

    @Override
    public void onBindViewHolder(RecyclerViewBaseHolder holder, int position) {
      convert(holder,datas.get(position),position);
    }

    @Override
    public int getItemCount() {
        return datas==null ? 0:datas.size();
    }

    @Override
    public int getItemViewType(int position) {
        return getViewItemType(datas,position);
    }


    @Override
    public abstract int  getViewItemType(ArrayList<T> datas, int position);

    @Override
    public abstract int  getLayoutId(int viewType);

    public abstract void convert(RecyclerViewBaseHolder holder,T t,int postion);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值