文档章节

Android ListView复杂列表优化实践

叶大侠
 叶大侠
发布于 2015/02/07 16:11
字数 1326
阅读 5239
收藏 174
点赞 5
评论 18

原文:Android ListView复杂列表优化实践



很多社交App都不免会涉及到复杂的列表元素实现,一个列表上面可能大量的图片,不定长的评论列表,给手机端的程序员带来了不少的挑战。本文就是在实现复杂的列表滑动的情况下,利用已知的优化方法指导下的一次优化实践,旨在提升ListView的滑动流畅度,为用户带来良好的体验。

1:设计稿:

 

这是列表中可能出现的ItemView,有两种,但是又有许多相同的地方,比如一样有点赞的图片,评论等...其中,评论和点赞的数量是可变的

2:使用一般布局带来的问题?

头像表格:如果使用自带的布局LinearLayout和ImageView来完成,会导致布局比较深,而且大量的addView操作会导致列表滑动的时候卡顿。

评论列表:和头像表格一样,由于Item的数量是会变化的,会带上和头像表格同样的问题。

大量图片加载: 不难看出图片的数量是可观的,由于每次请求回来的内容可能有很多条,如果数据一回来就请求里面带的全部图片链接,即使使用了线程池,也会占用cpu比较长的一段时间,因此也会带来界面的不流畅问题。

3:指导优化思路:

    (1): ViewHolder模式, 重用View和减少Child View查找时间,相信大家对这个都不陌生。

    (2): 尽可能减少布局层次

    (3): 只刷新变化的部分View

    (4): 避免调用addView这样的方法

    (5): 只加载当前视图需要的图片,并且在滑动列表的时候停止后台的加载线程,为UI线程空出cpu资源,在停止的时候再请求。

    (6): 首次加载图片就处理(圆角/缩放等)并缓存在本地

4:实践过程:

4.1:布局和View部分:

把【头像表格】和【评论列表】作为一个整体的自定义View来实现,右边的卡片结构基本一个RelativeLayout就可以实现了,这样整个Item就基本可以控制在3~4个层次深度上面。

【头像表格】实现注意点:

1):一开始应该先用默认头像填充,之后再图片返回的时候不要粗鲁地使用invalidate(),而是使用invalidate(Rect rect),进行局部刷新,响应点击事件更换背景时也应如此。

2):由于onMesure和onDraw的的过程是比较频繁和代价较高的,因此要尽可能复用对象,如(Paint, Rect...)

【评论列表】实现要点:

  1):除了上面提到的,这里有个难点就是字符串的绘制,什么时候该换行?这里涉及到非常复杂的文字处理,尤其是不同国家的不同文字系统,幸好,这些在Android API里面都有了相关实现,笔者是在TextView中找到的,也就是android.text.Layout 的几个实现类,笔者在这里只是使用了DynamicLayout来实现。通过这个类你可以获得字符串的高度信息(onMeasure),行数等...而且它已经实现了draw的过程,只需调整好画布的位置(canvas.translate),直接调用就可以了,非常方便。

【额外元素】

1):回到设计图上,我们看到还有可能出现的股票信息,对于这种额外元素,<ViewStub>最适合不过了...

【ListView】的数据变化:

  1):对于整个Item的增加或者删除动作,可以调用notifyDataChanged()。

2):对于Item内部的数据变化,不要粗鲁地使用notifyDataChanged(), 而是改变产生变化的View。

4.2:图片处理部分:

笔者一开始的想法是想做到:

1): 线程池,并且可以暂停所有下载线程和恢复下载

2): 双重缓存,本地永久缓存和内存级缓存

3): 滑动时候暂停所有下载,出让cpu资源给UI线程。

在实现的过程中,在多线程这里经常做的不好,经常出问题,非常幸运在github上找到了一个开源项目可以完美地解决上面的所有问题。现在我们公司的Android项目所有的图片加载已经自豪地使用上了... 附上地址:Android-Universal-Image-Loader

5:调整之后的效果:

由于笔者没有保留之前的界面卡顿时候的代码,因此只能演示最后的实现效果了,不能进行前后的比较。手机是小米4,图表是Developer选项中的Profile GPU rendering中,打开后前后不断滑动的结果。这里可以看到大部分情况都能在绿线下,说明整体的体验还是非常流畅的。

喜欢炒股的朋友也可以进一步去下载我们的应用:微财 , 即将在3.0版本可以体验到。

© 著作权归作者所有

共有 人打赏支持
叶大侠

叶大侠

粉丝 56
博文 44
码字总数 67312
作品 5
广州
程序员
加载中

评论(18)

李士钰

