来自博客: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中的控件;

[Android]对BaseAdapter中ViewHolder编写简化(转)的更多相关文章

  1. [Android]对BaseAdapter中ViewHolder编写简化

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/3642849.html 在Android项目中,经常都会用到Li ...

  2. android开发 BaseAdapter中getView()里的3个参数是什么意思

    BaseAdapter适配器里有个getView()需要重写public View getView(int position,View converView,ViewGroup parent){ // ...

  3. 43.Android之ListView中BaseAdapter学习

    实际开发中个人觉得用的比较多是BaseAdapter,尽管使用起来比其他适配器有些麻烦,但是使用它却能实现很多自己喜欢的列表布局,比如ListView.GridView.Gallery.Spinner ...

  4. Android应用项目中BaseAdapter、SimpleAdapter和ArrayAdapter中的三种适配器

    一.写在前面: 本次我们来讲解一下Android应用中三个适配器:BaseAdapter.SimpleAdapter和ArrayAdapter.其中常见的是BaseAdapter,也是个人推荐使用的适 ...

  5. android代码优化----ListView中自定义adapter的封装(ListView的模板写法)

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  6. Android笔记——BaseAdapter的使用

    Android中的适配器(Adapter)是数据与视图(View)之间的桥梁,用于对要显示的数据进行处理,并通过绑定到组件进行数据的显示. BaseAdapter是Android应用程序中经常用到的基 ...

  7. ListView优化-通用ViewHolder编写备份

    ViewHolder.java package cn.edu.bzu.util; import android.content.Context; import android.util.SparseA ...

  8. Android 实现ListView中Item被单击后背景色保持高亮

    今天为了解决一个需求,就是我有一个slidingDrawer,里面是一个ListView.然后,单击其中的Item,默认只是显示一个橙色背景后就恢复了.客户便有着个需求,需要单击这个Item的背景高亮 ...

  9. Android之BaseAdapter的优雅实现

    在android的开发过程中,我们不可避免的要使用ListView来展示我们的Activity上面的内容.你可以使用很多种方式来实现这一功能,但是如何优雅快速的来实现呢?这就是我要写的了,既为了大家共 ...

随机推荐

  1. bzoj千题计划267:bzoj3129: [Sdoi2013]方程

    http://www.lydsy.com/JudgeOnline/problem.php?id=3129 如果没有Ai的限制,就是隔板法,C(m-1,n-1) >=Ai 的限制:m减去Ai &l ...

  2. bzoj千题计划221:bzoj1500: [NOI2005]维修数列(fhq treap)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1500 1.覆盖标记用INF表示无覆盖标记,要求可能用0覆盖 2.代表空节点的0号节点和首尾的两个虚拟 ...

  3. Nginx配置项优化(转载)

    (1)nginx运行工作进程个数,一般设置cpu的核心或者核心数x2 如果不了解cpu的核数,可以top命令之后按1看出来,也可以查看/proc/cpuinfo文件 grep ^processor / ...

  4. javascript设计模式开篇:Javascript 接口的实现

    javascript语言不像java. c#. c++等面向对象语言那样有完备的接口支持,在javascript中,接口的实现有三种方式,分别为注释描述.属性检查.鸭式变形.注释描述实现起来最为简单, ...

  5. 20155233 2016-2017-2 《Java程序设计》第5周学习总结

    20155233 2016-2017-2 <Java程序设计>第5周学习总结 学习目标 理解异常架构 牚握try...catch...finally处理异常的方法 会用throw,thro ...

  6. iOS 中nil,Nil,NULL,NSNull的区别

    类与对象的概念 类是对同一类事物高度的抽象,类中定义了这一类对象所应具有的静态属性(属性)和动态属性(方法). 对象是类的一个实例,是一个具体的事物. 类与对象是抽象与具体的关系. 类其实就是一种数据 ...

  7. UVALive 7456 Least Crucial Node

    题目链接 题意: 给定一个无向图,一个汇集点,问哪一个点是最关键的,如果有多个关键点,输出序号最小的那个. 因为数据量比较小,所以暴力搜索就行,每去掉一个点,寻找和汇集点相连的还剩几个点,以此确定哪个 ...

  8. js深复制

    一般来讲深复制主要是为了复制js对象中的引用类型,引用类型在普通的赋值操作下相当于是引用,修改复制对象也会影响原对象,简单的方法的话可以使用JSON.parse(JSON.stringify(obj) ...

  9. 第10月第6天 lua 闭包

    1. static int mytest(lua_State *L) { //获取上值 )); printf("%d\n", upv); upv += ; lua_pushinte ...

  10. python垃圾回收之分代回收

    可参考vamei的博客和https://www.jianshu.com/p/1e375fb40506