RecyclerView的通用适配器
本来这一个主题应该早就写了,只是项目多,属于自己的时间不多,所以现在才开动!!
前一段时间写了一篇文章,是关于ListView,GriView万能适配器,没有看过的同学,可以先看看那篇文章,然后在来学习RecyclerView的话,会容易很多。链接http://www.cnblogs.com/huangjialin/p/7661328.html
当然,如果对RecyclerView基础不是了解的朋友,建议先去熟悉一下RecyclerView的基础知识!
闲话不多说,先简单的介绍一下这个RecyclerView,它是Android5.0的时候出来的一个新控件,主要目的就是替代ListView和GridView,也就是说RecyclerView能够实现ListView和GridView的效果,甚至比原来的更好,更方便,
我们知道,在写ListView和GridView的时候,都需要写一个适配器,然后继承BaseAdapter,接着实现几个方法,套路都是一样的,但是前一段时间写了一个通用的适配器,所以在写ListView和GridView的adapter的时候,可以省了很多事,方便了许多,那么,问题来了,
RecyclerView的通用适配器怎么写呢???
我们知道,在写ListView和GridView的适配器时候,我们需要考虑view的复用机制,但是RecyclerView内部已经帮我们写好了复用机制,所以,我们不需要考虑复用的情况,先不说,从ViewHolder开始
通用ViewHoler
package com.xiaoma.xting.adapter; 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;
import android.widget.ImageView;
import android.widget.TextView; /**
* Created by Administrator on 2017/11/6 0006.
* huangjialin
*/ public class BaseViewHolder extends RecyclerView.ViewHolder {
private SparseArray<View> mViews; //用来存储控件
private View mConvertView;
private Context mContext; public BaseViewHolder(Context context, View itemView) {
super(itemView);
this.mContext = context;
mConvertView = itemView;
mViews = new SparseArray<View>();
} /**
* 提供一个获取ViewHolder的方法
*/
public static BaseViewHolder getRecyclerHolder(Context context, ViewGroup parent, int layoutId) {
View itemView = LayoutInflater.from(context).inflate(layoutId, parent, false);
BaseViewHolder viewHolder = new BaseViewHolder(context, itemView);
return viewHolder;
} /**
* 获取控件
*/
public <T extends View> T getView(int viewId) {
View view = mViews.get(viewId);
if (view == null) {
view = mConvertView.findViewById(viewId);
mViews.put(viewId, view);
}
return (T) view;
} /**
* 给TextView设置setText方法
*/
public BaseViewHolder setText(int viewId, String text) {
TextView tv = getView(viewId);
tv.setText(text);
return this;
} /**
* 给ImageView设置setImageResource方法
*/
public BaseViewHolder setImageResource(int viewId, int resId) {
ImageView view = getView(viewId);
view.setImageResource(resId);
return this;
} /**
* 添加点击事件
*/
public BaseViewHolder setOnClickListener(int viewId, View.OnClickListener listener) {
View view = getView(viewId);
view.setOnClickListener(listener);
return this;
}
}
代码中,创建了BaseViewHolder,并且继承RecyclerView的ViewHoler,我们对外提供两个方法,一个是获取viewholder的getRecyclerHolder()方法,另一个是获取控件的getView()方法,由于RecyclerView的保存控件的方式是以变量的形式来,而这里则是通过SparseArray来通过key来进行存储的。
通用适配器
前面viewholer,现在看看adapter,先上代码
package com.example.administrator.recylerviewadaptertest; import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup; import java.util.List; /**
* Created by Administrator on 2017/11/6 0006.
* huangjialin
* 普通类型的适配器
*/ public abstract class BaseRecyclerAdapter<T> extends RecyclerView.Adapter<BaseViewHolder> {
private Context mContext;
private int mLayoutId;
private List<T> mData; public BaseRecyclerAdapter(Context mContext, int mLayoutId, List<T> mData) {
this.mContext = mContext;
this.mLayoutId = mLayoutId;
this.mData = mData;
} @Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
BaseViewHolder viewHolder = BaseViewHolder.getRecyclerHolder(mContext, parent, mLayoutId);
return viewHolder;
} @Override
public void onBindViewHolder(BaseViewHolder holder, int position) {
convert(holder, mData.get(position)); } @Override
public int getItemCount() {
return mData.size();
} /**
* 对外提供的方法
*/
public abstract void convert(BaseViewHolder holder, T t); }
代码不多,也相对简单,在onCreateViewHolder()方法中,获取到viewholer,然后我们自己定义一个convert()方法,对外提供该方法。那么,我们怎么用呢?
package com.example.administrator.recylerviewadaptertest; import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.TextView; import java.util.ArrayList;
import java.util.List; public class MainActivity extends Activity {
private RecyclerView recycler;
private BaseRecyclerAdapter mAdapter;
private List<String> stringList = new ArrayList<String>(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); recycler = findViewById(R.id.recycler); mAdapter = new BaseRecyclerAdapter<String>(this, R.layout.rl_item_view, stringList) {
@Override
public void convert(BaseViewHolder holder, String s) {
holder.setText(R.id.test, s);
}
}; LinearLayoutManager manager = new LinearLayoutManager(this);
recycler.setLayoutManager(manager);
recycler.setAdapter(mAdapter); for (int i = 0; i < 50; i++) {
stringList.add("测试-->" + i);
}
mAdapter.notifyDataSetChanged(); }
}
这些都相对来说很简单如果有朋友觉得看不懂的话,我强烈建议先去看一下前面写的ListView通用适配器,然后回来你就会发现很简单了,套路都是差不多。
ItemViewType
前面写的相对来说是针对与一些常见的列表布局,如果说复杂一些的布局,可能就行不通了,比如说我一个列表第一个item垂直显示若干个控件,第二个item我水平显示若干个控件,按照以往的经验,我们通常会
在adapter中实现getItemViewType()方法,然后进行一些判断,但是通用适配器中改怎么实现呢??
从前面获取viewholder的时候,我们知道viewholder是通过布局来id来进行获取的,那么,我们能不能这样写呢,我们通过不同的布局,来获取不同的viewholder呢
我们在BaseRecyclerAdapter中加上这个接口
/**
* 针对多种类型的itemView
* @param <T>
*/
public interface ConmonItemType<T> {
int getLayoutId(int itemType); //不同的Item的布局 int getItemViewType(int position, T t); //type
}
然后我们新创建一个adapter并且继承BaseRecyclerAdapter,代码:
package com.example.administrator.recylerviewadaptertest; import android.content.Context;
import android.view.ViewGroup; import java.util.List; /**
* Created by Administrator on 2017/11/6 0006.
* huangjialin
* 如果列表的布局item有多种类型,则需要继承该适配器
*/ public abstract class MultiItemCommonAdapter<T> extends BaseRecyclerAdapter<T> {
private ConmonItemType<T> mConmonItemType;
private List<T> mDatas;
private Context mContext; public MultiItemCommonAdapter(Context mContext, List<T> mData, ConmonItemType<T> conmonItemType) {
super(mContext, -1, mData);
this.mConmonItemType = conmonItemType;
mDatas = mData;
this.mContext = mContext;
} @Override
public int getItemViewType(int position) {
return mConmonItemType.getItemViewType(position, mDatas.get(position));
} @Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
int layoutId = mConmonItemType.getLayoutId(viewType);
BaseViewHolder holder = BaseViewHolder.getRecyclerHolder(mContext, parent, layoutId);
return holder;
}
}
从代码可以看出,我们通过构造方法从外面传进来的ConmonItemType<T> conmonItemType,通过这个来获取不同的布局,从而获取到不同的viewholer,看看怎么使用:
package com.example.administrator.recylerviewadaptertest; import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.widget.TextView; import java.util.ArrayList;
import java.util.List; public class MainActivity extends Activity {
private RecyclerView recycler;
private BaseRecyclerAdapter mAdapter;
private List<String> stringList = new ArrayList<String>(); private MultiItemCommonAdapter adapter;
private int typeOne = 1;
private int typeTwo = 2; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); recycler = findViewById(R.id.recycler); /**
* 普通的列表形式
*/
// mAdapter = new BaseRecyclerAdapter<String>(this, R.layout.rl_item_view, stringList) {
// @Override
// public void convert(BaseViewHolder holder, String s) {
// holder.setText(R.id.test, s);
// }
// };
//
// LinearLayoutManager manager = new LinearLayoutManager(this);
// recycler.setLayoutManager(manager);
// recycler.setAdapter(mAdapter);
//
//
// for (int i = 0; i < 50; i++) {
// stringList.add("测试-->" + i);
// }
// mAdapter.notifyDataSetChanged(); /**
* 不同item布局的形式
*/
BaseRecyclerAdapter.ConmonItemType conmonItemType = new BaseRecyclerAdapter.ConmonItemType<String>() { @Override
public int getLayoutId(int itemType) {
if (itemType == typeOne) {
return R.layout.item_one;
} else {
return R.layout.item_two;
}
} @Override
public int getItemViewType(int position, String s) {
if (position == 0) {
return typeOne;
} else {
return typeTwo;
}
}
}; for (int i = 0; i < 2; i++) {
stringList.add("测试-->" + i);
} adapter = new MultiItemCommonAdapter<String>(this, stringList, conmonItemType) {
@Override
public void convert(BaseViewHolder holder, String s) {
if (holder.getItemViewType() == 0) {
//Todo } else {
//Todo
}
}
};
LinearLayoutManager manager = new LinearLayoutManager(this);
recycler.setLayoutManager(manager);
recycler.setAdapter(adapter); }
}
在这里我是自己定义的typeone,和typetwo,在项目中我们可以根据bean来进行判断,不同的类型,返回不同的值,从而获取不同的item布局,ok,这样的话,我们的多种ItemViewType的支持也就完成了
源码链接:https://github.com/343661629/RecyclerView-
RecyclerView的通用适配器的更多相关文章
- RecyclerView的通用适配器,和滚动时不加载图片的封装
对于RecyclerView我们需要使用RecyclerAdapter,使用方式与ListViewAdapter类似,具体代码大家可以在网上搜索,这里就只教大家使用封装后的简洁RecyclerAdap ...
- RecyclerView高速通用适配Adapter
RecyclerView Adapter 为RecyclerView提供更简单的适配器实现方式,不断更新完好中. Demo视频演示 GitHub地址 博客 使用 BaseViewHolder 的使用 ...
- listview-android:打造万能通用适配器(转)
转载:https://blog.csdn.net/q649381130/article/details/51781921: 1.前言 listview作为安卓项目中一个的明星控件,它的适配器的写法是广 ...
- ListView ,GridView 通用适配器
前言 接近半年的时间没有写博客了,今年公司的项目有点多,比较忙,没时间写,这是其一.其次是,这半年来,有时间的时候,我都会看看自己以前写的博客,也许是以前刚刚写博客,经验不足,感觉写出来的博客质量很不 ...
- RecyclerView通用适配器
在Android开发中使用列表呈现数据的情况很多,现在我们常用RecyclerView呈现列表,为了开发敏捷和代码优雅,我们现在来打造<?xml version="1.0" ...
- 为RecyclerView打造通用Adapter
##RecycleView简单介绍 RecyclerView控件和ListView的原理有非常多相似的地方,都是维护少量的View来进行显示大量的数据.只是RecyclerView控件比ListVie ...
- 为RecyclerView打造通用Adapter 让RecyclerView更加好用
原文出处: 张鸿洋 (Granker,@鸿洋_ ) 一.概述 记得好久以前针对ListView类控件写过一篇打造万能的ListView GridView 适配器,如今RecyclerView异军突起, ...
- 打造android偷懒神器———RecyclerView的万能适配器
转载请注明出处谢谢:http://www.cnblogs.com/liushilin/p/5720926.html 很不好意思让大家久等了,本来昨天就应该写这个的,无奈公司昨天任务比较紧,所以没能按时 ...
- RecyclerView打造通用的万能Adapter
既然想做到通用那么现在摆在面前的就三个问题:数据怎么办?布局怎么办? 绑定怎么办?.数据决定采用泛型,布局打算直接构造传递,绑定显示效果肯定就只能回传. 1 基本改造 数据决定采用泛型,布局打算直接构 ...
随机推荐
- Taints和Tolerations
Taints和Tolerations和搭配使用的,Taints定义在Node节点上,声明污点及标准行为,Tolerations定义在Pod,声明可接受得污点. 可以在命令行为Node节点添加Taint ...
- idea提示,格式化代码,清除不使用的包快捷键,maven自动导jar包
一.提示快捷键 idea默认快捷键是ctrl+space,通常和别的软件快捷键冲突,所以将快捷键修改为alt+/ 二.格式化快捷键ctrl+alt+l,通常和qq.tim快捷键冲突,请修改qq或者ti ...
- POJ2533 最长递增子序列
描述: 7 1 7 3 5 9 4 8 输出4 最长递增子序列为1 3 5 9,不必连续. 解法: 三种思路: 转化为最长公共子序列(n^2),动态规划(n^2),不知叫什么解法(nlogn). 解法 ...
- (转)Java 中关于String的空对象(null) ,空值(empty),空格
原文出处:Java 中关于String的空对象(null) ,空值(empty),空格 定义 空对象: String s = null; 空对象是指定义一个对象s,但是没有给该对象分配空间,即没有实例 ...
- 21-py3 发邮件
Python3 SMTP发送邮件 SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式. p ...
- Python 关于数组矩阵变换函数numpy.nonzero(),numpy.multiply()用法
1.numpy.nonzero(condition),返回参数condition(为数组或者矩阵)中非0元素的索引所形成的ndarray数组,同时也可以返回condition中布尔值为True的值索引 ...
- jFinal render为什么不跳转到指定的页面
jFinal render为什么不跳转到指定的页面 1:需要在你自己的主配置文件里面配置所有页面的文件前缀,没配置默认是项目的根目录 //配置页面访问主路径 me.setBaseViewPath(&q ...
- Jenkins执行selenium报错unknown error: cannot find Chrome binary
问题描述:在Pycharm中执行selenium测试用例,可以正常运行, 集成在Jenkins中,构建时,发现构建成功,但是查看Console Output,报错:unknown error: can ...
- Android代码实现求和运算
Android代码实现求和运算 实验要求: 用Android语言设计一个界面,点击某按钮实现求和运算. 代码实现 码云链接 核心代码 以上为求和按钮的代码截图,解析如图标注. 实验结果 当输入为空值时 ...
- WebDriver高级应用——操作Web页面的滚动条
目的: (1)滑动页面的滚动条到页面最下方 (2)滑动页面的滚动条到页面某个元素 (3)滑动页面的滚动条向下移动某个数量的像素 测试的网址: http://www.seleniumhq.org/ 代码 ...