引用来自“海风心情”的评论

看到你们3.0版本了,不能发图片啊
码农还有这么美的?
叶大侠
叶大侠

引用来自“lackiechan”的评论

引用来自“DarcyYe”的评论

引用来自“lackiechan”的评论

不错,居然是在广州大学城,我也在广州大学城13

呵呵,请问可以向你请教一下吗?我拿开源中国的android源码的图片加载换成Android—Universal—Image—liader,并且listView加上滚动事件监听listview.setOnScrollListener(new PauseOnScrollListener(ImageLoader.getInstance(),true,true,this)); 但是滚动的时候还是有卡顿现象,我看开源中国源码里面也是采用了VIewHolder模式,但是不知道为什么还会卡顿
不知道你的具体情况是什么样子的~ 你可以试着分析性能可能出现的地方~ 然后尝试从对象的复用,优化View的层次和View的数量,和尽量除了更新Ui的耗时操作放到后台线程看看?
lackiechan
lackiechan

引用来自“DarcyYe”的评论

引用来自“lackiechan”的评论

不错,居然是在广州大学城,我也在广州大学城13

呵呵,请问可以向你请教一下吗?我拿开源中国的android源码的图片加载换成Android—Universal—Image—liader,并且listView加上滚动事件监听listview.setOnScrollListener(new PauseOnScrollListener(ImageLoader.getInstance(),true,true,this)); 但是滚动的时候还是有卡顿现象,我看开源中国源码里面也是采用了VIewHolder模式,但是不知道为什么还会卡顿
叶大侠
叶大侠

引用来自“lackiechan”的评论

不错,居然是在广州大学城,我也在广州大学城13
lackiechan
lackiechan
不错,居然是在广州大学城,我也在广州大学城13
一只大熊猫
一只大熊猫
79
noprom
noprom
不错不错
lucky_jayce
lucky_jayce

引用来自“DarcyYe”的评论

引用来自“海风心情”的评论

看到你们3.0版本了,不能发图片啊
mark, 年后加~

0
叶大侠
叶大侠

引用来自“海风心情”的评论

看到你们3.0版本了,不能发图片啊
mark, 年后加~
红鼠、
红鼠、
看到你们3.0版本了,不能发图片啊
Android系统源码分析团体项目BeesAndroid正式上线啦

嗨,BeesAndroid开源技术小组正式成立啦,Bees,即蜜蜂,取义分享、合作与奉献的意思,这也是BeesAndroid小组的宗旨,我们第一个团体项目BeesAndroid也于2018年3月6日同步上线,该项目的前 ...

郭孝星 ⋅ 03/08 ⋅ 0

Android分页加载刷新AsyncListUtil中DataCallback的refreshData()

Android分页加载刷新AsyncListUtil中DataCallback的refreshData() Android分页加载刷新AsyncListUtil中DataCallback的refreshData()函数,返回值控制分页总数据量。如果返回一个既定的整型数...

zhangphil ⋅ 05/29 ⋅ 0

Java反射改变Android属性

Java反射改变Android属性 在某些情况下,Android体系里面的某些对象没有对外提供针对某个属性或者类,方法公开的get或者set方法,但是项目需要对这些需要修改和调整。就需要使用Java的反射机...

zhangphil ⋅ 04/28 ⋅ 0

[搬运] 三层界面布局实例展示

本文系搬运过来,原文章链接 http://www.jb51.net/article/39399.htm 给原作者点赞 共同学习,希望对您有所帮助 android实现底部布局往往使用RelativeLayout的布局方式,并且设置android:lay...

sirius_0 ⋅ 2016/01/08 ⋅ 0

Android ListView复杂列表优化实践

原文:Android ListView复杂列表优化实践 很多社交App都不免会涉及到复杂的列表元素实现,一个列表上面可能大量的图片,不定长的评论列表,给手机端的程序员带来了不少的挑战。本文就是在实现...

程序袁_绪龙 ⋅ 2015/02/07 ⋅ 1

打造万能的BannerView(ViewPager)无限轮播图

为什么写这篇文章,因为在网上看到的绝大多数BannerView实现了右无限轮播图,甚至没有实现无限轮播图,说成是无限轮播图,实现了左右无限轮播图的,并没有做性能上的优化。 先看张效果图 工程...

Steven_520 ⋅ 05/11 ⋅ 0

德清县服务(小妹)这真找哪全套一晚上多少?

