浅谈Android开发中ListView控件性能的一些优化方法

 更新时间:2016年01月18日 09:37:18   作者:左老怪  
这篇文章主要介绍了Android开发中ListView控件性能的一些优化方法,需要的朋友可以参考下

ListView优化一直是一个老生常谈的问题,不管是面试还是平常的开发中,ListView永远不会被忽略掉,那么这篇文章我们来看看如何最大化的优化ListView的性能。

1.在adapter中的getView方法中尽量少使用逻辑

2.尽最大可能避免GC

3.滑动的时候不加载图片

4.将ListView的scrollingCache和animateCache设置为false

5.item的布局层级越少越好

6.使用ViewHolder

下面就具体来看一些

1.在adapter中的getView方法中尽量少使用逻辑

不要在你的getView()中写过多的逻辑代码,我们可以将这些代码放在别的地方,例如:

优化前的getView():

@Override

public View getView(intposition, View convertView, ViewGroup paramViewGroup) {

Object current_event = mObjects.get(position);

ViewHolder holder =null;if(convertView ==null) {

holder =newViewHolder();

convertView = inflater.inflate(R.layout.row_event,null);

holder.ThreeDimension = (ImageView) convertView.findViewById(R.id.ThreeDim);

holder.EventPoster = (ImageView) convertView.findViewById(R.id.EventPoster);

convertView.setTag(holder);

}else{

holder = (ViewHolder) convertView.getTag();

}

//在这里进行逻辑判断,这是有问题的

if(doesSomeComplexChecking()) {

holder.ThreeDimention.setVisibility(View.VISIBLE);

}else{

holder.ThreeDimention.setVisibility(View.GONE);

}

// 这是设置image的参数,每次getView方法执行时都会执行这段代码,这显然是有问题的

RelativeLayout.LayoutParams imageParams =newRelativeLayout.LayoutParams(measuredwidth, rowHeight);

holder.EventPoster.setLayoutParams(imageParams);

returnconvertView;

}

优化后的getView():

@Override

public View  getView(intposition, View convertView, ViewGroup paramViewGroup) {

Object object = mObjects.get(position);

ViewHolder holder =null;if(convertView ==null) {

holder =newViewHolder();

convertView = inflater.inflate(R.layout.row_event,null);

holder.ThreeDimension = (ImageView) convertView.findViewById(R.id.ThreeDim);

holder.EventPoster = (ImageView) convertView.findViewById(R.id.EventPoster);

//设置参数提到这里,只有第一次的时候会执行,之后会复用

RelativeLayout.LayoutParams imageParams =newRelativeLayout.LayoutParams(measuredwidth, rowHeight);

holder.EventPoster.setLayoutParams(imageParams);

convertView.setTag(holder);

}else{

holder = (ViewHolder) convertView.getTag();

}// 我们直接通过对象的getter方法代替刚才那些逻辑判断,那些逻辑判断放到别的地方去执行了holder.ThreeDimension.setVisibility(object.getVisibility());returnconvertView;

}

2.GC 垃圾回收器

当你创建了大量的对象的时候,GC就会频繁的执行,所以在getView()方法中不要创建很多的对象,最好的优化是,不要在ViewHolder以外创建任何对象,如果你的你的log里面发现“GC has freed some memory”频繁出现的话,那你的程序肯定有问题了。你可以检查一下:

a) item布局的层级是否太深

b) getView()方法中是否有大量对象存在

c) ListView的布局属性

3.加载图片

如果你的ListView中需要显示从网络上下载的图片的话,我们不要在ListView滑动的时候加载图片,那样会使ListView变得卡顿,所以我们需要再监听器里面监听ListView的状态,如果滑动的时候,停止加载图片,如果没有滑动,则开始加载图片

