news 2026/8/27 12:42:07

【提升栈】ListView优化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【提升栈】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(int position, View convertView, ViewGroup paramViewGroup) { Object current_event = mObjects.get(position); ViewHolder holder = null; if (convertView == null) { holder = new ViewHolder(); 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 = new RelativeLayout.LayoutParams(measuredwidth, rowHeight); holder.EventPoster.setLayoutParams(imageParams); return convertView; }

优化后的getView():

@Override public View getView(int position, View convertView, ViewGroup paramViewGroup) { Object object = mObjects.get(position); ViewHolder holder = null; if (convertView == null) { holder = new ViewHolder(); 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 = new RelativeLayout.LayoutParams(measuredwidth, rowHeight); holder.EventPoster.setLayoutParams(imageParams); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } // 我们直接通过对象的getter方法取代刚才那些逻辑推断。那些逻辑推断放到别的地方去运行了 holder.ThreeDimension.setVisibility(object.getVisibility()); return convertView; }

2.GC 垃圾回收器

当你创建了大量的对象的时候。GC就会频繁的运行。所以在getView()方法中不要创建非常多的对象。最好的优化是,不要在ViewHolder以外创建不论什么对象。假设你的你的log里面发现“GC has freed some memory”频繁出现的话。那你的程序肯定有问题了。

你能够检查一下:
a) item布局的层级是否太深
b) getView()方法中是否有大量对象存在
c) ListView的布局属性

3.载入图片

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

listView.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView listView, int scrollState) { //停止载入图片 if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) { imageLoader.stopProcessingQueue(); } else { //開始载入图片 imageLoader.startProcessingQueue(); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { // 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

<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

<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的时候,一定要将这几点考虑进去,发挥它的最大的性能。

这些东西其实只要技术到了一定高度,经验多了就很稀疏平常。

学无止境,更多的知识在等着我们去学习。

需要学习进阶框架技术的可以扫码领取资料!

**《Android架构开发手册》**Android进阶框架学习教材

由于文章内容比较多,篇幅有限,资料已经被整理成了PDF文档,有需要**《Android架构开发手册》**完整文档的可以加微信 即可免费领取!

### **目录**

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/27 12:38:07

RGBWY五路独立调光:支持PD充电宝、适配器、储能电源

你见过&#xff0c;不带电池&#xff0c;却能用充电宝供电的美容大排灯吗&#xff1f;采用PD方案的美容大排灯传统美容大排灯一般采用插电或锂电池供电&#xff0c;而大容量电池不仅成本高&#xff0c;充电时间也更长。现在越来越多的LED医美和光疗产品&#xff0c;开始采用 Ty…

作者头像 李华
网站建设 2026/8/27 12:37:06

给大家普及一下,腾讯Agent开发社招要达到什么强度

很多人觉得&#xff0c;腾讯Agent开发就是会调用大模型、会搭几个Agent Demo。 如果你真这么想&#xff0c;面试大概率过不了。 最近看了腾讯公开招聘的Agent岗位&#xff0c;再结合身边已经上岸朋友的反馈&#xff0c;我发现腾讯现在招Agent开发&#xff0c;考察重点已经变了。…

作者头像 李华
网站建设 2026/8/27 12:37:01

34岁Java后端转AI应用开发1年,说点没人敢说的大实话

交个底&#xff0c;我34&#xff0c;做了8年Java&#xff0c;去年底裸辞转的AI。 这一年过得什么日子呢——Python现学的&#xff0c;LangChain翻了三遍文档还懵&#xff0c;第一次面试被问RAG的QPS&#xff0c;一个字都憋不出来。凌晨调线上bug是家常便饭&#xff0c;躺在床上…

作者头像 李华
网站建设 2026/8/27 12:34:00

福州永泰麻将微信小程序后端:从zip交付到部署上线全链路解析

简介&#xff1a;在微信小程序后端开发中&#xff0c;棋牌类项目因实时对战和复杂规则而尤为考验工程能力。以福州永泰麻将为例&#xff0c;其后端通常以zip包形式交付&#xff0c;涵盖源码、配置、数据库脚本与部署文档。开发过程中&#xff0c;开发者常遇到“file is not a z…

作者头像 李华
网站建设 2026/8/27 12:32:52

LTE-M/NB-IoT大规模部署:IoT模块选型与工程实践

这几年要说什么物联网技术最接地气&#xff0c;LTE-M和NB-IoT一定排在最前面。它们不追高带宽&#xff0c;却把覆盖、功耗和成本做到了极致&#xff0c;让海量低速率设备第一次有了规模化落地的路径。而在这条路径里&#xff0c;IoT模块是整个链条上最关键的节点——它一头连着…

作者头像 李华
网站建设 2026/8/27 12:32:40

曲线回归结果解读:非线性关系的建模与检验

曲线回归结果解读曲线回归&#xff08;curvilinear regression&#xff09;是用于研究自变量X与因变量Y之间非线性关系的统计分析方法。当散点图显示变量间存在明显的曲线趋势而非线性关系时&#xff0c;可通过多项式变换将非线性模型转化为线性形式进行参数估计。本研究采用SP…

作者头像 李华