【十Ⅴィ訁:KL22228芬芬】德清县服务(小妹【各种特色,任您挑选】【十Ⅴィ訁:KL22228芬芬】客人虐我千百遍,我待客人如初恋我们将竭诚为您服务,只有您想不到,没有我们做不...

隔壁家的老王 ⋅ 03/17 ⋅ 0

克拉玛依独山子区服务(小妹)这真找哪全套一晚上多少?

【十Ⅴィ訁:KL22228芬芬】克拉玛依独山子区服务(小妹【各种特色,任您挑选】【十Ⅴィ訁:KL22228芬芬】客人虐我千百遍,我待客人如初恋我们将竭诚为您服务,只有您想不到,没...

chazz ⋅ 03/17 ⋅ 0

Android性能优化:这是一份详细的布局优化 指南(含、、)

前言 在 开发中,性能优化策略十分重要 本文主要讲解性能优化中的布局优化,希望你们会喜欢。 目录 /** 实例说明:在上述例子,在布局B中 通过标签引用布局C 此时:布局层级为 = RelativeLa...

Carson_Ho ⋅ 05/14 ⋅ 0

Android取消RecyclerView、ListView、ScrollView、HorizontalScrollView滑动到边缘闪现灰白色水波纹动画

Android取消RecyclerView、ListView、ScrollView、HorizontalScrollView滑动到边缘闪现灰白色水波纹动画 标准的Android RecyclerView、ListView、ScrollView、HorizontalScrollView滑动到边缘...

zhangphil ⋅ 05/04 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Springboot2 之 Spring Data Redis 实现消息队列——发布/订阅模式

一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式,这里利用redis消息“发布/订阅”来简单实现订阅者模式。 实现之前先过过 redis 发布订阅的一些基础概念和操...

Simonton ⋅ 23分钟前 ⋅ 0

error:Could not find gradle

一.更新Android Studio后打开Project,报如下错误: Error: Could not find com.android.tools.build:gradle:2.2.1. Searched in the following locations: file:/D:/software/android/andro......

Yao--靠自己 ⋅ 昨天 ⋅ 0

Spring boot 项目打包及引入本地jar包

Spring Boot 项目打包以及引入本地Jar包 [TOC] 上篇文章提到 Maven 项目添加本地jar包的三种方式 ,本篇文章记录下在实际项目中的应用。 spring boot 打包方式 我们知道,传统应用可以将程序...

Os_yxguang ⋅ 昨天 ⋅ 0

常见数据结构(二)-树(二叉树,红黑树,B树)

本文介绍数据结构中几种常见的树:二分查找树,2-3树,红黑树,B树 写在前面 本文所有图片均截图自coursera上普林斯顿的课程《Algorithms, Part I》中的Slides 相关命题的证明可参考《算法(第...

浮躁的码农 ⋅ 昨天 ⋅ 0

android -------- 混淆打包报错 (warning - InnerClass ...)

最近做Android混淆打包遇到一些问题,Android Sdutio 3.1 版本打包的 错误如下: Android studio warning - InnerClass annotations are missing corresponding EnclosingMember annotation......

切切歆语 ⋅ 昨天 ⋅ 0

eclipse酷炫大法之设置主题、皮肤

eclipse酷炫大法 目前两款不错的eclipse 1.系统设置 Window->Preferences->General->Appearance 2.Eclipse Marketplace下载【推荐】 Help->Eclipse Marketplace->搜索‘theme’进行安装 比如......

anlve ⋅ 昨天 ⋅ 0

vim编辑模式、vim命令模式、vim实践

vim编辑模式 编辑模式用来输入或修改文本内容,编辑模式除了Esc外其他键几乎都是输入 如何进入编辑模式 一般模式输入以下按键,均可进入编辑模式,左下角提示 insert(中文为插入) 字样 i ...

蛋黄Yolks ⋅ 昨天 ⋅ 0

大数据入门基础:SSH介绍

什么是ssh 简单说,SSH是一种网络协议,用于计算机之间的加密登录。 如果一个用户从本地计算机,使用SSH协议登录另一台远程计算机,我们就可以认为,这种登录是安全的,即使被中途截获,密码...

董黎明 ⋅ 昨天 ⋅ 0

web3j教程

web3j是一个轻量级、高度模块化、响应式、类型安全的Java和Android类库提供丰富API,用于处理以太坊智能合约及与以太坊网络上的客户端(节点)进行集成。 汇智网最新发布的web3j教程,详细讲解...

汇智网教程 ⋅ 昨天 ⋅ 0

谷歌:安全问题机制并不如你想象中安全

腾讯科技讯 5月25日,如今的你或许已经对许多网站所使用的“安全问题机制”习以为常了,但你真的认为包括“你第一个宠物的名字是什么?”这些问题能够保障你的帐户安全吗? 根据谷歌(微博)安...

问题终结者 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部