原文链接:http://stackvoid.com/using-adapter-in-efficiency-way/

在使用Listview或GridView的时候,往往须要自己定义数据适配器。一般都要覆写getView(),在该方法中有一个convertView參数。该參数就是用来载入数据时的View。

刚開始学习的人简单但低效的方式

 1 public View getView(int position, View convertView, ViewGroup parent) {
2
3 View item= inflater.inflate(R.layout.good_list_item, null, false);
4
5 ImageView img = (ImageView) item.findViewById(R.id.img);
6 TextView price = (TextView) item.findViewById(R.id.price);
7 img.setImageResource(R.drawable.ic_launcher);
8 price.setText("$"+list.get(position).price);
9
10 return item;
11 }

每次载入view,都要又一次建立非常多view对象,假设listview中有一万条数据,而且每条view中的数据都比較复杂。这样的载入方式就歇菜了。

利用convertView

利用convertView来又一次回收View,效率有了本质提高。

View的每次创建是比較耗时的。因此对于getview方法传入的convertView应充分利用 != null的推断 。

 1 public View getView(int position, View convertView, ViewGroup parent) {
2
3 if(convertView==null){
4 convertView = inflater.inflate(R.layout.good_list_item, null, false);
5 }
6 TextView tv_price = (TextView)convertView.findViewById(R.id.price)
7 ImageView iv = (ImageView)convertView.findViewByID(R.id.img);
8
9 return convertView;
10 }

使用ViewHolder

ViewHolder将须要缓存的view封装好。convertView的setTag才是将这些缓存起来供下次调用。

当你的listview里布局多样化的时候 viewholder的作用体现明显,效率再一次提高。 View的findViewById()方法也是比較耗时的,因此须要考虑仅仅调用一次,之后就用View.getTag()方法来获得ViewHolder对象。

 1 class ViewHolder{
2 ImageView img;
3 TextView price;
4 }
5 public View getView(int position, View convertView, ViewGroup parent) {
6 ViewHolder holder = new ViewHolder();
7 if(convertView==null){
8 convertView = inflater.inflate(R.layout.good_list_item, null, false);
9 holder.img = (ImageView) convertView.findViewById(R.id.img);
10 holder.price = (TextView) convertView.findViewById(R.id.price);
11 convertView.setTag(holder);
12 }else{
13 holder = (ViewHolder) convertView.getTag();
14 }
15 //设置holder
16 holder.img.setImageResource(R.drawable.ic_launcher);
17 holder.price.setText("$"+list.get(position).price);
18
19 return convertView;
20 }

优雅的使用ViewHolder

使用ViewHolder时。每次一遍一遍的findViewById。一遍一遍在ViewHolder里面加入View的定义。view一多。是不是感觉烦爆了,base-adapter-helper这个类库似乎完美的攻克了这个问题。

其设计思想是使用 SparseArray来存储view的引用,取代了原本的ViewHolder,不用声明一大堆View。简洁明了。

我也自己动手写了一个简单版的ViewHolder。

 1 public class ViewHolder{
2
3 private final SparseArray<View> views;
4 private View convertView;
5
6 private ViewHolder(View convertView){
7 this.views = new SparseArray<View>();
8 this.convertView = convertView;
9 convertView.setTag(this);
10 }
11
12 public static ViewHolder get(View convertView){
13 if (convertView == null) {
14 return new ViewHolder(convertView);
15 }
16 ViewHolder existedHolder = (ViewHolder) convertView.getTag();
17 return existedHolder;
18 }
19
20 public <T extends View> T getView(int viewId) {
21 View view = views.get(viewId);
22 if (view == null) {
23 view = convertView.findViewById(viewId);
24 views.put(viewId, view);
25 }
26 return (T) view;
27 }
28 }

使用的话就超级简单和简洁了:

 1 public View getView(int position, View convertView, ViewGroup parent) {
2 if (convertView == null) {
3 convertView = LayoutInflater.from(context)
4 .inflate(R.layout.good_list_item, null, false);
5 }
6
7 ViewHolder mViewHolder = ViewHolder.get(convertView);
8 TextView price = mViewHolder.getView(R.id.price);
9 //...其它getView
10
11 return convertView;
12 }

类似这样的情况不要使用ViewHolder

很多其它内容请參照我的个人网站: http://stackvoid.com/

