概述

现在我们基本上不怎么使用ListView,而是使用RecyclerView代替了,关于如何引入和基本使用RecyclerView这里就不分享了,我们主要分享的是如何打造一个全能的适配器给RecyclerView使用。
本文的例子是一个可以添加头部和底部的RecyclerView,我们将在BaseAdapter去处理。

思路

1,我们需要一个BaseRecyclerAdapter去继承RecyclerView.Adapter
2,我们需要一个BaseRecyclerHolder去继承RecyclerView.ViewHolder
3,我们有三种类型的ViewType,一个是header,一种是正常的itemView,一种是bottom
4,我们需要自己集成onClick和onLongClick两种事件

实现

1,对于BaseRecyclerHolder,我们具体的ViewHolder使用一个简单的注入框架来实现View的初始化,所以我们在BaseRecyclerHolder引入,具体代码如下:

public abstract class BaseRecyclerHolder extends RecyclerView.ViewHolder {public View itemView;public BaseRecyclerHolder(View itemView) {super(itemView);this.itemView = itemView;ButterKnife.bind(this, itemView);}
}

需要注意的是他需要声明为一个独立的java文件,不能作为BaseRecyclerAdapter的内部类
对于onClick和onLongClick事件,我们使用泛型去实现具体的回调数据,具体代码,他们二者比较类似
OnRecyclerViewItemLongClickListener:

public interface OnRecyclerViewItemLongClickListener<T> {void onItemLongClick(View view, T t, int position);
}

OnRecyclerViewItemClickListener:

public interface OnRecyclerViewItemClickListener<T> {void onItemClick(View view, T t, int position);
}

对于BaseRecyclerAdapter,我们需要重写RecyclerView.Adapter的一些方法,首先是onCreateViewHolder方法,我们在这里判断需要创建的Holder的类型,一共三种,一种是header的一种是bottom的,一种是itemView的,具体代码:

 @Overridepublic final BaseRecyclerHolder onCreateViewHolder(ViewGroup parent, int viewType) {View itemtView;if (viewType == ITEM_TYPE_HEADER) {itemtView = LayoutInflater.from(App.me()).inflate(getHeaderLayout(), parent, false);return getBottomHolder(itemtView);} else if (viewType == ITEM_TYPE_BOTTOM) {itemtView = LayoutInflater.from(App.me()).inflate(getBottomLayout(), parent, false);return getHeaderHolder(itemtView);} else if (viewType == ITEM_TYPE_CONTENT) {itemtView = LayoutInflater.from(App.me()).inflate(getItemLayout(), parent, false);return getHolder(itemtView);}return null;}

