本文内容:adapter,listview的优化,RecycleBi,google大会推荐优化,

实现ListView的过程,Adapter起到了至关重要的作用,不仅仅因为getview()方法。那么,先从Adapter说起~

Adapter:

    它在ListView和数据源之间起到桥梁的作用,避免listview和数据源直接接触,而导致因为数据源的复杂性使listview显得臃肿。

  Adapter,适配器,把复杂的数据源适配给listview,很容易联想到适配器模式。

 

下面是几种常用的Adapter:

  •  ArrayAdapter:简单易用的Adapter,通常用于数组或list集合的数据源(多个值包装成多个列表项)。
  •  simpleAdapter:并不见得、功能强大的Adapter,可用于list集合的多个对象包装成多个列表项。
  •  simpleCursorAdapter:与上相似,但是用于包装jCursor(数据库游标)提供的数据源。
  • BaseAdapter:通常用于被扩展。扩展BaseAdapter可以对各列表项进行最大限度的定制。

下面是listview的优化:

增加优化一:convertView的使用,主要优化加载布局问题

  1.listivew每次滚动都会调用gitview()方法,所以优化gitview是重中之重。

    下面是getview()在Adapter类的源码,这个没有实现,要看重点部分已经颜色标记。无非是View convertView的介绍~

/*** Get a View that displays the data at the specified position in the data set. You can either* create a View manually or inflate it from an XML layout file. When the View is inflated, the* parent View (GridView, ListView...) will apply default layout parameters unless you use* {@link android.view.LayoutInflater#inflate(int, android.view.ViewGroup, boolean)}* to specify a root view and to prevent attachment to the root.* * @param position The position of the item within the adapter's data set of the item whose view*        we want.* @param convertView The old view to reuse, if possible. Note: You should check that this view*        is non-null and of an appropriate type before using. If it is not possible to convert*        this view to display the correct data, this method can create a new view.*        Heterogeneous lists can specify their number of view types, so that this View is*        always of the right type (see {@link #getViewTypeCount()} and*        {@link #getItemViewType(int)}).* @param parent The parent that this view will eventually be attached to* @return A View corresponding to the data at the specified position.*/View getView(int position, View convertView, ViewGroup parent);

大家对于 convertView = null优化方法的使用已经了然于胸,但是我那个纠结,就知道是缓存了listview里面已经加载好的view(下文会讲解)。

核心代码如下:

     这部分代码很简单,如果没有缓存就加载布局,如果有缓存就直接用convertView对象。所以这样就不用滑动listview的时候

调用getView()方法每次都去加载布局了(如果改布局已经加载)。

View view;
if(convertView == null){
view = LayoutInfalter.from(getContext()).inflate(resourceID,null)
}
else{
view = convertView
}

表示宝宝一开始对 LayoutInfalter.from(getContext()).inflate(resourceID,null) 一脸蒙蔽,然后找到了解释。

//加载布局管理器
LayoutInflater inflater = LayoutInflater.from(context);
//将xml布局转换为view对象
convertView = inflater.inflate(R.layout.item_myseallist,parent, false);
//利用view对象,找到布局中的组件
convertView.findViewById(R.id.delete);// 删除

增加优化二:内部类ViewHolder的使用。

代码如下主要优化getView方法中每次回调用findviewByID()方法来获取一次控件的代码。

新增加内部类ViewHolder,用于对控件的实力存储进行缓存。

  • convertView为空时,viewHolder会将空间的实力存放在ViewHolder里,然后用setTag方法讲viewHolder对象存储在view里。
  • convertView不为空时,用getTag方法获取viewHolder对象.
//getView核心代码
ViewHolder viewHolder;
if(convertView == null){
viewHolder = new ViewHolder();
viewHolder.fruitImage = (ImageView) view.findViewByID(R.id.fruit_image);
view.setTage(viewHolder);//讲ViewHolder存储在View中}else{
view = convertView;
viewHolder = ViewHolder view.getTag();//重获取viewHolder
}
viewHolder.fruitImage.setImageResource(fruit.getIMageID);//内部类
class ViewHolder{
ImageView fruitImage;
}

可以看到方案一二目的很明确:第一个是优化加载布局,第二个是优化加载控件。

回到我问题~convertView存储的问题。

有没有想过ListView加载成千上万的数据为什么不出OOM错误?

最主要的是因为RecycleBin机制。

  • listview的许多view呈现在Ui上,这样的View对我们来说是可见的,可以称为OnScreen的view(也为ActionView)。
  • view被上滚移除屏幕,这样的view称为offScreenView(也称为ScrapView)。
  • 然后ScrapView会被listview删除,而RecycleView会将这部分保存。
  • 而listview底部需要显示的view会从RecycleBin里面取出一个ScrapView。

将其作为convertView参数传递过去,

  • 从而达到View复用的目的,这样就不必在Adapter的getView方法中执行LayoutInflater.inflate()方法了(不用加载布局了有木有)。

在RecycleBin里面有两个数组,看名字就知道了Actionview和ScrapViews.

/*** Views that were on screen at the start of layout. This array is populated at the start of* layout, and at the end of layout all view in mActiveViews are moved to mScrapViews.* Views in mActiveViews represent a contiguous range of Views, with position of the first* view store in mFirstActivePosition.*/private View[] mActiveViews = new View[0];/*** Unsorted views that can be used by the adapter as a convert view.*/private ArrayList<View>[] mScrapViews;

 原理如下:

