android开发之recycleView的adapter理解

之前很长时间都是使用的listview,然后自己写适配器,主要都是继承自BaseAdapter。大致的思路呢,就是我们传入数据源以及上下文对象,然后我们在自定义适配器文件中实现了构造方法,然后将传入的上下文对象(context)以及数据源初始化,下一步就是实现了我们继承自BaseAdapter的四个抽象方法:

1.getCount,返回的对象是数据源的大小;

2.getItem,返回的是每一项数据(datas.get(position));

3.getItemId,这个参数并没有深入去理解过,只是知道返回的参数是position;

4,getView,这个方法是主要的方法,我们的一系列赋值操作都是在这里来完成的,在这里面,我们通过convertview的复用来优化listview,通过布局映射器(layoutInflater)来将每个item的布局映射进来,然后通过findviewbyid初始化各个控件。此外,我们还使用到了viewHolder来优化listview。

之所以在理解recycleview的adapter之前提这么多list view的adapter,是因为为了对比着来理解,因为recycleview并没有那么成熟的系统的adapter来供我们使用,给了我们高度自由化的空间。

相比于listview继承的是baseAdapter,我们使用recycleview继承的是recycleview的adapter,这里我们需要传参数是我们自定义的viewHolder,这个viewHolder是继承于recycle view 的viewholder,至于我们要在viewholder里面执行的操作,我们后面再说,首先说我们继承recycle view的adapter需要继承的方法:

1.onCreateViewHolder,这个方法就类似我们的getview方法,但只是执行简单的绑定视图操作;

 public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // 多布局支持
        if (mMultiTypeSupport != null) {
            mLayoutId = viewType;
        }

        View itemView = mInflater.inflate(mLayoutId, parent, false);
        return new ViewHolder(itemView);
    }

这里的viewholder就是我们自定义的viewholder,在这里将视图传到我们的viewholder里面。

2.onBindViewHolder,这个方法主要是对数据进行赋值操作,它的两个参数分别为(viewholder,T)我们通过viewholder拿到控件,后面的为数据,然后执行了一些正常的控件赋值操作。

3.getItemCount,返回的是数据源的大小,类似于list view的adapter的getCount;

当我们封装通用adapter的时候,就是在bind方法里面执行我们的抽象方法。

  @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        // 设置点击和长按事件
        if (mItemClickListener != null) {
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mItemClickListener.onItemClick(position);
                }
            });
        }
        if (mLongClickListener != null) {
            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    return mLongClickListener.onLongClick(position);
                }
            });
        }
        if(mHoverListener!=null){
            holder.itemView.setOnHoverListener(new View.OnHoverListener() {
                @Override
                public boolean onHover(View view, MotionEvent motionEvent) {
                    return mHoverListener.onHover(view,motionEvent);
                }
            });
        }

        // 绑定怎么办?回传出去
        convert(holder, mDatas.get(position));
    }

    /**
     * 利用抽象方法回传出去,每个不一样的Adapter去设置
     * @param item 当前的数据
     */
    public abstract void convert(ViewHolder holder, T item);

然后要说的就是我们的viewHolder类,我们可以新建文件来实现这个类,也可以写在我们的adapter里面。

1.首先是我们的构造方法,通过上面在create里面的应用,我们可以发现,我们的构造方法里面,必须有的参数,就是我们的view对象,就是将我们的视图映射器加载进来的视图传递到我们的viewholder中来,之前我们在listview里面是直接手写的各个item布局的控件,而这里,我们是直接传递进来,我们用一个容器来装载我们的子view。

 // 用来存放子View减少findViewById的次数
         private SparseArray mViews;

        public ViewHolder(View itemView) {
             super(itemView);
             mViews = new SparseArray<>();
         }

2.一个主要的方法,getView,就是通过这个方法,我们实现了寻找控件并绑定

         /**
          * 通过id获取view
          */
         public  T getView(int viewId) {
             // 先从缓存中找
             View view = mViews.get(viewId);
             if (view == null) {
                 // 直接从ItemView中找
                 view = itemView.findViewById(viewId);
                 mViews.put(viewId, view);
             }
             return (T) view;
         }

3.其他的就是我们就行的一些简单的赋值操作,包括文本以及图片,这里以textview为例:

  /**
          * 设置TextView文本
          */
         public ViewHolder setText(int viewId, CharSequence text) {
             TextView tv = getView(viewId);
             tv.setText(text);
             return this;
         }

至此,简单的理解就这样了,至于添加事件监听,可以查看下面的全部代码:

package com.meng.yao.baselibrary.adapter;

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

import java.util.List;

/**
 * 项目名称:joke
 * 类描述:万能RecyclerView适配器
 * 创建人:woochen123
 * 创建时间:2017/5/23 18:32
 */
