RecyclerView通用适配器的实现

分析

  • 我们需要在RecyclerViewAdapter内部维持一个数据集合的引用
  • 需要实现Item的点击事件,包括短按和长按,并需要向外部提供设置监听器的方法
  • 这个适配器必须通用,所以应该是泛型的,并且ViewHolder也是通用的,可以采用SparseArray维持View的所有集合
  • 在RecyclerViewAdapter内部需要实现数据的绑定(抽象方法,延迟到子类实现),监听器的绑定

编写监听器

分为短按事件和长按事件

  • 短按监听器
package cn.edu.zafu.base.adapter.listener;

import android.view.View;

/**
 * Created by lizhangqu on 2015/6/3.
 */
public interface OnItemClickListener<T> {
    void onClick(View view, T item);
}
  • 长按监听器
package cn.edu.zafu.base.adapter.listener;

import android.view.View;

/**
 * Created by lizhangqu on 2015/6/3.
 */
public interface OnItemLongClickListener<T> {
    void onLongClick(View view, T item);
}

编写通用适配器

  • 设置监听器
package cn.edu.zafu.base.adapter;

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

import java.util.List;

import cn.edu.zafu.base.adapter.listener.OnItemClickListener;
import cn.edu.zafu.base.adapter.listener.OnItemLongClickListener;

/**
 * this is a BaseAdapter for RecyclerView
 * author lizhangqu
 * version 1.0
 * date 2015/6/3.
 */
public abstract class BaseRecyclerViewAdapter<T, VH extends BaseRecyclerViewAdapter.SparseArrayViewHolder> extends RecyclerView.Adapter<VH> {

    /**
     * click listener
     */
    protected OnItemClickListener mOnItemClickListener;
    /**
     * long click listener
     */
    protected OnItemLongClickListener mOnItemLongClickListener;

    /**
     * set a long click listener
     *
     * @param onItemLongClickListener
     */
    public void setOnItemLongClickListener(OnItemLongClickListener onItemLongClickListener) {
        mOnItemLongClickListener = onItemLongClickListener;
    }

    /**
     * set a click listener
     *
     * @param onItemClickListener
     */
    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        mOnItemClickListener = onItemClickListener;
    }

}
  • 编写构造方法,将数据集合进行赋值
    /**
     * data
     */
    protected List<T> mList;

    /**
     * @param list the datas to attach the adapter
     */
    public BaseRecyclerViewAdapter(List<T> list) {
        mList = list;
    }
  • 实现几个必要的方法,比如获得Item以及覆写getItemCount方法

     /**
     * get a item by index
     *
     * @param position
     * @return
     */
    protected T getItem(int position) {
        return mList.get(position);
    }
    
    @Override
    public int getItemCount() {
        return mList.size();
    }
    
  • 实现将布局文件映射成View的方法
   /**
     * inflate a view by viewgroup ,id ,etc
     *
     * @param viewGroup
     * @param layoutId
     * @return
     */
    protected View inflateItemView(ViewGroup viewGroup, int layoutId) {
        return inflateItemView(viewGroup, layoutId, false);
    }

    /**
     * inflate a view by viewgroup ,id ,etc
     *
     * @param viewGroup
     * @param layoutId
     * @param attach
     * @return
     */
    protected View inflateItemView(ViewGroup viewGroup, int layoutId, boolean attach) {
        return LayoutInflater.from(viewGroup.getContext()).inflate(layoutId, viewGroup, attach);
    }
  • 实现onBindViewHolder方法,这一步很重要,将具体实现抽取到两个方法中去实现,bindDataToItemView是一个抽象方法,延迟到子类实现,bindItemViewClickListener方法设置监听器
  /**
     * a final function to avoid you override
     * use template design pattern
     *
     * @param vh
     * @param position
     */
    @Override
    public final void onBindViewHolder(VH vh, int position) {
        final T item = getItem(position);
        bindDataToItemView(vh, item);
        bindItemViewClickListener(vh, item);
    }

    /**
     * bind data to itemview
     *
     * @param vh   viewholder
     * @param item item
     */
    protected abstract void bindDataToItemView(VH vh, T item);
    /**
     * bind click listner to itemview
     *
     * @param vh   viewholder
     * @param item item
     */
    protected final void bindItemViewClickListener(VH vh, final T item) {
        if (mOnItemClickListener != null) {
            vh.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    mOnItemClickListener.onClick(view, item);
                }
            });
        }
        if (mOnItemLongClickListener != null) {
            vh.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    mOnItemLongClickListener.onLongClick(v, item);
                    return true;
                }
            });
        }
    }
  • 实现通用ViewHolder,内部使用SparseArray维持View对象
    public static class SparseArrayViewHolder extends RecyclerView.ViewHolder {
        private final SparseArray<View> views;

        public SparseArrayViewHolder(View itemView) {
            super(itemView);
            views = new SparseArray<View>();
        }

        public <T extends View> T getView(int id) {
            View view = views.get(id);
            if (view == null) {
                view = itemView.findViewById(id);
                views.put(id, view);
            }
            return (T) view;
        }
    }