Google推荐优化方案: 

public View getView(int position, View convertView, ViewGroup parent) {3:     Log.d("MyAdapter", "Position:" + position + "---"4:             + String.valueOf(System.currentTimeMillis()));5:     ViewHolder holder;6:     if (convertView == null) {7:         final LayoutInflater inflater = (LayoutInflater) mContext8:                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);9:         convertView = inflater.inflate(R.layout.list_item_icon_text, null);10:         holder = new ViewHolder();11:         holder.icon = (ImageView) convertView.findViewById(R.id.icon);12:         holder.text = (TextView) convertView.findViewById(R.id.text);13:         convertView.setTag(holder);14:     } else {15:         holder = (ViewHolder) convertView.getTag();16:     }17:     holder.icon.setImageResource(R.drawable.icon);18:     holder.text.setText(mData[position]);19:     return convertView;20: }21:  22: static class ViewHolder {23:     ImageView icon;24:  25:     TextView text;

转载于:https://www.cnblogs.com/chiguiming/p/6625861.html

Android优化系列之ListView优化老生常谈相关推荐

  1. Android性能优化系列之内存优化

    在Java中,内存的分配是由程序完成的,而内存的释放是由垃圾收集器(Garbage Collection,GC)完成的,程序员不需要通过调用函数来释放内存,但也随之带来了内存泄漏的可能,上篇博客,我介 ...

  2. Android性能优化系列:启动优化

    文章目录 1 应用启动类型 1.1 冷启动 1.2 温启动 1.3 热启动 2 查看启动耗时 2.1 adb命令查看 2.2 Logcat Displayed查看启动耗时 2.3 手动记录启动耗时 2 ...

  3. Android 性能优化系列之 —— 存储优化(3)

    序 昨晚公司进行团建 ,突突了两瓶汾酒结果都嗨了 ,亲眼见证程序员其实也是多才多艺的 ,有几个小伙伴简直就是被代码耽误的歌手 . PS :今天在家使用室友的 MacBookPro(TouchBar)的 ...

  4. Android开发系列之ListView

    上篇博客攻克了Androidclient通过WebService与server端程序进行交互的问题,这篇博客重点关注两个问题,一个是Android应用程序怎样与本机文件型数据库SQLite进行交互,还 ...

  5. Android性能优化系列之渲染优化

    众所周知的Android系统每隔16ms重新绘制一次activity,也就是说你的app必须在16ms内完成屏幕刷新的所有逻辑操作,这样才能达到60帧/s.而用户一般所看到的卡顿是由于Android的 ...

  6. Android性能优化系列之布局优化,Android程序员校招蚂蚁金服

    25 26 rInflate方法关键代码 void rInflate(XmlPullParser parser, View parent, Context context, AttributeSet ...

  7. Android性能优化系列之电量优化

    电量消耗的计算与统计是一件麻烦而且矛盾的事情,记录电量消耗本身也是一个费电量的事情,随着Android开的性能要求越来越高,电量的优化,也显得格外重要,一个耗电的应用,用户肯定会毫不犹豫的进行卸载,所 ...

  8. 你想要的Android性能优化系列:启动优化 !

    文章目录 一.概述 二.应用启动流程介绍 三.优化核心思想 四.时间检测 4.1 Displayed 4.2 adb shell 4.3 reportFullyDrawn() 4.4 代码打点 4.5 ...

  9. 抖音 Android 性能优化系列:启动优化实践

    动手点关注 干货不迷路 

最新文章

  1. 关于树,各种平衡树查找树的资料合集~~
  2. 一位跨平台开发者的自白
  3. 「技术人生」专题第1篇:什么是技术一号位?
  4. 虚拟光驱的开发者斟酌了很久
  5. uuid表示时间的部分_基于时间UUID的妙用
  6. android查看第三方libs的jar源码
  7. 新手干货:Vue - 常用指令
  8. c语言程序与结构,c语言基础与顺序结构-c语言程序设计.ppt
  9. idea 出现 GC overhead limit exceed解决
  10. chmod命令用法linux,Linux下chmod命令详细介绍及用法举例
  11. 基于Python的数据分析
  12. 基于SOLIDWORKS Simulation的有限元分析法实例应用
  13. WAP1 X/WAP2 0以及WAP浏览器的协议版本
  14. SpringBoot体验Mybatis、MybatisPlus、TKMybatis
  15. 静态多层Map缓存清除
  16. 加强财务知识细节:营业利润,利润总额,净利润
  17. 【POJ 3580】 SuperMemo
  18. 农民股神六万元博出千万身家
  19. 从数据爬取到决策树建模——预测北京二手房房价
  20. STM32基础-外部中断与优先级

热门文章

  1. Pytorch搭建自己的模型
  2. 使用flash在IPAD2上播放FLV效率不高
  3. windows虚拟声卡直播_【韭菜爱镰刀】高性价比的录音/直播设备推荐
  4. onvif学习笔记10:获取RTSP流地址
  5. cmd命令大全/cmd命令提示符大全
  6. windows上使用Git bash详细图文教程
  7. 拉普拉斯变换_拉普拉斯变化(s变换)定义与性质
  8. 【kafka】kafka UnknownProducerIdException raised broker locate producer metadata producerId
  9. 【hadoop】Hadoop Output directory file output already exists
  10. 【Elasticsearch】2021 年的顶级 ETL 工具......以及对 ETL 说“不”的理由