![Android性能优化-ListView自适应性能问题](http://img.jiangsulong.com/230324/152J22364-9.jpg)
文章插图
NoScrollListview 出现的主要目的是为了支持ListView放在ScrollView等垂直滚动视图中,原理很简单,利用前面ListView测量原理分析到的机制,强行设置AT_MOST来测量子View高度,也就是强制ListView自适应,即使你在xml中正确地使用layout_height=”match_parent”,在JAVA代码里面也会强行设置成wrap_content,导致的结果就是每一次onMeasure都会不停调用getView 。
如果,结合上前面说的RelativeLayout嵌套,ListView的性能损耗还要再翻倍!
假设ScrollView中存在RelativeLayout里面嵌套NoScrollListview,RelativeLayout嵌套层数为n,那么onMeasure的次数为2^n+2^(n+1)次,ListView显示项数为m,getView调用次数为(2^n + 2^(n+1) +1)* m次 。如果n=4,m=10,getView次数为490次
![Android性能优化-ListView自适应性能问题](http://img.jiangsulong.com/230324/152J2E92-10.png)
文章插图
相信看到这里,终于知道为什么ScrollView中嵌有列表的页面会卡出翔了吧!
当然,事情还远远不止这么简单,尤其在某些特殊的场景下,容易导致onMeasure频繁调用,以实际项目中遇到的问题场景举两个例子 。
- 有些ScrollView具有下拉弹性功能,当手指下拉时会导致子View不停onMeasure,如果子View包含NoScrollListview,页面肯定一顿一顿的 。
- 如果你在getView中的某些不恰当的操作导致ListView重新onMeasure,比如setVisibility为Gone等,就会造成onMeasure和getView的相互循环调用,这时候性能消耗非常严重(一般不会ANR) 。
- 同样的,某些时候我们需要监听ListView的滚动状态,会使用setOnScrollListener,由于在onMeasure的时候会触发OnScrollListener的回调,如果回调里面某些不恰当的操作导致ListView再次触发onMeasure就会导致OnScrollChangeListener和onMeasure两者的死循环 。
对于以上几点问题,有如下一些建议:
- 使用ListView的时候注意尽量使用layout_height=”match_parent” 。
- 如果第1点无法避免,需要注意ListView的父布局,父布局以上绝对不要使用RelativeLayout,即使使用FrameLayout或LinearLayout会增加布局层级 。
- 如果第1点无法避免,需要注意不要在getView中使用setVisibility这种会触发ListView重新onMeasure的操作 。
- 如果ListView存在位移,比如下来刷新等,绝对要遵循第1点来设置layout_height=”match_parent”,不然频繁触发onMeasure会导致交互卡顿 。
- 关于NoScrollListView,这种布局是严禁使用的,无论是哪种场景,如果ScrollView中必须要使用ListView,可以使用SimulateListView控件代替ListView
【Android性能优化-ListView自适应性能问题】
推荐阅读
- Android系统服务DropBoxManagerService详解与实践应用
- Go、Spring Boot、 Elixir 以及Helidon 微服务框架性能测试对比
- C++中的HashTable性能优化
- 七个你需要知道的强大 JavaScript 优化技巧
- 网络优化是做什么的(无线网络优化是做什么的)
- 什么手机性能好(目前配置最高的手机)
- 优化是什么意思(需要优化是什么意思)
- 超频是什么意思(手机cpu用久了性能会下降吗)
- 求职|为了通过面试可以在简历上撒谎吗?简历优化和造假有什么区别?
- 现在什么手机最好(目前性能最好的手机是什么)