文档章节

Android ListView复杂列表优化实践

程序袁_绪龙
 程序袁_绪龙
发布于 2015/02/07 22:38
字数 1326
阅读 5990
收藏 39

原文: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版本可以体验到。


本文转载自:http://my.oschina.net/daxia/blog/376395

共有 人打赏支持
程序袁_绪龙
粉丝 98
博文 242
码字总数 66750
作品 0
普陀
程序员
加载中

评论(1)

qingzheng
qingzheng
测试安卓端程序
Android ListView复杂列表优化实践

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

叶大侠
2015/02/07
0
18
android中的selector背景选择器

关于listview和button都要改变android原来控件的背景,在网上查找了一些资料不是很全,所以现在总结一下android的selector的用法。 首先android的selector是在drawable/xxx.xml中配置的。 先...

泡泡爸爸
2013/03/17
0
0
Android组件及UI框架大全

Android 是目前最流行的移动操作系统(还需要加之一吗?)。 随着新版本的不断发布, Android的功能也日益强大, 涌现了很多流行的应用程序, 也催生了一大批的优秀的组件。 本文试图将目前流行...

千山万水
2015/07/13
0
4
Android组件及UI框架大全

Android 是目前最流行的移动操作系统(还需要加之一吗?)。 随着新版本的不断发布, Android的功能也日益强大, 涌现了很多流行的应用程序, 也催生了一大批的优秀的组件。 本文试图将目前流行...

千山万水
2015/07/13
0
0
android listview 拖动 背景变黑

一般这种情况是在android 4.0一下版本会出现,在4.0内系统已经优化listview 但是还是建议把这些属性加上。触摸拖动list列表时,背景一片黑色。(增加相关属性) listView.setCacheColorHint(Co...

tfc
2014/03/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

TypeScript基础入门之声明合并(一)

转发 TypeScript基础入门之声明合并(一) 声明合并 介绍 TypeScript中的一些独特概念描述了类型级别的JavaScript对象的形状。 TypeScript特别独特的一个例子是"声明合并"的概念。 在使用现有J...

durban
28分钟前
1
0
Mysql-db

aptitude install default-libmysqlclient-dev pip install mysql-python

dragon_tech
33分钟前
1
0
函数装饰器

def debug(func): def wrapper(*args, **kwargs): # 多个参数# def wrapper(something): # 指定一样的参数 print("[DEBUG]: enter {}()".format(func.__name__)) ......

colin_86
35分钟前
1
0
Notification-状态栏上的通知

当程序并不是出在运行状态的时候,可以调用Notification来显示通知。 1、创建 Notification的创建主要涉及到三个类:NotificationManager,Notification和PendingIntent NotificationManager主...

西米小娅
38分钟前
1
0
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource c

spring boot启动报错: Description: Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured. Reason: Failed to determin......

wenzhizhon
40分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部