内部实现了一个泛型的getView方法,其作用就是将View缓存至SparseArray中去

  • 实现通用ViewHolder的一些属性设置方法,采用链式调用,返回this对象
        public SparseArrayViewHolder setText(int viewId, String value) {
            TextView view = getView(viewId);
            view.setText(value);
            return SparseArrayViewHolder.this;
        }

        public SparseArrayViewHolder setTextColor(int viewId, int textColor) {
            TextView view = getView(viewId);
            view.setTextColor(textColor);
            return SparseArrayViewHolder.this;
        }

        public SparseArrayViewHolder setImageResource(int viewId, int imageResId) {
            ImageView view = getView(viewId);
            view.setImageResource(imageResId);
            return SparseArrayViewHolder.this;
        }

        public SparseArrayViewHolder setBackgroundColor(int viewId, int color) {
            View view = getView(viewId);
            view.setBackgroundColor(color);
            return SparseArrayViewHolder.this;
        }

        public SparseArrayViewHolder setBackgroundResource(int viewId, int backgroundRes) {
            View view = getView(viewId);
            view.setBackgroundResource(backgroundRes);
            return SparseArrayViewHolder.this;
        }

        public SparseArrayViewHolder setVisible(int viewId, boolean visible) {
            View view = getView(viewId);
            view.setVisibility(visible ? View.VISIBLE : View.GONE);
            return SparseArrayViewHolder.this;
        }

        public SparseArrayViewHolder setOnClickListener(int viewId, View.OnClickListener listener) {
            View view = getView(viewId);
            view.setOnClickListener(listener);
            return SparseArrayViewHolder.this;
        }

        public SparseArrayViewHolder setOnTouchListener(int viewId, View.OnTouchListener listener) {
            View view = getView(viewId);
            view.setOnTouchListener(listener);
            return SparseArrayViewHolder.this;
        }

        public SparseArrayViewHolder setOnLongClickListener(int viewId, View.OnLongClickListener listener) {
            View view = getView(viewId);
            view.setOnLongClickListener(listener);
            return SparseArrayViewHolder.this;
        }

        public SparseArrayViewHolder setTag(int viewId, Object tag) {
            View view = getView(viewId);
            view.setTag(tag);
            return SparseArrayViewHolder.this;
        }

源码

时间: 2024-12-08 16:57:36

RecyclerView通用适配器的实现的相关文章

让偷懒更彻底——用Butterknife 来为recyclerview 打造通用适配器(上)

背景 随着recyclerview 的越来越普及,其高度的易用性,让我们越来越爱不释手,当然网上也出现了很多类似的通用适配器,让我们更加方便的使用它,今天我们这里介绍一种新的recyclerview的通用适配器的实现思路--把recyclerview和ButterKnife结合起来使用(ps:因为公司开发一直使用butterknife,才有了这种想法). 首先贴上我的实现效果: 代码用法使用: ModelRecyclerAdapter adapter = new ModelRecyclerAda

