设计通用的Adapter
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的更多相关文章
- 解析大型.NET ERP系统 设计通用Microsoft Excel导入功能
做企业管理软件很难避免与Microsoft Excel打交道,常常是软件做好了,客户要求说再做一个Excel导入功能.导入Excel数据的功能的难度不大,从Excel列数据栏位的取值,验证值,再导入到 ...
- 使用java泛型设计通用方法
泛型是Java SE 1.5的新特性, 泛型的本质是参数化类型, 也就是说所操作的数据类型被指定为一个参数. 因此我们可以利用泛型和反射来设计一些通用方法. 现在有2张表, 一张user表和一张stu ...
- 通用访问 - 用“反射”来设计通用的通信协议,以及配套的SDK、工具
1. 效果演示 2. 通信协议 功能介绍 特点 TCP协议 WebApi协议 3. SDK与工具 4. 应用示例 迷你网管 通用GIS 系统管理 5. 设计初衷与演化 1. 效果演示 服务 ...
- RecyclerView高速通用适配Adapter
RecyclerView Adapter 为RecyclerView提供更简单的适配器实现方式,不断更新完好中. Demo视频演示 GitHub地址 博客 使用 BaseViewHolder 的使用 ...
- 通用的Adapter
activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu ...
- 利用JAVA反射机制设计通用的DAO
利用JAVA反射机制设计一个通用的DAO 反射机制 反射机制指的是程序在运行时能够获取自身的信息.在java中,只要给定类的名字, 那么就可以通过反射机制来获得类的所有信息. 反射机制创建类对象 ...
- 为RecyclerView打造通用Adapter
##RecycleView简单介绍 RecyclerView控件和ListView的原理有非常多相似的地方,都是维护少量的View来进行显示大量的数据.只是RecyclerView控件比ListVie ...
- 为RecyclerView打造通用Adapter 让RecyclerView更加好用
原文出处: 张鸿洋 (Granker,@鸿洋_ ) 一.概述 记得好久以前针对ListView类控件写过一篇打造万能的ListView GridView 适配器,如今RecyclerView异军突起, ...
- 痞子衡嵌入式:嵌入式里通用微秒(microseconds)计时函数框架设计与实现
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是嵌入式里通用微秒(microseconds)计时函数框架设计与实现. 在嵌入式软件开发里,计时可以说是非常基础的功能模块了,其应用也非常 ...
随机推荐
- CF51C Three Base Stations
https://codeforces.com/problemset/problem/51/C 题目 The New Vasjuki village is stretched along the mot ...
- MVC autofac 属性注入
Global文件 public class MvcApplication : System.Web.HttpApplication { private static IContainer Contai ...
- SpringBoot之常用注解
在spring boot中,摒弃了spring以往项目中大量繁琐的配置,遵循约定大于配置的原则,通过自身默认配置,极大的降低了项目搭建的复杂度.同样在spring boot中,大量注解的使用,使得代码 ...
- 大白话 Scala 控制抽象
2019-04-14 关键字: Scala.Scala控制抽象.Scala高阶函数 本篇文章系笔者根据当前掌握的知识对 Scala 控制抽象的教材知识总结,不保证文章所述内容的绝对.完全正确性. 在 ...
- Day 1 下午
POINT 1 贪心 每一步都取当前的最优解的思想:一般来说符合直观思路,需要严格的证明:OI中使用多个错误的贪心策略进行加成有时会有良好的效果 例一给定N个农民,第i个农民有Ai单位的牛奶,单价Pi ...
- MySQL数据库开发的三十六条军规
一.核心军规 尽量不在数据库做运算,cpu计算的事务必移至业务层; 控制表.行.列数量([控制单张表的数据量 1年/500W条,超出可做分表],[单库表数据量不超过300张] .[单张表的字段个数不超 ...
- 「ZJOI Day2」游记
Day-1 晚上一直在出自己做的模拟赛的T1,真的快要死掉了. 分类讨论几十种情况. 窝还是找了Bluesky大佬一起来验题,她瞬间就A掉了这一道题目...自闭了.. 诶,我还是太弱了. 之前教练组织 ...
- django rest framework authentication
身份验证 身份验证是将传入请求与一组识别凭证(例如请求的用户或其签名的令牌)相关联的机制.然后,权限和限制策略可以使用这些凭据来确定请求是否应该被允许. REST framework 提供了许多开箱即 ...
- centos下彻底删除mysql的方法
本文记录了CentOS下MySQL的彻底卸载,供大家参考,具体内容如下: 1.查看MySQL是否安装 方式1: [root@localhost usr]# yum list installed mys ...
- js实现点气球小游戏
二话不说直接贴代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...