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

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

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

初学者简单但低效的方式

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

每次加载view,都要重新建立很多view对象,如果某条listview中有一万条数据,这种加载方式就歇菜了。

利用convertView

利用Android的Recycler机制,利用convertView来重新回收View,效率有了本质提高。View的每次创建是比较耗时的,因此对于getview方法传入的convertView应充分利用 != null的判断 。

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

使用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. return convertView;
  19. }

优雅的使用ViewHolder

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

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

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

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

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

  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. ViewHolder mViewHolder = ViewHolder.get(convertView);
  7. TextView price = mViewHolder.getView(R.id.price);
  8. //...其他getView
  9. return convertView;
  10. }
时间: 2024-11-10 14:01:11

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

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);

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

数据适配器: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开发中常用的ListView列表的优化方式ViewHolder

在Android开发中难免会遇到大量的数据加载到ListView中进行显示, 然后其中最重要的数据传递桥梁Adapter适配器是常用的,随着市场的需 求变化ListView'条目中的内容是越来越多这就需要程序员来自定义适配器, 而关键的就是适配器的优化问题,适配器没有优化好往往就会造成OOM (内存溢出)或者是滑动卡顿之类的问题,接下来我就给大家介绍一种常 用的Adapter优化方法 1 /** 2 * list View的适配器 3 */ 4 class Adapter extends Bas

Android必学之数据适配器BaseAdapter

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

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

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