博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Android]对BaseAdapter中ViewHolder编写简化
阅读量:6940 次
发布时间:2019-06-27

本文共 5300 字,大约阅读时间需要 17 分钟。

以下内容为原创,欢迎转载,转载请注明

来自天天博客:

 

在Android项目中,经常都会用到ListView这个控件,而相应的Adapter中getView()方法的编写有一个标准的形式,如下:

1 @Override 2     public View getView(int position, View convertView, ViewGroup parent) { 3         ViewHolder holder; 4         if(null == convertView){ 5             holder = new ViewHolder(); 6             LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 7             convertView = mInflater.inflate(R.layout.item, null); 8             holder.btn = (Button) convertView.findViewById(R.id.btn); 9             holder.tv = (TextView) convertView.findViewById(R.id.tv);10             holder.iv = (TextView) convertView.findViewById(R.id.iv);11 12             convertView.setTag(holder);13         }else{14             holder = (ViewHolder) convertView.getTag();15         }16         final HashMap
map = list.get(position);17 18 holder.iv.setImageResource(Integer.valueOf(map.get("iv").toString()));19 holder.tv.setText(map.get("tv").toString());20 21 holder.btn.setOnClickListener(new View.OnClickListener() {22 @Override23 public void onClick(View v) {24 Toast.makeText(context, map.get("btn").toString(), Toast.LENGTH_SHORT).show();25 }26 });27 28 return convertView;29 }30 31 class ViewHolder{32 Button btn;33 ImageView iv;34 TextView tv;35 36 }

以下是碎碎念(想直接看代码的,就跳过这段吧-_-!):

也就是说每次编写Adapter都需要编写class ViewHolder...、if(null == convertView){...等等。这些代码跟业务逻辑关系不大,没有必要每次都写重复代码,

所以,显然有简化代码的余地。

既然我们的需求是不需要重复编写ViewHolder等内部类,那就把它移到父类吧。

但是ViewHolder中在实际项目中有不同的View,那就用list存放起来吧,但是放在list中的话,怎么取出来?用index?显然不是好的方法,不是有Resource Id这玩意,通过这个取不就好了么?所以以Resource Id为key放在Map中比较合适,但是既然以int(Resource Id)为key,那自然而然想到使用SparseArray了。

然后再把if(null == converView)...这些代码统统移到父类中。

所以ABaseAdapter诞生了,代码如下:

1 /** 2  * 实现对BaseAdapter中ViewHolder相关的简化 3  * Created with IntelliJ IDEA. 4  * Author: wangjie  email:tiantian.china.2@gmail.com 5  * Date: 14-4-2 6  * Time: 下午5:54 7  */ 8 public abstract class ABaseAdapter extends BaseAdapter{ 9     Context context;10 11     protected ABaseAdapter(Context context) {12         this.context = context;13     }14 15     protected ABaseAdapter() {16     }17 18     /**19      * 各个控件的缓存20      */21     public class ViewHolder{22         public SparseArray
views = new SparseArray
();23 24 /**25 * 指定resId和类型即可获取到相应的view26 * @param convertView27 * @param resId28 * @param
29 * @return30 */31 public
T obtainView(View convertView, int resId){32 View v = views.get(resId);33 if(null == v){34 v = convertView.findViewById(resId);35 views.put(resId, v);36 }37 return (T)v;38 }39 40 }41 42 /**43 * 改方法需要子类实现,需要返回item布局的resource id44 * @return45 */46 public abstract int itemLayoutRes();47 48 @Override49 public View getView(int position, View convertView, ViewGroup parent) {50 ViewHolder holder;51 if(null == convertView){52 holder = new ViewHolder();53 convertView = LayoutInflater.from(context).inflate(itemLayoutRes(), null);54 convertView.setTag(holder);55 }else{56 holder = (ViewHolder) convertView.getTag();57 }58 return getView(position, convertView, parent, holder);59 }60 61 /**62 * 使用该getView方法替换原来的getView方法,需要子类实现63 * @param position64 * @param convertView65 * @param parent66 * @param holder67 * @return68 */69 public abstract View getView(int position, View convertView, ViewGroup parent, ViewHolder holder);70 71 }

如上代码:增加了一个itemLayoutRes()的抽象方法,该抽象方法提供给子类实现,返回item布局的resource id,为后面的getView方法提供调用。

可以看到上述代码中,在系统的getView方法中,进行我们以前在BaseAdapter实现类中所做的事(初始化converView,并绑定ViewHolder作为tag),然后抛弃了系统提供的getView方法,直接去调用自己写的getView抽象方法,这个getView方法是提供给子类去实现的,作用跟系统的getView一样,但是这个getView方法中携带了一个ViewHolder对象,子类可以通过这个对象进行获取item中的控件。

具体使用方式如下,比如创建了MyAdapter并继承了ABaseAdapter:

注意,在构造方法中需要调用父类的构造方法:

1 public MyAdapter(Context context, List
> list) {2 super(context);3 this.list = list;4 }

即,以上的“super(context);”必须调用。

接着实现itemLayoutRes()方法,返回item的布局:

1 @Override2 public int itemLayoutRes() {3     return R.layout.item;4 }

 

getView方法中的实现如下:

1 @Override 2 public View getView(int position, View convertView, ViewGroup parent, ViewHolder holder) { 3     final HashMap
map = list.get(position); 4 5 Button btn = holder.obtainView(convertView, R.id.item_btn); 6 ImageView iv = holder.obtainView(convertView, R.id.item_iv); 7 TextView tv = holder.obtainView(convertView, R.id.item_tv); 8 9 btn.setOnClickListener(new View.OnClickListener() {10 @Override11 public void onClick(View v) {12 Toast.makeText(context, map.get("btn").toString(), Toast.LENGTH_SHORT).show();13 }14 });15 16 iv.setImageResource(Integer.valueOf(map.get("iv").toString()));17 tv.setText(map.get("tv").toString());18 19 return convertView;20 }

如上代码:调用holder.obtainView方法既可获取item中的控件;

 

 

你可能感兴趣的文章
简历上的项目经历怎么写 ?这 3 条原则不可忽视 !
查看>>
Python:鲜为人知的功能特性(下)
查看>>
正则表达式
查看>>
基于python flask编写测试平台系列之·(1)当前项目展示
查看>>
[译] 玩转 JavaScript 面试:何为 Promise ?
查看>>
java B2B2C Springcloud电子商务平台源码 -Feign之源码解析
查看>>
jQuery源码解析之addClass(),removeClass(),toggleClass()和hasClass()
查看>>
正则的回溯引用
查看>>
The Next Step for Machine Learning 机器学习落地需攻破的9个难题
查看>>
js捕获错误信息
查看>>
有道智云OCR图片识别文字+返回数据处理技巧(实现语言-按键精灵脚本请求识别+java服务端处理数据)...
查看>>
Integer和int的关系
查看>>
Java面试被问框架源码看过吗?70道SSM面试题及学习笔记值得收藏!
查看>>
Summit系统架构概览
查看>>
JS-数据类型-数组Array
查看>>
小米平板2简单卡刷开发版开启root权限的步骤
查看>>
阿里云前端周刊 - 第 11 期
查看>>
Java HttpRequest 详解
查看>>
iOS开发之定位
查看>>
探究行内元素和块级元素
查看>>