通用的RecyclerView Adapter适配器

在Android开发中,会经常用到RecyclerView来显示数据,数据的绑定使用到Adapter,原声的Adapter需要些很多重复代码,今天写了一个通用的代码来实现适配器绑定数据,减少代码量。
通用Adapter的功能:
1、FooterView和headerView的显示
2、停止滚动屏幕,再去加载数据
下面是代码的详解:
1、通用的ViewHolder

public class RecyclerViewHolder extends RecyclerView.ViewHolder {
    private SparseArray arrayView;
    public RecyclerViewHolder(View itemView) {
        super(itemView);
        arrayView = new SparseArray<>();
    }

    /**
     * 通过填写的itemId来获取具体的View的对象
     * @param itemId  R.id.***
     * @param  必须是View的子类
     * @return
     */
    public  T getView(int itemId){
        //arrayVie类似于Map容器,get(key)取出的是value值
        View mView = arrayView.get(itemId);
        if(mView == null){
            //实例化具体的View类型
            mView = itemView.findViewById(itemId);
            arrayView.put(itemId,mView);
        }
        return (T) mView;
    }

    /**
     * 设置TextView的内容
     * @param itemId
     * @param text
     */
    public void setText(int itemId,String text){
        TextView tv = getView(itemId);
        tv.setText(text);
    }

    /**
     * 设置图片
     * @param itemId
     * @param imageId
     */
    public void setBitmapImage(int itemId,int imageId){
        ImageView iv = getView(itemId);
        iv.setImageResource(imageId);
    }
}

1、主要方法:getView(int itemId) 传入的是具体的id,
2、使用SparseArray中的get方法获取View实例,如果不存在,那么就findViewByid(itemId)获取View实例。
3、最后,为一些基本的空间提供设置内容的方法。如setText()为TextView设置内容,setBitmapImage(int id)为图片设置内容。
2、BaseRecyclerAdapter

public abstract class BaseRecyclerAdapter extends RecyclerView.Adapter{
    private static final String TAG = "BaseRecyclerAdapter--->";
    private static final int TYPE_HEAD = 0;
    private static final int TYPE_ITEM = 1;
    private static final int TYPE_FOOT = 2;
    private boolean isScrolling = true;  //false表示滑动,true表示不滑动
    private View headerView,footerView;  //头和尾的view
    private List lists;   //传入的集合。
    private int totalList;
    private int itemLayoutId; //设置Layout的id。
    private Context cxt;
    private OnItemViewClickListener onItemViewClickListener;
    public interface OnItemViewClickListener{
        //设置item中某个view的点击事件
        void onItemViewClick(RecyclerViewHolder view,int position);
    }
    public void setonItemViewClickListener(OnItemViewClickListener listener){
        this.onItemViewClickListener = listener;
    }
    public BaseRecyclerAdapter(RecyclerView view,List list,int itemLayoutId){
        this.lists = list;
        this.itemLayoutId = itemLayoutId;
        this.cxt = view.getContext();

        view.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                //设置如果Recycler停止滑动,去绑定更新数据。
                if(newState == RecyclerView.SCROLL_STATE_IDLE){
                    //表示停止滑动
                    isScrolling = true;
                    Log.i(TAG,isScrolling+"停止滚动");
                }else{
                    //正在滑动
                    isScrolling = false;
                    Log.i(TAG,isScrolling+"正在滚动....");
                }
                //将上面代码改写成这样。
//                isScrolling = (newState == RecyclerView.SCROLL_STATE_IDLE);
                if(isScrolling){ //为true时候表示停止滑动操作,去更新数据
                    notifyDataSetChanged();
                }

                super.onScrollStateChanged(recyclerView,newState);
            }
        });
    }
    public void setFooterView(View view){
        this.footerView = view;
    }
    public void setHeaderView(View view){
        this.headerView = view;
    }

    /**
     * 创建RecyclerView里面的itemView。
     * @param parent
     * @param viewType
     * @return
     */
    @Override
    public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if(viewType == TYPE_HEAD && headerView !=null){
            return new RecyclerViewHolder(headerView);
        }
        if(viewType == TYPE_FOOT && footerView!=null){
            return new RecyclerViewHolder(footerView);
        }
        View view = LayoutInflater.from(cxt).inflate(itemLayoutId,parent,false);
        return new RecyclerViewHolder(view);
    }

    /**
     *  绑定每一个itemView的具体数据
     * @param holder
     * @param position
     */
    @Override
    public void onBindViewHolder(RecyclerViewHolder holder, int position) {
        if(getItemViewType(position) != TYPE_ITEM){
            //如果不是正常的Item,就不去绑定数据
            return;
        }
        Log.i(TAG,"bindView---"+position);
        //抽象方法,让子类去具体的实现
        int p = getRealPosition(position);
        bindConvert(holder,p,lists.get(p),isScrolling);
        if(onItemViewClickListener!=null){
           onItemViewClickListener.onItemViewClick(holder,p);
        }
    }
    private int getRealPosition(int position){
       return headerView ==null ? position : position-1;
    }
    public abstract void bindConvert(RecyclerViewHolder holder, int position, T item, boolean isScrolling);

    /**
     * 判断有多少个list.size()
     * @return
     */
    @Override
    public int getItemCount() {
        if(lists == null){
            return 0;
        }
        if(headerView!=null && footerView!=null){
            //头尾都不为空
            totalList =  lists.size()+2;
        }else if(headerView ==null && footerView ==null){
            //头尾都为空
            totalList = lists.size();
        }else{
            //头尾有一个不为空
            totalList = lists.size()+1;
        }
        return totalList;
    }

    @Override
    public int getItemViewType(int position) {
        if(position == 0 && headerView !=null){
            //表示第一个item,并且headerView不为空
            return TYPE_HEAD;
        }
        if(position+1 == getItemCount() && footerView !=null){
            //表示最好一个item,并且footerView不为空
            return TYPE_FOOT;
        }
        return TYPE_ITEM;
    }
}