Android数据适配器(Adapter)优化:使用高效的ViewHolder的更多相关文章

  1. Android数据适配器Adapter简介

    1.简介 Adapter是用来帮助填充数据的中间桥梁,简单点说就是:将各种数据以合适的形式显示到view上,在常见的View(List View,Grid View)等地方都需要用到Adapter! ...

  2. Android 数据适配器

    把复杂的数据(数组.链表.数据库.集合等)填充到指定的视图界面上.   arrayAdapter(数组适配器):      用于绑定一些格式单一的数据,数据源:数据或者集合.   private Li ...

  3. 代码优化>>>Android ListView适配器三级优化详解

    转载本专栏每一篇博客请注明转载出处地址,尊重原创.此博客转载链接地址:点击打开链接  http://blog.csdn.net/qq_32059827/article/details/52718489 ...

  4. Android之ListView性能优化——使用ConvertView和ViewHolder

    使用ConvertView和ViewHolder的优化是针对ListView的Adapter(BaseAdapter)的.这种优化的优点如下: 1)重用了ConveertView,在很大程度上减少了内 ...

  5. Android之ListView性能优化——一行代码绑定数据——万能适配器

    如下图,加入现在有一个这样的需求图,你会怎么做?作为一个初学者,之前我都是直接用SimpleAdapter结合一个Item的布局来实现的,感觉这样实现起来很方便(基本上一行代码就可以实现),而且也没有 ...

  6. Android学习之Adapter(数据适配器)

    1.定义     数据适配器是AdapterView视图(如ListView - 列表视图控件.Gallery - 缩略图浏览器控件.GridView - 网格控件.Spinner - 下拉列表控件. ...

  7. Android必学之数据适配器BaseAdapter

    什么是数据适配器? 下图展示了数据源.适配器.ListView等数据展示控件之间的关系.我们知道,数据源是各种各样的,而ListView所展示数据的格式则是有一定的要求的.数据适配器正是建立了数据源与 ...

  8. 浅析android适配器adapter中的那些坑

    做项目中遇到的,折磨了我将近两天,今天把经验分享出来.让大家以后少走点弯路,好了.简单来说一下什么是android的适配器,怎样定义.怎样添加适配器的重用性.怎样去减少程序的耦合性 适配器顾名思义是用 ...

  9. ListView和Adapter数据适配器的简单介绍

    ListView 显示大量相同格式数据 常用属性: listSelector            listView每项在选中.按下等不同状态时的Drawable divider            ...

随机推荐

  1. FIREDAC记录SQL日志

    FIREDAC记录SQL日志 跟踪SQL日志可以方便开发的时候的程序调试.SQL日志记录会耗费服务费资源,正式部署中间件的时候,建议关闭SQL日志记录. FIREDAC通过使用TFDMoniFlatF ...

  2. Android源码和内核源码的下载,编译和执行

    笔者依据罗升阳老师的<Android 系统源码情景分析>一书,尝试下载,编译和执行Android源码和内核源码.但可能是软件源"被墙"或版本号更新的原因.期间遇到诸多问 ...

  3. 修改kafka broker.id

    kafka.common.InconsistentBrokerIdException: Configured broker.id 1 doesn't match stored broker.id 0 ...

  4. k8s restful API 结构分析

    k8s的api-server组件负责提供restful api访问端点, 并且将数据持久化到etcd server中. 那么k8s是如何组织它的restful api的? 一, namespaced ...

  5. 点击Div,显示其innerHTML

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. badblocks检测磁盘坏道

    1.检测整个盘如/dev/sdb #badblocks -v /dev/sdb > badsectors.txt 2.检测一个分区#badblocks -v /dev/sdb1 > bad ...

  7. <p>在我们的实际软件项目中,管理团队事实上比写代码或者实现一个客户的需求更为的有挑战性。由于编程实际上是和机器打交道,而和机器打交道,仅仅要你符合机器预定的逻辑,</p>

    在我们的实际软件项目中,管理团队事实上比写代码或者实现一个客户的需求更为的有挑战性. 由于编程实际上是和机器打交道.而和机器打交道,仅仅要你符合机器预定的逻辑, 一步步迈向解决这个问题的道路上一点都不 ...

  8. Jeewx 捷微管家操作配置文档(开源版本号)

    1.1.1.  公众帐号管理 (1)捷微是第三方微信公众帐号管理平台,使用本平台前,请自行注冊申请微信公众帐号,操作流程请參照百度经验[怎样注冊微信公众帐号]: http://jingyan.baid ...

  9. C++ 模板详解(一)(转)

    C++模板 模板是C++支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模式,使得类中的某些数据成员或者成员函数的参数.返回值取得任意类型. 模板是一种对类型进行参数化的工具: 通常有 ...

  10. STL学习笔记(string)

    动机 C++标准程序库中的string class使我们可以将string当做一个一般型别.我们可以像对待基本型别那样地复制.赋值和比较string, 再也不必但系内存是否足够.占用的内存实际长度等问 ...