使用final是不需要子类去重写这个方法。
然后,我们需要在onBindViewHolder方法绑定数据的时候判断是属于哪一种ViewHolder,然后做不同的处理。具体代码

   public final void onBindViewHolder(BaseRecyclerHolder holder, int position) {if (isBottomView(position)) {converBottomHolderView(holder);} else if (isHeaderView(position)) {converHeaderHolderView(holder);} else {// 需要注意获取数据时候开始的位置,需要减去头部占据的sizeholder.itemView.setTag(position-mHeaderCount);holder.itemView.setOnClickListener(this);holder.itemView.setOnLongClickListener(this);converHolderView(holder, mDatas.get(position-mHeaderCount), position-mHeaderCount);}}

这里需要注意的一个点是我们的itemView的数据计算,他是需要减去header的数量之后才是正确的。
完整代码:
BaseRecyclerAdapter:

import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;import com.liweijie.design.graduation.gallery.app.App;
import com.liweijie.design.graduation.gallery.event.OnRecyclerViewItemClickListener;
import com.liweijie.design.graduation.gallery.event.OnRecyclerViewItemLongClickListener;
import com.liweijie.design.graduation.gallery.util.L;import java.util.ArrayList;
import java.util.List;/*** Created by liweijie on 2016/3/28.**/
public abstract class BaseRecyclerAdapter<T> extends RecyclerView.Adapter<BaseRecyclerHolder> implements View.OnClickListener, View.OnLongClickListener {private List<T> mDatas = new ArrayList<>();protected OnRecyclerViewItemClickListener<T> mOnItemClickListener;protected OnRecyclerViewItemLongClickListener<T> mOnItemLongClickListener;private int mHeaderCount ;//头部View个数private int mBottomCount ;//底部View个数//三种类型public static final int ITEM_TYPE_HEADER = 0;public static final int ITEM_TYPE_CONTENT = 1;public static final int ITEM_TYPE_BOTTOM = 2;public BaseRecyclerAdapter(List<T> mDatas, int mHeaderCount, int mBottomCount) {this.mDatas.addAll(mDatas);this.mHeaderCount = mHeaderCount;this.mBottomCount = mBottomCount;}@Overridepublic final BaseRecyclerHolder onCreateViewHolder(ViewGroup parent, int viewType) {View itemtView;if (viewType == ITEM_TYPE_HEADER) {itemtView = LayoutInflater.from(App.me()).inflate(getHeaderLayout(), parent, false);return getBottomHolder(itemtView);} else if (viewType == ITEM_TYPE_BOTTOM) {itemtView = LayoutInflater.from(App.me()).inflate(getBottomLayout(), parent, false);return getHeaderHolder(itemtView);} else if (viewType == ITEM_TYPE_CONTENT) {itemtView = LayoutInflater.from(App.me()).inflate(getItemLayout(), parent, false);return getHolder(itemtView);}return null;}/**** @param holder* @param position*/@Overridepublic final void onBindViewHolder(BaseRecyclerHolder holder, int position) {if (isBottomView(position)) {converBottomHolderView(holder);} else if (isHeaderView(position)) {converHeaderHolderView(holder);} else {// 需要注意获取数据时候开始的位置,需要减去头部占据的sizeholder.itemView.setTag(position-mHeaderCount);holder.itemView.setOnClickListener(this);holder.itemView.setOnLongClickListener(this);converHolderView(holder, mDatas.get(position-mHeaderCount), position-mHeaderCount);}}@Overridepublic int getItemCount() {return mDatas.size() + mHeaderCount + mBottomCount;}public int getContentCount() {return mDatas.size();}//判断当前item是否是HeadViewpublic boolean isHeaderView(int position) {return mHeaderCount != 0 && position < mHeaderCount;}//判断当前item是否是FooterViewpublic boolean isBottomView(int position) {L.i("Bottom",position+"==" +(mHeaderCount+getContentCount()));return mBottomCount != 0 && position >= (mHeaderCount + getContentCount());}@Overridepublic int getItemViewType(int position) {int dataItemCount = getContentCount();// 第一个if (mHeaderCount != 0 && position < mHeaderCount) {//头部Viewreturn ITEM_TYPE_HEADER;} else if (mBottomCount != 0 && position >= (mHeaderCount + dataItemCount)) { //底部//底部Viewreturn ITEM_TYPE_BOTTOM;} else {//内容Viewreturn ITEM_TYPE_CONTENT;}}public abstract BaseRecyclerHolder getHolder(View itemtView);/*** 子类需要,子类实现** @return*/public BaseRecyclerHolder getBottomHolder(View itemtView) {return null;}/*** 子类需要,子类实现** @return*/public BaseRecyclerHolder getHeaderHolder(View itemtView) {return null;}public abstract int getItemLayout();/*** 子类需要,子类实现** @return*/public int getHeaderLayout() {return 0;}/*** 子类需要,子类实现** @return*/public int getBottomLayout() {return 0;}public abstract void converHolderView(BaseRecyclerHolder holder, T t, int position);/*** 子类需要,子类实现** @return*/public void converBottomHolderView(BaseRecyclerHolder holder) {}/*** 子类需要,子类实现** @return*/public void converHeaderHolderView(BaseRecyclerHolder holder) {}// 一般操作public void add(T t) {mDatas.add(t);this.notifyDataSetChanged();}public T get(int position) {return mDatas.size() <= position ? mDatas.get(position) : null;}public List<T> getDatas() {return mDatas;}// 事件相关public void setOnItemClickListener(OnRecyclerViewItemClickListener<T> listener) {this.mOnItemClickListener = listener;}public void setOnItemLongClickListener(OnRecyclerViewItemLongClickListener<T> listener) {this.mOnItemLongClickListener = listener;}// 事件@Overridepublic void onClick(View v) {if (mOnItemClickListener != null) {int position = (int) v.getTag();mOnItemClickListener.onItemClick(v, mDatas.get(position), position);}}@Overridepublic boolean onLongClick(View v) {if (mOnItemLongClickListener != null) {int position = (int) v.getTag();mOnItemLongClickListener.onItemLongClick(v, mDatas.get(position), position);}return false;}}

这样子,我们通过抽闲方法让子类实现,通过一些header或者是bottom的方法,让子类选择实现,避免无用代码。
使用:

public class CollectFragmentAdapter extends BaseRecyclerAdapter<ImageBean> {public CollectFragmentAdapter(List<ImageBean> mDatas) {super(mDatas, 1, 1);}@Overridepublic BaseRecyclerHolder getHolder(View itemtView) {return new CollectHolder(itemtView);}@Overridepublic int getItemLayout() {return R.layout.item_gallery_all_pic;}@Overridepublic int getHeaderLayout() {return R.layout.core_blank_view;}@Overridepublic int getBottomLayout() {return R.layout.core_blank_view;}@Overridepublic BaseRecyclerHolder getBottomHolder(View itemtView) {return new CollectBottomHolder(itemtView);}@Overridepublic BaseRecyclerHolder getHeaderHolder(View itemtView) {return new CollectHeaderHolder(itemtView);}@Overridepublic void converHolderView(BaseRecyclerHolder holder, ImageBean imageBean, int position) {if (holder instanceof CollectHolder) {CollectHolder localHolder = (CollectHolder) holder;localHolder.collect_item_tv_cont.setText(String.valueOf(imageBean.getCount()));localHolder.collect_item_tv_name.setText("" + imageBean.getName());MyImageLoader.getInstance(2, MyImageLoader.Type.LIFO).loadImage(imageBean.getFirstImage(), localHolder.collect_item_iv_first);}}class CollectHolder extends BaseRecyclerHolder {@Bind(R.id.collect_item_iv_first)ImageView collect_item_iv_first;@Bind(R.id.collect_item_tv_name)TextView collect_item_tv_name;@Bind(R.id.collect_item_tv_cont)TextView collect_item_tv_cont;public CollectHolder(View itemView) {super(itemView);}}class CollectHeaderHolder extends BaseRecyclerHolder {public CollectHeaderHolder(View itemView) {super(itemView);}}class CollectBottomHolder extends BaseRecyclerHolder {public CollectBottomHolder(View itemView) {super(itemView);}}
}

这样子就行了,以后我们的Adapter就可以继承这个BaseRecyclerAdapter了。
使用longclock事件:

mAdapter.setOnItemLongClickListener(new OnRecyclerViewItemLongClickListener<ImageBean>() {@Overridepublic void onItemLongClick(View view, ImageBean bean, int position) {}});

使用click事件类似。

RecyclerView的全能适配器,带有header和bottom相关推荐

  1. 第7天 Recyclerview万能的适配器(基本使用、分割线、增加删除动画)

    第7天 Recyclerview万能的适配器(基本使用.分割线.增加删除动画) Recyclerview的使用 思路 代码 Recyclerview的使用 用了很长一段时间的RecyclerView, ...

  2. ROS中自定义带有header的消息文件

    ROS中自定义带有header的消息文件 为什么需要header? 在发布端发布的数据或者在订阅端订阅数据时,数据通常是连续发布或者被订阅的,这些信息没有特定的标识,搞得我们发和收了很多消息,都不知道 ...

  3. Android RecyclerView简单通用适配器

    一直都想写一个通用的RecyclerView适配器,但是一直都无从下手,后来看了鸿洋大神的博客后才知道怎么写,并且在此基础上添加了点自己的东西,终于算是大功告成.先上代码看看 public class ...

  4. RecyclerView超级万能适配器(多布局、head、foot、下拉刷新、上拉自动更多、滑动删除)

    使用方法 GitHub APK下载 将libray模块复制到项目中,或者直接在build.gradle中依赖: allprojects {repositories {maven { url 'http ...

  5. kotlin中RecyclerView.Adapter通用适配器

    文章目录 结合databinding,livedata BaseViewHolder BaseAdapter recycleView通用adapter 使用 数据bean ViewModel 绑定it ...

  6. 一个适用于ListView/GridView/RecyclerView的通用适配器

    简化大量重复代码 支持多布局 自定义图片加载 常用数据操作 view复用 RecyclerView item 点击和长按事件 GitHub源码地址 简书地址 gradle依赖 dependencies ...

  7. 实现带header和footer功能的RecyclerView

    这个项目很简单,其实一年前就开发完成了,但是一直没闲下来去整理. RecyclerView是Android 5.0版本引入的一个新的组件,目的是在一些场景中取代之前ListView和GridView, ...

  8. 实现带header和footer功能的RecyclerView——完善篇

    在上一篇文章中我们实现了实现带header和footer功能的RecyclerView,见  实现带header和footer功能的RecyclerView 但是由于加入了header,item的po ...

  9. ListView、AdapterView、RecyclerView全面解析

    原文链接:http://blog.csdn.net/carson_ho/article/details/51472640 AdapterView简介 AdapterView本身是一个抽象类,Adapt ...

最新文章

  1. 如何删除sublime目录
  2. 关于逻辑回归,面试官们都怎么问
  3. gdb info frame信息解释
  4. P1040,jzoj1167-加分二叉树【树形dp】
  5. 一些Select检索高级用法
  6. maya python 游戏与影视编程指南_《Maya Python游戏与影视编程指南》【价格 目录 书评 正版】_中国图书网...
  7. 大会门票限免最后一周!来聊聊 NVIDIA、抖音等大厂的 AI 技术落地
  8. Replication--复制延迟的诊断和解决
  9. python做带数据库的登录界面_Python3 Tkinkter + SQLite实现登录和注册界面
  10. Python网络爬虫与信息提取[request库的应用](单元一)
  11. angular drag and drop (ngDraggable) 笔记
  12. MVC中 关于退出按钮的写法
  13. linux常用命令的全拼(转载)
  14. gatsbyjs 了解
  15. 【一】如果让我学习TensorFlow,我该怎么学?
  16. Winform解决界面重绘闪烁的问题
  17. Android好用的音乐,安卓手机音乐播放器哪个好用?十大最好音乐播放器介绍
  18. labview与matlab接口,LabVIEW Comms与MATLAB®的互联接口
  19. 恶意软件隐身术:把可执行文件隐藏在注册表里
  20. 笔记本电脑开机后,屏幕无反应,插入的鼠标和键盘无灯亮起

热门文章

  1. JSAPI支付——H5网页端调起支付接口
  2. 怎么知道本台计算机的用户名和密码,访问其它电脑时“开始-运行-\输入要连接的电脑的IP,用户名和密码输入什么?...
  3. C语言(二级基础知识2)
  4. thinkphp6 jwt扩展
  5. 说谎者的辩白 -卢梭
  6. 全球仅通过不到 2000 位的 Elastic 认证工程师,到底难不难?
  7. ShaderJoy —— “水面波纹消散” 的实现 【GLSL】
  8. 技术小黑屋投稿开放了
  9. vue项目前端实现pdf文件下载
  10. 【spring 的 init and destory 方法】