public abstract class CommonRecyclerAdapter extends RecyclerView.Adapter {
    protected Context mContext;
    private LayoutInflater mInflater;
    //数据怎么办?利用泛型
    protected List mDatas;
    // 布局怎么办?直接从构造里面传递
    private int mLayoutId;
    // 多布局支持
    private MultiTypeSupport mMultiTypeSupport;

    public CommonRecyclerAdapter(Context mContext, List mDatas, int mLayoutId) {
        this.mContext = mContext;
        this.mDatas = mDatas;
        this.mLayoutId = mLayoutId;
        this.mInflater = LayoutInflater.from(mContext);
    }

    /**
     * 多布局支持
     */
    public CommonRecyclerAdapter(Context context, List data, MultiTypeSupport multiTypeSupport) {
        this(context, data, -1);
        this.mMultiTypeSupport = multiTypeSupport;
    }

    /**
     * 根据当前位置获取不同的viewType
     */
    @Override
    public int getItemViewType(int position) {
        // 多布局支持
        if (mMultiTypeSupport != null) {
            return mMultiTypeSupport.getLayoutId(mDatas.get(position), position);
        }
        return super.getItemViewType(position);
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // 多布局支持
        if (mMultiTypeSupport != null) {
            mLayoutId = viewType;
        }

        View itemView = mInflater.inflate(mLayoutId, parent, false);
        return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        // 设置点击和长按事件
        if (mItemClickListener != null) {
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mItemClickListener.onItemClick(position);
                }
            });
        }
        if (mLongClickListener != null) {
            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    return mLongClickListener.onLongClick(position);
                }
            });
        }
        if(mHoverListener!=null){
            holder.itemView.setOnHoverListener(new View.OnHoverListener() {
                @Override
                public boolean onHover(View view, MotionEvent motionEvent) {
                    return mHoverListener.onHover(view,motionEvent);
                }
            });
        }

        // 绑定怎么办?回传出去
        convert(holder, mDatas.get(position));
    }

    /**
     * 利用抽象方法回传出去,每个不一样的Adapter去设置
     * @param item 当前的数据
     */
    public abstract void convert(ViewHolder holder, T item);

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

    public static class ViewHolder extends RecyclerView.ViewHolder{
         // 用来存放子View减少findViewById的次数
         private SparseArray mViews;

        public ViewHolder(View itemView) {
             super(itemView);
             mViews = new SparseArray<>();
         }

         /**
          * 设置TextView文本
          */
         public ViewHolder setText(int viewId, CharSequence text) {
             TextView tv = getView(viewId);
             tv.setText(text);
             return this;
         }

         /**
          * 通过id获取view
          */
         public  T getView(int viewId) {
             // 先从缓存中找
             View view = mViews.get(viewId);
             if (view == null) {
                 // 直接从ItemView中找
                 view = itemView.findViewById(viewId);
                 mViews.put(viewId, view);
             }
             return (T) view;
         }

         /**
          * 设置View的Visibility
          */
         public ViewHolder setViewVisibility(int viewId, int visibility) {
             getView(viewId).setVisibility(visibility);
             return this;
         }

         /**
          * 设置ImageView的资源
          */
         public ViewHolder setImageResource(int viewId, int resourceId) {
             ImageView imageView = getView(viewId);
             imageView.setImageResource(resourceId);
             return this;
         }

         /**
          * 设置条目点击事件
          */
         public void setOnIntemClickListener(View.OnClickListener listener) {
             itemView.setOnClickListener(listener);
         }

         /**
          * 设置条目长按事件
          */
         public void setOnIntemLongClickListener(View.OnLongClickListener listener) {
             itemView.setOnLongClickListener(listener);
         }

        /**
         * 设置条目悬浮事件
         * @param hoverListener
         */
        public void setmHoverListener(View.OnHoverListener hoverListener){
            itemView.setOnHoverListener(hoverListener);
        }

    }

    /*
     * 设置条目点击和长按事件
     */
    public OnItemClickListener mItemClickListener;
    public OnLongClickListener mLongClickListener;
    public View.OnHoverListener mHoverListener;

    public void setOnItemClickListener(OnItemClickListener itemClickListener) {
        this.mItemClickListener = itemClickListener;
    }

    public void setOnLongClickListener(OnLongClickListener longClickListener) {
        this.mLongClickListener = longClickListener;
    }
    public void setmHoverListener(View.OnHoverListener hoverListener){
        this.mHoverListener = hoverListener;
    }

}
这里的全部代码,实现了多布局支持,只是多布局这块,本人也不是很理解,就只是贴代码,就不作陈述了。

你可能感兴趣的:(android开发之recycleView的adapter理解)