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

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

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

 @Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(null == convertView){
holder = new ViewHolder();
LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.item, null);
holder.btn = (Button) convertView.findViewById(R.id.btn);
holder.tv = (TextView) convertView.findViewById(R.id.tv);
holder.iv = (TextView) convertView.findViewById(R.id.iv); convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
final HashMap<String, Object> map = list.get(position); holder.iv.setImageResource(Integer.valueOf(map.get("iv").toString()));
holder.tv.setText(map.get("tv").toString()); holder.btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, map.get("btn").toString(), Toast.LENGTH_SHORT).show();
}
}); return convertView;
} class ViewHolder{
Button btn;
ImageView iv;
TextView tv; }

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

也就是说每次编写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诞生了,代码如下:

 /**
* 实现对BaseAdapter中ViewHolder相关的简化
* Created with IntelliJ IDEA.
* Author: wangjie email:tiantian.china.2@gmail.com
* Date: 14-4-2
* Time: 下午5:54
*/
public abstract class ABaseAdapter extends BaseAdapter{
Context context; protected ABaseAdapter(Context context) {
this.context = context;
} protected ABaseAdapter() {
} /**
* 各个控件的缓存
*/
public class ViewHolder{
public SparseArray<View> views = new SparseArray<View>(); /**
* 指定resId和类型即可获取到相应的view
* @param convertView
* @param resId
* @param <T>
* @return
*/
public <T extends View> T obtainView(View convertView, int resId){
View v = views.get(resId);
if(null == v){
v = convertView.findViewById(resId);
views.put(resId, v);
}
return (T)v;
} } /**
* 改方法需要子类实现,需要返回item布局的resource id
* @return
*/
public abstract int itemLayoutRes(); @Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(null == convertView){
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(itemLayoutRes(), null);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
return getView(position, convertView, parent, holder);
} /**
* 使用该getView方法替换原来的getView方法,需要子类实现
* @param position
* @param convertView
* @param parent
* @param holder
* @return
*/
public abstract View getView(int position, View convertView, ViewGroup parent, ViewHolder holder); }

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

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

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

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

 public MyAdapter(Context context, List<HashMap<String, Object>> list) {
super(context);
this.list = list;
}

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

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

 @Override
public int itemLayoutRes() {
return R.layout.item;
}

getView方法中的实现如下:

 @Override
public View getView(int position, View convertView, ViewGroup parent, ViewHolder holder) {
final HashMap<String, Object> map = list.get(position); Button btn = holder.obtainView(convertView, R.id.item_btn);
ImageView iv = holder.obtainView(convertView, R.id.item_iv);
TextView tv = holder.obtainView(convertView, R.id.item_tv); btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, map.get("btn").toString(), Toast.LENGTH_SHORT).show();
}
}); iv.setImageResource(Integer.valueOf(map.get("iv").toString()));
tv.setText(map.get("tv").toString()); return convertView;
}

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

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

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

    来自博客:http://www.cnblogs.com/tiantianbyconan/p/3642849.html 在Android项目中,经常都会用到ListView这个控件,而相应的Adapte ...

  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. iOS_屏幕截图

    github地址: https://github.com/mancongiOS/UIImage.git UIImage的category UIView+ImageScreenShot.h #impor ...

  2. 《HelloGitHub月刊》第04期(秋招临近,本期加入了面试相关的项目)

    兴趣是最好的老师,而<HelloGitHub> 就是帮你找到兴趣! 因为我比较熟悉python语言,所以月刊中python语言的项目居多,个人能力有限,其他语言涉及甚少,欢迎各路人士加入, ...

  3. SQL Server 2014新特性——基数评估(白皮书阅读笔记)

    基数评估 目录 基数评估 说明 基数评估准确的重要性 模型假设 启用新的基数评估 验证基数评估的版本 在迁移到新的基数评估前要测试 校验基数评估 偏差问题 需要手动处理的变化 避免因为新的CE造成性能 ...

  4. github代码管理工具的使用方法

    一.创建一个存储库 1.点击页面右上方你的用户名右边的+标志,然后点击下拉列表中的"new repository"选项,一般填写项目名称和选择public 和选择初始化有READM ...

  5. 简单设置,解决使用webpack前后端跨域发送cookie的问题

    最近用vue来做项目,用webpack来做前端自动化构建.webpack-dev-server会在本地搭建一个服务器,在和后端调试的时候,就会涉及到跨域的问题. 刚开始时,没有用vue-cli来构建项 ...

  6. 总结消息队列RabbitMQ的基本用法

    一.RabbitMQ是什么? AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计.消息中间件主要用于组 ...

  7. 从设计到开发,硅谷技术专家教你做“声控”APP

    编者:本文为携程机票研发部技术专家祁一鸣在携程技术微分享中的分享内容,关注携程技术中心微信公号ctriptech,获知更多一手干货. [携程技术微分享]是携程技术中心推出的线上公开分享课程,每月1-2 ...

  8. jQuery Pagination分页插件的使用

    一.引用CSS和JS: <link href="/Content/Plugins/jQuery.Pagination_v2.2/pagination.css" rel=&qu ...

  9. Socket开发框架之消息的回调处理

    在一般的Socket应用里面,很多时候数据的发送和接收是分开处理的,也就是我们发送一个消息,不知道这个请求消息什么时候得到应答消息,而且收到对应的应答消息的时候,如果操作界面的内容,也是需要特别处理的 ...

  10. SignalR入门之基本介绍

    SignalR是微软对web开发技术的扩充,它是一种框架,方便用来创建实时应用程序. 有一些即时消息系统,实时协作工作集,多人在线游戏,信息广播服务等其他需要在信息产生时就能进行发送的任务系统. 对于 ...