[Android]对BaseAdapter中ViewHolder编写简化

简介: 以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/3642849.html   在Android项目中,经常都会用到ListView这个控件,而相应的Adapter中getView()方法的编写有一个标准的形式...

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

来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/3642849.html

 

在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<String, Object> 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             @Override
23             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<View> views = new SparseArray<View>();
23 
24         /**
25          * 指定resId和类型即可获取到相应的view
26          * @param convertView
27          * @param resId
28          * @param <T>
29          * @return
30          */
31         public <T extends View> 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 id
44      * @return
45      */
46     public abstract int itemLayoutRes();
47 
48     @Override
49     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 position
64      * @param convertView
65      * @param parent
66      * @param holder
67      * @return
68      */
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<HashMap<String, Object>> list) {
2     super(context);
3     this.list = list;
4 }

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

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

1 @Override
2 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<String, Object> 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         @Override
11         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月前
|
存储 Android开发 开发者
Android项目架构设计问题之定义RecyclerView的ViewHolder如何解决
Android项目架构设计问题之定义RecyclerView的ViewHolder如何解决
41 0
|
Android开发 容器 缓存
基于“ViewHolder”技术提升Android ListView中Item View加载效率
对于提升Android中频繁使用的ListView子Item View的加载效率,基于两点基本考虑: 1,Android的View的创建比较消耗资源; 2,findViewById()也不是最快的。
699 0
|
程序员 Android开发
android studio 程序员有福了—从layout自动生成viewholder类
狂点这里下载 超级牛逼的插件啊,比那些使用SparseArray的强太多了! 在android studio 1.0上测试,没有问题。 不说了直接说功能 Android Toolbox Plugin for IDEA.
1040 0
|
8天前
|
编解码 Java Android开发
通义灵码:在安卓开发中提升工作效率的真实应用案例
本文介绍了通义灵码在安卓开发中的应用。作为一名97年的聋人开发者,我在2024年Google Gemma竞赛中获得了冠军,拿下了很多项目竞赛奖励,通义灵码成为我的得力助手。文章详细展示了如何安装通义灵码插件,并通过多个实例说明其在适配国际语言、多种分辨率、业务逻辑开发和编程语言转换等方面的应用,显著提高了开发效率和准确性。
|
7天前
|
Android开发 开发者 UED
安卓开发中自定义View的实现与性能优化
【10月更文挑战第28天】在安卓开发领域,自定义View是提升应用界面独特性和用户体验的重要手段。本文将深入探讨如何高效地创建和管理自定义View,以及如何通过代码和性能调优来确保流畅的交互体验。我们将一起学习自定义View的生命周期、绘图基础和事件处理,进而探索内存和布局优化技巧,最终实现既美观又高效的安卓界面。
19 5
|
5天前
|
JSON Java Android开发
探索安卓开发之旅:打造你的第一个天气应用
【10月更文挑战第30天】在这个数字时代,掌握移动应用开发技能无疑是进入IT行业的敲门砖。本文将引导你开启安卓开发的奇妙之旅,通过构建一个简易的天气应用来实践你的编程技能。无论你是初学者还是有一定经验的开发者,这篇文章都将成为你宝贵的学习资源。我们将一步步地深入到安卓开发的世界中,从搭建开发环境到实现核心功能,每个环节都充满了发现和创造的乐趣。让我们开始吧,一起在代码的海洋中航行!
|
6天前
|
缓存 数据库 Android开发
安卓开发中的性能优化技巧
【10月更文挑战第29天】在移动应用的海洋中,性能是船只能否破浪前行的关键。本文将深入探讨安卓开发中的性能优化策略,从代码层面到系统层面,揭示如何让应用运行得更快、更流畅。我们将以实际案例和最佳实践为灯塔,引领开发者避开性能瓶颈的暗礁。
22 3
|
9天前
|
存储 IDE 开发工具
探索Android开发之旅:从新手到专家
【10月更文挑战第26天】在这篇文章中,我们将一起踏上一段激动人心的旅程,探索如何在Android平台上从零开始,最终成为一名熟练的开发者。通过简单易懂的语言和实际代码示例,本文将引导你了解Android开发的基础知识、关键概念以及如何实现一个基本的应用程序。无论你是编程新手还是希望扩展你的技术栈,这篇文章都将为你提供价值和启发。让我们开始吧!