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. tomcat server.xml结构

    所有xml文件使用的文件头 <?xml version='1.0' encoding='utf-8'?> 2 <Server port="8005" shutdo ...

  2. Django内存管理的6种方法

    一.django的缓存方式有6种: 1.开发者调试缓存 2.内存缓存 3.文件缓存 4.数据库缓存 5.Memcache缓存(使用python-memecached模块) 6.Memcache缓存(使 ...

  3. [leetcode] 5.Longest Palindromic Substring-2

    想了很多方法 搞轴对称,算对称轴,偶数都高出了一堆0.5在那加加减减,最后发现在移轴之前可能就返回了. class Solution: def longestPalindrome(self, s: s ...

  4. POJ2960 S-Nim 【博弈论】

    Description Arthur and his sister Caroll have been playing a game called Nim for some time now. Nim ...

  5. Ubuntu terminal colors

    Today I run ubuntu docker image on powershell and find the directory color is blue, so I want to cha ...

  6. centos7升级内核至最新

    应用背景: 最近在接触docker,其对内核版本要求较高,就连目前使用的centos7.x默认内核版本为3.10.0-xxx,也是刚好满足其最低要求,故借此机会记录一下升级内核的操作步骤. 测试环境: ...

  7. HTTP与HTTPS(转)

    一.什么是HTTP? 什么是HTTPS?  HTTP:(Hyper Text Transfer Protocol 超文本传输协议) HTTPS:(Hyper Text Transfer Protoco ...

  8. 史上最全PMP备考考点全攻略(上篇-五大过程组,附赠资料)

    一.这可能是一篇史上最全的PMP备考考点全梳理文章 写在前面,这可能是史上最全的PMBOK考点全书考点梳理,由PMP备考自律营呕心沥血整理,内容较长,分为上下篇,绝对值得所有正在备考PMP的学员收藏! ...

  9. mysql函数调用过程

    1.conn = mysql_init(NULL);//初始化  MYSQL *conn; 2.mysql_real_connect(conn, "localhost", &quo ...

  10. Java设计模式--装饰器模式到Java IO 流

    装饰器模式 抽象构件角色:给出一个抽象接口,以规范准备接受附加责任的对象. 具体构件角色:定义准备接受附加责任的对象. 抽象装饰角色:持有一个构件对象的实例,并对应一个与抽象构件接口一致的接口. 具体 ...