2019年3月18日 10:53:27

参照博文:Android 快速开发系列 打造万能的ListView GridView 适配器

一 BaseViewHolder

public class BaseViewHolder {
private final SparseArray<View> mViews;
private View mConvertView;
private int mPosition; private BaseViewHolder(Context context, ViewGroup parent, int layoutId,
int position) {
this.mViews = new SparseArray<View>();
mConvertView = LayoutInflater.from(context).inflate(layoutId, parent,
false);
this.mPosition = position;
//setTag
mConvertView.setTag(this); }
/**
* 拿到一个ViewHolder对象
*
* @param context
* @param convertView
* @param parent
* @param layoutId
* @param position
* @return
*/
public static BaseViewHolder getViewHolder(Context context, View convertView,
ViewGroup parent, int layoutId, int position) { if (convertView == null) {
return new BaseViewHolder(context, parent, layoutId, position);
}else{
BaseViewHolder holder = (BaseViewHolder)convertView.getTag();
holder.mPosition = position;
return holder;
}
} /**
* 通过控件的Id获取对于的控件,如果没有则加入views
*
* @param viewId
* @return
*/
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;
} public View getConvertView() {
return mConvertView;
} }

  

  首先分析下ViewHolder的作用,通过convertView.setTag与convertView进行绑定,然后当convertView复用时,直接从与之对于的ViewHolder(getTag)中拿到convertView布局中的控件,省去了findViewById的时间~

也就是说,实际上们每个convertView会绑定一个ViewHolder对象,这个viewHolder主要用于帮convertView存储布局中的控件。那么我们只要写出一个通用的ViewHolder,然后对于任意的convertView,提供一个对象让其setTag即可;

  既然是通用,那么我们这个ViewHolder就不可能含有各种控件的成员变量了,因为每个Item的布局是不同的,最好的方式是什么呢?

提供一个容器,专门存每个Item布局中的所有控件,而且还要能够查找出来;既然需要查找,那么ListView肯定是不行了,需要一个键值对进行保存,键为控件的Id,值为控件的引用,相信大家立刻就能想到Map;但是我们不用Map,因为有更好的替代类,就是我们android提供的SparseArray这个类,和Map类似,但是比Map效率,不过键只能为Integer.
  我们使用了一个SparseArray<View>用于存储与之对于的convertView的所有的控件,当需要拿这些控件时,通过getView(id)进行获取;

二 CommonAdapter

  下面看如何打造一个通过的Adapter,我们叫做CommonAdapter继续分析,Adapter一般需要保持一个List对象,存储一个Bean的集合,不同的ListView,Bean肯定是不同的,这个CommonAdapter肯定需要支持泛型,内部维持一个List<T>,就解决我们的问题了;

  对外公布了一个convert方法,并且还把viewHolder和本Item对于的Bean对象给传出去。

public abstract class CommonAdapter<T> extends BaseAdapter {
protected LayoutInflater mInflater;
protected Context mContext;
protected List<T> mDatas;
protected int mItemLayoutId; public CommonAdapter(Context context, List<T> datas, int itemLayoutId) {
this.mInflater = LayoutInflater.from(context);
this.mContext = context;
this.mDatas = datas;
this.mItemLayoutId = itemLayoutId;
} @Override
public int getCount() {
return mDatas.size();
} @Override
public T getItem(int i) {
return mDatas.get(i);
} @Override
public long getItemId(int i) {
return i;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
final BaseViewHolder baseViewHolder = getViewHolder(position, convertView,
parent);
convert(baseViewHolder, getItem(position));
return baseViewHolder.getConvertView(); } public abstract void convert(BaseViewHolder helper, T item); private BaseViewHolder getViewHolder(int position, View convertView,
ViewGroup parent) {
return BaseViewHolder.getViewHolder(mContext, convertView, parent, mItemLayoutId,
position);
} }

三 MyAdapter继承CommonAdapter

  convert方法是具体实现CommonAdapter中的抽象方法。

public class MyAdapter extends CommonAdapter {

    public MyAdapter(Context context, List datas, int itemLayoutId) {
super(context, datas, itemLayoutId);
} @Override
public void convert(BaseViewHolder viewHolder, Object item) {
Bean bean = (Bean) item;
((TextView)viewHolder.getView(R.id.id_title)).setText(bean.getTitle());
((TextView)viewHolder.getView(R.id.id_info)).setText(bean.getInfo());
((TextView)viewHolder.getView(R.id.id_time)).setText(bean.getTime());
} }

四 MainActivity实现CommonAdapterActivity

public class CommonAdapterActivity extends Activity {

    @BindView(R.id.id_lv_main)
ListView idLvMain;
private ArrayList<Bean> mDatas; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_common_adapter);
ButterKnife.bind(this);
initData();
initListView();
} private void initListView() {
idLvMain.setAdapter(new MyAdapter(this, mDatas, R.layout.item_single_str));
idLvMain.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(CommonAdapterActivity.this, "" + mDatas.get(i).getTitle(), Toast.LENGTH_SHORT).show();
}
});
} private void initData() {
mDatas = new ArrayList<Bean>();
for (int i = 1; i <= 10; i++) {
mDatas.add(new Bean("我是标题 " + i, "Android打造ListView和GridView万能适配器", "2016-09-28"));
}
}
}

五 bean文件

记录了要显示的内容类

public class Bean {