RecyclerView的通用适配器的高级使用

前言 博主由于项目中频繁的使用了V7包中的RecyclerView来代替ListView的列表展示,所以抽空基于ListView的通用适配器的原理,给RecyclerView也写了一个通用适配器主要支持以下功能: 1.支持item的点击事件,在多布局的情况下可以指定生效的itemType 2.支持item中的控件的点击事件(博主觉得具有创新性),在多布局的情况下可以指定生效的itemType 3.支持添加和移除头部(博主没有写添加尾部的方法,其实和添加头部的方法是类似的,如果你有需要就自己参照着

RecyclerView的通用适配器

本来这一个主题应该早就写了,只是项目多,属于自己的时间不多,所以现在才开动!! 前一段时间写了一篇文章,是关于ListView,GriView万能适配器,没有看过的同学,可以先看看那篇文章,然后在来学习RecyclerView的话,会容易很多.链接http://www.cnblogs.com/huangjialin/p/7661328.html 当然,如果对RecyclerView基础不是了解的朋友,建议先去熟悉一下RecyclerView的基础知识! 闲话不多说,先简单的介绍一下这个Recyc

Android 5.0 v7扩展包之RecyclerView的使用以及通用适配器的封装实现

添加Gradle依赖 compile 'com.android.support:appcompat-v7:23.2.1'compile 'com.android.support:recyclerview-v7:23.2.1' 备注:recyclerview的版本号要与appcompat的一致,此处为: v7:23.2.1 以泛型方式定义通用RecyclerViewHold对象,内部以SparseArray存储View对象,提高xml的解析速度. /** * Created by Administ

使用通用适配器Base-adapter-helper

适配器写多了会有一种写到吐的感觉,今天来体验一下不用写适配器等待感觉,一般来说,我们写适配器都是重写getView方法,然后使用ViewHolder设计模式,在getView里进行数据绑定,写一次还好,写多了会感觉在不断做重复工作,那么有没有这么一个通用的适配器供我们使用,而不用写那么多次重复代码呢,答案是有的,见https://github.com/JoanZapata/base-adapter-helper,今天就使用一下这个适配器. 在这之前,先看下实现效果. 开始编写实体类,涉及到的就是

RecyclerView万能适配器

转载请申明:http://blog.csdn.net/yoyo_newbie/article/details/48130813 没次当我们用RecyclerView是时候,不得不想到要添加点击事件, 头部,尾部,甚至分组繁琐代码烦恼,于是本人就无奈写了共用的adapter. 使用说明: 如,item资源为 R.layout.fragment_jiongtu_item_of_indexfregment item里面有个imageview id为 R.id.iv_photo private clas

ListView通用适配器

package org.adapter; import java.lang.reflect.Field; import java.util.List; import java.util.Map; import java.util.Vector; import org.cache.TransformUtils; import android.content.Context; import android.view.LayoutInflater; import android.view.View;

RecyclerView的万能适配器+定义可以到底部自动刷新的RecyclerView

RecyclerView的重要性就不做重复说明了,为了方便以后直接使用写了这个,主要有: 万能适配器在使用的时候分为定义布局和绑定数据,方便直接套用.加入了底部刷新,需要配合自己写的RecyclerView一起使用,对于布局中各个子布局和控件可以做到响应各种点击事件: 首先抽取ViewHolder:这里的要点是用到了SparseArray(源码中类似ArrayList.直接使用Object数组进行实现): package com.fightzhao.baseadapterdemo.base; i

深入浅出 RecyclerView

常用方法 RecyclerView 与 ListView.GridView 类似,都是可以显示同一种类型 View 的集合的控件. 首先看看最简单的用法,四步走: 0.接入 build.gradle 文件中加入 compile 'com.android.support:recyclerview-v7:24.0.0' 1.创建对象 RecyclerView recyclerview = (RecyclerView) findViewById(R.id.recyclerview); 2.设置显示规则