文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2022-06-06 09:12

关注

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 ListView和ProgressBar(进度条控件)的使用方法Android控件之ListView用法实例详解Android ExpandableListView展开列表控件使用实例Android控件ListView用法(读取联系人示例代码)Android UI控件ExpandableListView基本用法详解android使用ExpandableListView控件实现小说目录效果的例子Android控件之使用ListView实现时间轴效果Android 自定义弹性ListView控件实例代码(三种方法)Android编程之控件ListView使用方法Android控件ListView使用方法详解


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