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. mysql 小结

    Mariadb proxy maxscale01.test.com maxscale02.test.com Mariadb Galera Cluster db01.test.com db02.test ...

  2. P1238 走迷宫

    原题链接 https://www.luogu.org/problemnew/show/P1238 为了巩固一下刚学习的广搜,练一下迷宫类型的题 不过这道题我用的深搜..... 看问题,我们就知道这道题 ...

  3. 使用Python操作MongoDB

    MongoDB简介(摘自:http://www.runoob.com/mongodb/mongodb-intro.html) MongoDB 由C++语言编写,是一个基于分布式文件存储的开源数据库系统 ...

  4. PAT 甲级真题题解(1-62)

    准备每天刷两题PAT真题.(一句话题解) 1001 A+B Format  模拟输出,注意格式 #include <cstdio> #include <cstring> #in ...

  5. TJOI2018Party

    题目描述 小豆参加了\(NOI\)的游园会,会场上每完成一个项目就会获得一个奖章,奖章 只会是\(N\), \(O\), \(I\)的字样.在会场上他收集到了\(K\)个奖章组成的串. 兑奖规则是奖章 ...

  6. 哈尔滨工程大学第十四届程序设计竞赛(同步赛)F 小帆帆走迷宫(dp)

    题目描述 小帆帆被困在一个 NxN 的方格矩阵迷宫,每个格子中都有一个整数 A[i][j].小帆帆从迷宫起点(左上角)格子 A[1][1]开始走,每一步可以向右或向下移动,目标是移动到迷宫的出口右下角 ...

  7. 你不得不用的MAC软件开发工具软件,个个万里挑一

    作为软件行业,尤其是程序员,Mac上都不得不安装一些必备的MAC软件开发工具软件,下面给大家分享一些必装的MAC软件开发工具软件,以备日后之需,有备无患. 其中,包含各种语言的主流 IDE.开发辅助. ...

  8. 详解散列hashCode在HashMap中的使用原理

    1散列的价值在于它的速度:散列使得查询变快,它将键key保存在某处,而我们知道存储一组数组最快的数据结构是数组,所以用它来表示键的信息(注意,数组保存的是键的信息,不是键本身),由于数组是固定的,当我 ...

  9. Ansible-基础

    Ansible架构 Inventory   主机清单,可以对主机分组 ansible-hoc   ansible的命令,适用临时场景 ansible-playbook   ansible是一个场景的集 ...

  10. Gephi——使用map of countries和Geo Layout实现包含地理坐标的数据可视化

    前言: Gephi(以下内容基于0.9.2)比较擅长用来处理社会网络分析,其自身以及插件对地理数据的支持非常不足.主要有以下几点: 1.map of countries这个插件可以在gephi底图上以 ...