1、该抽象类, 首先继承了RecyclerView.Adapter类,
2、实现VH onCreateViewHolder(ViewGroup parent, int viewType)、
实例化具体的ViewHolder类
void onBindViewHolder(VH holder, int position);
绑定具体的数据。
int getItemCount()三个抽象方法。
3、重写int getItemViewType(int position)方法。
4、定义一个抽象类,让继承该类的子类去实现方法。
主要是绑定具体的View数据。

public abstract void bindConvert(RecyclerViewHolder holder, int position, T item, boolean isScrolling);

3、子类Adapter实现BaseRecyclerAdapter方法

public class TextAdapter extends BaseRecyclerAdapter<String> {

    public TextAdapter(RecyclerView view, List list) {
        super(view, list, R.layout.recyclerview_item);
    }

    @Override
    public void bindConvert(RecyclerViewHolder holder, int position, String item, boolean isScrolling) {
        if(isScrolling) {
            //不滑动的时候去加载数据
            holder.setText(R.id.info_tv, "第" + position + "条数据");
        }
    }
}

isScrolling来自于父类的方法,主要是滑动的监听,用户滑动屏幕时候,不去加载数据,停止滑动时再去加载数据。

 view.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                //设置如果Recycler停止滑动,去绑定更新数据。
                if(newState == RecyclerView.SCROLL_STATE_IDLE){
                    //表示停止滑动
                    isScrolling = true;
                    Log.i(TAG,isScrolling+"停止滚动");
                }else{
                    //正在滑动
                    isScrolling = false;
                    Log.i(TAG,isScrolling+"正在滚动....");
                }
                //将上面代码改写成这样。
//                isScrolling = (newState == RecyclerView.SCROLL_STATE_IDLE);
                if(isScrolling){ //为true时候表示停止滑动操作,去更新数据
                    notifyDataSetChanged();
                }

                super.onScrollStateChanged(recyclerView,newState);
            }
        });

源码下载地址:http://download.csdn.net/detail/u011521890/9488936

你可能感兴趣的:(Android进阶)