listView.setOnScrollListener(newOnScrollListener() {

@Override

public void onScrollStateChanged(AbsListView listView,intscrollState) {

//停止加载图片

if(scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) {

imageLoader.stopProcessingQueue();

}else{

//开始加载图片

imageLoader.startProcessingQueue();

}

}

@Override

public void onScroll(AbsListView view,intfirstVisibleItem,intvisibleItemCount,inttotalItemCount) {

// TODO Auto-generated method stub}

});

4.将ListView的scrollingCache和animateCache设置为false

scrollingCache:scrollingCache本质上是drawing cache,你可以让一个View将他自己的drawing保存在cache中(保存为一个bitmap),这样下次再显示View的时候就不用重画了,而是从cache中取出。默认情况下drawing cahce是禁用的,因为它太耗内存了,但是它确实比重画来的更加平滑。而在ListView中,scrollingCache是默认开启的,我们可以手动将它关闭。

animateCache:ListView默认开启了animateCache,这会消耗大量的内存,因此会频繁调用GC,我们可以手动将它关闭掉

优化前的ListView

<android:id="@android:id/list"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:cacheColorHint="#00000000"

android:divider="@color/list_background_color"

android:dividerHeight="0dp"

android:listSelector="#00000000"

android:smoothScrollbar="true"

android:visibility="gone"/>

优化后的ListView

<android:id="@android:id/list"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:divider="@color/list_background_color"

android:dividerHeight="0dp"

android:listSelector="#00000000"

android:scrollingCache="false"

android:animationCache="false"

android:smoothScrollbar="true"

android:visibility="gone"/>

5.减少item的布局的深度

我们应该尽量减少item布局深度,因为当滑动ListView的时候,这回直接导致测量与绘制,因此会浪费大量的时间,所以我们应该将一些不必要的布局嵌套关系去掉。减少item布局深度

6.使用ViewHolder

这个大家应该非常熟悉了,但是不要小看这个ViewHolder,它可以大大提高我们ListView的性能

ListView的优化我们已经讲完了,如果在你的项目中,这些基本优化你还没有做到的话,那么你的ListView是有问题的,还有很大的提升潜力,以后再使用ListView的时候,一定要将这几点考虑进去,发挥它的最大的性能。

附:

此外,如果发现性能方面的问题,以下几个常见问题也应注意:

1..Adapter的getView方法里面convertView没有使用setTag和getTag方式;

2.在getView方法里面ViewHolder初始化后的赋值或者是多个控件的显示状态和背景的显示没有优化好,抑或是里面含有复杂的计算和耗时操作;

3.在getView方法里面 inflate的row 嵌套太深(布局过于复杂)或者是布局里面有大图片或者背景所致;

4.Adapter多余或者不合理的notifySetDataChanged;

5.listview 被多层嵌套,多次的onMessure导致卡顿,如果多层嵌套无法避免,建议把listview的高和宽设置为fill_parent. 如果是代码继承的listview,那么也请你别忘记为你的继承类添加上LayoutPrams,注意高和宽都是fill_parent的;  以往我一般都是将listview的高度设置成fill_parent,而这次我是设为wrap_content,这样做的问题在于,ListView没有取到实际的高度,他还要根据计算才能确定,而每一次计算应该会触发listview的渲染,所以就会出现getview的调用次数跟正常情况相比多了好几倍。所以在一般情况下,我建议把listiview在布局文件中的高度总是设置为:fill_parent(或者match_parent),这不仅仅是getview的调用次数问题,还涉及到布局的效率。

相关文章

  • Android实现消息提醒小红点效果

    Android实现消息提醒小红点效果

    这篇文章主要为大家详细介绍了Android实现消息提醒小红点效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • Android中二维码的扫描和生成(使用zxing库)

    Android中二维码的扫描和生成(使用zxing库)

    ZXing是一个开放源码的,用Java实现的多种格式的1D/2D条码图像处理库,它包含了联系到其他语言的端口,下面这篇文章主要给大家介绍了关于Android中二维码扫描和生成的相关资料,主要使用的zxing库,需要的朋友可以参考下
    2022-09-09
  • Android一行代码实现圆形头像

    Android一行代码实现圆形头像

    本篇文章主要介绍了Android一行代码实现圆形头像的相关知识,具有很好的参考价值。下面跟着小编一起来看下吧
    2017-05-05
  • Android在kts中使用navigation及Args的方法

    Android在kts中使用navigation及Args的方法

    在Android项目中使用Kotlin脚本(kts)替代Groovy配置navigation和Args,需添加相关依赖,并在build.gradle中进行配置,文章详细介绍了如何在kts中使用navigation进行页面导航和参数传递,介绍了使用Bundle和Safe Args两种方式安全传递参数
    2024-10-10
  • 在AndroidManifest.xml中uses-sdk内属性意思

    在AndroidManifest.xml中uses-sdk内属性意思

    本文为大家讲解下minSdkVersion、targetSdkVersion、maxSdkVersion、target API level四个数值的意思与区别,感兴趣的朋友可以参考下哈
    2013-06-06
  • 利用Jetpack Compose实现主题切换功能

    利用Jetpack Compose实现主题切换功能

    这篇文章主要介绍了如何利用Android中的Jetpack Compose实现主题切换功能,文中的示例代码讲解详细,对我们学习有一定帮助,需要的可以参考一下
    2022-01-01
  • Android 动画之AlphaAnimation应用详解

    Android 动画之AlphaAnimation应用详解

    本节讲解AlphaAnimation 动画,窗口的动画效果,淡入淡出什么的,有些游戏的欢迎动画,logo的淡入淡出效果就使用AlphaAnimation,具体的祥看本文,需要的朋友可以参考下
    2012-12-12
  • Android 蓝牙BLE开发完全指南

    Android 蓝牙BLE开发完全指南

    BLE蓝牙的兴起主要因为近年来可穿戴设备的流行,由于传统蓝牙功耗高不能满足可穿戴设备对于续航的要求,所以大部分可穿戴设备采用蓝牙4.0,即BLE蓝牙技术,这篇文章主要给大家介绍了关于Android 蓝牙BLE开发的相关资料,需要的朋友可以参考下
    2021-11-11
  • Android自定义开关按钮源码解析

    Android自定义开关按钮源码解析

    这篇文章主要为大家详细解析了Android自定义开关源码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • Android Jetpack架构组件 ViewModel详解

    Android Jetpack架构组件 ViewModel详解

    这篇文章主要介绍了Android Jetpack架构组件 ViewModel详解,ViewModel类让数据可在发生屏幕旋转等配置更改后继续存在,ViewModel类旨在以注重生命周期的方式存储和管理界面相关的数据。感兴趣可以来学习一下
    2020-07-07

最新评论