    private String title;
private String info;
private String time; public Bean(String title, String info, String time) {
this.title = title;
this.info = info;
this.time = time;
} public Bean() {
} public String getTitle() {
return title;
} public void setTitle(String title) {
this.title = title;
} public String getInfo() {
return info;
} public void setInfo(String info) {
this.info = info;
} public String getTime() {
return time;
} public void setTime(String time) {
this.time = time;
}
}

六 总结

  如上所示,定义的BaseViewHolder跟CommonAdapter不需要改动,我们使用过程中只需要,定义一个对应的Bean类、MyAdapter及其对应的布局即可。

代码地址:https://dev.tencent.com/u/MichaelPan9999/p/CommonAdapter/git

设计通用的Adapter的更多相关文章

  1. 解析大型.NET ERP系统 设计通用Microsoft Excel导入功能

    做企业管理软件很难避免与Microsoft Excel打交道,常常是软件做好了,客户要求说再做一个Excel导入功能.导入Excel数据的功能的难度不大,从Excel列数据栏位的取值,验证值,再导入到 ...

  2. 使用java泛型设计通用方法

    泛型是Java SE 1.5的新特性, 泛型的本质是参数化类型, 也就是说所操作的数据类型被指定为一个参数. 因此我们可以利用泛型和反射来设计一些通用方法. 现在有2张表, 一张user表和一张stu ...

  3. 通用访问 - 用“反射”来设计通用的通信协议,以及配套的SDK、工具

    1. 效果演示 2. 通信协议 功能介绍 特点 TCP协议 WebApi协议 3. SDK与工具 4. 应用示例 迷你网管 通用GIS 系统管理 5. 设计初衷与演化   1. 效果演示     服务 ...

  4. RecyclerView高速通用适配Adapter

    RecyclerView Adapter 为RecyclerView提供更简单的适配器实现方式,不断更新完好中. Demo视频演示 GitHub地址 博客 使用 BaseViewHolder 的使用 ...

  5. 通用的Adapter

    activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu ...

  6. 利用JAVA反射机制设计通用的DAO

    利用JAVA反射机制设计一个通用的DAO 反射机制 反射机制指的是程序在运行时能够获取自身的信息.在java中,只要给定类的名字,    那么就可以通过反射机制来获得类的所有信息. 反射机制创建类对象 ...

  7. 为RecyclerView打造通用Adapter

    ##RecycleView简单介绍 RecyclerView控件和ListView的原理有非常多相似的地方,都是维护少量的View来进行显示大量的数据.只是RecyclerView控件比ListVie ...

  8. 为RecyclerView打造通用Adapter 让RecyclerView更加好用

    原文出处: 张鸿洋 (Granker,@鸿洋_ ) 一.概述 记得好久以前针对ListView类控件写过一篇打造万能的ListView GridView 适配器,如今RecyclerView异军突起, ...

  9. 痞子衡嵌入式:嵌入式里通用微秒(microseconds)计时函数框架设计与实现

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是嵌入式里通用微秒(microseconds)计时函数框架设计与实现. 在嵌入式软件开发里,计时可以说是非常基础的功能模块了,其应用也非常 ...

随机推荐

  1. 加载hive-jdbc driver时报错:java.lang.NoClassDefFoundError: org/apache/hadoop/conf/Configuration

    这是因为缺少一个hadoop-common包,引入即可: <dependency> <groupId>org.apache.hadoop</groupId> < ...

  2. 使用Excel批量提取文件名

    Excel中如何快速选择所有奇数行或偶数行? 方法3:=MOD(ROW(),2) 总结:方法1和方法2的区别主要在ctrl键的使用 轻松将一个文件夹里所有的文件名提取出来,放到Excel表格里 &qu ...

  3. 【AGC030D】Inversion Sum DP

    题目大意 有一个序列 \(a_1,a_2,\ldots,a_n\),有 \(q\) 次操作,每次操作给你两个数 \(x,y\),你可以交换 \(a_x,a_y\),或者什么都不做. 问你所有 \(2^ ...

  4. Python基础7:字符串方法

    1 * 重复输出字符串 print('helo '*4) 2 [],[:] 通过索引获取字符串中的字符,这里和列表中的切片操作是相同的,具体内容见列表 print('hello word'[2:]) ...

  5. 在maven pom.xml中加载不同的properties ,如localhost 和 dev master等jdbc.properties 中的链接不一样

    [参考]:maven pom.xml加载不同properties配置[转] 首先 看看效果: 点开我们项目中的Maven projects 后,会发现右侧 我们profile有个可勾选选项.默认勾选l ...

  6. js实现一个长页面中的图片懒加载即滚动到其位置才加载

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. Python与微信——itchat包

    目录 itchat itchat 一安装itchat pip install itchat pip install echarts-python 二登陆并向文件传输助手发消息 import itcha ...

  8. 【linux】常用命令集锦&持续更新...

    滴:转载引用请注明哦[握爪]:https://www.cnblogs.com/zyrb/p/9709013.html  对深度学习训练及日常work中的常用linux命令进行整理. [一]screen ...

  9. 001 UI介绍

    UI全称:User Interface,即用户界面 UI的职责:负责人机之间的交互,它需要将关键信息,操作逻辑等展示给用户 UI在游戏中承担的职责: 1.游戏美术风格的重要组成部分 2.承担着重要的美 ...

  10. Python高级笔记(一) -- GIL (全局解释器锁)

    1. GIL概念 (cpython历史遗留问题) 概念? 对Python多线程的影响? 编写一个多线程抓取网页的程序? 阐述多线程抓取程序是否比单线程性能有提升, 并解释原因. GIL:全局解释器锁, ...