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. Python——pyqt5——智能提示(lineEdit/conmbobox)

    一.文本框智能补全 completer = QtWidgets.QCompleter(data) completer.setCompletionMode(QtWidgets.QCompleter.Po ...

  2. JavaScript继承总结

    1.创建对象 1.字面量对象 2.构造函数 3.Object.create //1.字面量 var obj={ name: '字面量', show: function(){ console.log(t ...

  3. Educational Codeforces Round 62 Div. 2

    突然发现上一场edu忘记写了( A:签到. #include<iostream> #include<cstdio> #include<cmath> #include ...

  4. macTypeError: slice indices must be integers or None or have an index method

    一般是由于Numpy的版本太高了(1.12对此进行了调整),有的时候传入numpy array里面的索引可能是浮点数,这个时候最好检查一下索引强制转换为int类型 或者安装低版本的numpy sudo ...

  5. 洛谷P4643 [国家集训队]阿狸和桃子的游戏(思维题+贪心)

    思维题,好题 把每条边的边权平分到这条边的两个顶点上,之后就是个sb贪心了 正确性证明: 如果一条边的两个顶点被一个人选了,一整条边的贡献就凑齐了 如果分别被两个人选了,一作差就抵消了,相当于谁都没有 ...

  6. Sql知识点总结

    一.数据库对象:表(table) 视图(view) 序列(sequence) 索引(index) 同义词(synonym) 视图(view) : 存储起来的 select 语句 create view ...

  7. requests爆破+简单数字验证码

    验证码用正则获取 然后提交:访问方式为get:由于有验证码 要用session:注意:获取验证码的时候所打开的网页要用当前session(即要get的) 不能另外打开(如urllib中的打开网页)网页 ...

  8. Mac 装机必备软件推荐

    所谓Mac 装机必备软件,就是用 Mac OS X 几乎都要安装的软件,无论你是开发者.设计师还是摄影师,如果你是刚开始用 Mac,那么推荐看看以下内容,对你非常有帮助. 一.输入法 Mac 自带的中 ...

  9. 如何解决Java警告信息:"objc[31336]: Class JavaLaunchHelper is implemented in both places ..."

    在macOS High Sierra Version 10.13.6下使用Intellij在Java 8上执行Java程序,console中会打印如下警告信息: objc[31336]: Class ...

  10. day21双下方法,源码相关,异常处理

    #!/usr/bin/env python# -*- coding:utf-8 -*- # 1.列举你了解的面向对象中的特殊成员,并为每个写代码示例.'''__init__初始化:class A: d ...