Android数据适配器(Adapter)优化:使用高效的ViewHolder

在使用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

时间: 2024-08-29 21:13:12

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

Android数据适配器(Adapter)优化:高效ViewHolder

在使用Listview或GridView的时候,往往需要自定义数据适配器,一般都要覆写getView(),在该方法中有一个convertView参数,该参数就是用来加载数据时的View. 在使用Listview或GridView的时候,往往需要自定义数据适配器,一般都要覆写getView(),在该方法中有一个convertView参数,该参数就是用来加载数据时的View. 初学者简单但低效的方式 public View getView(int position, View convertView

Android 数据适配器

把复杂的数据(数组.链表.数据库.集合等)填充到指定的视图界面上. arrayAdapter(数组适配器): 用于绑定一些格式单一的数据,数据源:数据或者集合. private ListView listView ; private ArrayAdapter<String> adapter ; private SimpleAdapter simpleAdapter; @Override protected void onCreate(Bundle savedInstanceState) { s

Android中适配器Adapter的使用

安卓中最常使用的适配器Adapter有三种:1.ArrayAdapter 2.SimpleAdapter 3.BaseAdpter,此处我们用代码结合图文的方式理解.     首先需要在起始布局activity_main.xml文件中设置三个Button按钮,并分别设置点击事件,并与MainActivity相结合     一:ArrayAdapter:简单易用的Adapter,通常用于将数组或者List集合的多个值包装成多个列表项. 1.声明arrayadapter的第一步:创建activity

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

使用ConvertView和ViewHolder的优化是针对ListView的Adapter(BaseAdapter)的.这种优化的优点如下: 1)重用了ConveertView,在很大程度上减少了内存的消耗.通过判断ConvertView是否为NULL,如果是NULL那么就需要生成一个新的View出来(通过LayoutInflater生成),绑定数据后显示给用户:如果ConvertView不是NULL,则我们需要做的就只有绑定数据并呈现给用户. 2)由于ListView中的Item往往都是只有

数据适配器:Adapter

数据适配器(Adapter): Adapter的功能是:为GridView.ListView等界面控件与数据之间搭建桥梁,当列表里的每一项显示到页面时,都会调用Adapter.getView(),返回一个View. 实现ListAdapter的Adapter分三类(1.BaseAdapter 2.SimpleAdapter 3.SimpleCursorAdapter). 1.BaseAdapter:  是一个实现了既能在ListView(实现了ListAdapter接口)和Spinner(实现了

Android学习笔记(10)——数据适配器ArrayAdapter和SimpleAdapter

上一篇文章我们介绍了关于ListView的基本知识,也说到了一些关于数据适配器Adapter的问题,这里我们继续介绍两种比较常见的数据适配器的类型,ArrayAdapter和SimpleAdapter.这两种适配器各自有各自的特点,适用于不同的情况. ArrayAdapter 这种适配器比较简单,常用于仅仅是文本内容的ListView.没有图标或者比较复杂的布局的情况下,实现方法主要就是去填写构造函数中的参数,ArrayAdapter函数的构造方法有好几种,这里介绍了最主要的两种情况,具体可以看

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

1.定义     数据适配器是AdapterView视图(如ListView - 列表视图控件.Gallery - 缩略图浏览器控件.GridView - 网格控件.Spinner - 下拉列表控件.AutoCompleteTextView - 自动提示文本框.ExpandableListView - 支持展开/收缩功能的列表控件等)与数据之间的桥梁,用来处理数据并将数据绑定到AdapterView上. 2.作用    数据适配器是连接数据源和视图界面的桥梁. 3.分类     包括ArrayA

Android必学之数据适配器BaseAdapter

.什么是数据适配器? 下图展示了数据源.适配器.ListView等数据展示控件之间的关系.我们知道,数据源是各种各样的,而ListView所展示数据的格式则是有一定的要求的.数据适配器正是建立了数据源与ListView之间的适配关系,将数据源转换为ListView能够显示的数据格式,从而将数据的来源与数据的显示进行解耦,降低程序的耦合性.这也体现了Android的适配器模式的使用.对于ListView.GridView等数据展示控件有多种数据适配器,本文讲解最通用的数据适配器——BaseAdap

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

做项目中遇到的,折磨了我将近两天,今天把经验分享出来.让大家以后少走点弯路,好了.简单来说一下什么是android的适配器,怎样定义.怎样添加适配器的重用性.怎样去减少程序的耦合性 适配器顾名思义是用来做适配的,可是他是怎样做适配的.机制是什么.作用是什么,好,相信写java的都是知道什么是面向对象编程吧,这里用面向对象来解释非常好理解.事实上适配器是把每一个对象放在其空间上然后在andorid页面显示,如今再来理解,对象事实上就是数据的抽象体吧,而页面显示通常是xml也就是视图吧,那么数据以视