1. 简介
应用程序布局直接影响用户体验。如果实现不够理想,那么会导致严重内存问题并且拖慢加载过程。Android SDK中包含了相关工具用来定位布局的性能问题,通过这些工具你能够以最小的内存实现平滑滚动。
以下从四部分描述如何进行布局优化,分别为减少布局层次、 使用
2. 减少布局层次
如果复杂的网页会拖长加载时间一样,越复杂的布局加载时间越长,带来的用户体验也越差。因为每个视图都需要经过初始化、布局和绘制的过程,如果布局嵌套层次越深,这些过程就越耗时。因此在构建布局时应该尽量将布局进行扁平化处理,即尽量少进行布局嵌套。
查找布局层次问题的工具有:Hierarchy Viewer、Lint、LayoutOpt(已被Lint替代)。
Lint提供的一些优化建议:
- 使用Compound Drawable — 用一个Compound Drawable 替代一个包含 ImageView 和 TextView 的LinearLayout 会更有效率;
- 使用merge合并根节点 — 如果 FrameLayout 是 Layout 的根节点,并且没有使用padding 或者背景等,那么用 merge 标签替代他们会稍微高效些;
- 去除无用的子节点 — 一个没有子节点或者背景的 Layout 应该被去掉,来获得更扁平的层次;
- 去除无用的父节点 — 一个节点如果没有兄弟节点,并且它不是 ScrollView 或根节点,没有背景,这样的节点应该直接被子节点取代,来获得更扁平的层次
- 使用RelativeLayout或GridLayout — LinearLayout这类布局可能会导致嵌套层次太深,可以尝试使用更扁平的布局,例如RelativeLayout 或 GridLayout 。
以LinearLayout替换为RelativeLaytout为例,通过Hierarchy Viewer查看,如图一使用LinearLayout层次为数3,替换后图二RelativeLaytout层次数为2。
替换后:
3. 使用merge标签实现布局复用
在Android提供了
例如为实现多个界面相同的标题栏背景,首先定义titlebar.xml如下:
在需要设置标题的Activity布局中:
可以看出这里将多出
布局最终结构为:
这里
4. 使用ViewStub动态加载视图
有时我们可能不希望某部分视图在初始化时就被加载,而是希望需要呈现时才进行加载以便提高加载速度。例如进度条、列表项的细节,这时可以使用ViewStub来实现。
ViewStub是一个不包含尺寸的轻量级视图。它不会在Layout中加入任何信息,只有当ViewStub设置为可见或调用inflate()时才会在上级Layout中加入ViewStub 属性android:layout指向的布局。
如下定义一个ViewStub:
ViewStub载入方式一设为可见:
ViewStub载入方式二调用inflate():
一旦设为可见或执行了inflate(),ViewStub元素不再是视图层次中的一部分。它将被它指向的布局替代,并且ID为属性android:inflatedId的值(android:id属性值将不再有效)。
5. 使用ViewHolder缓存视图对象
频繁调用findViewById()可能会影响到性能,例如在ListView中可能会影响到滑动的效果,通过缓存视图对象减少查询操作来提高性能。
例如可以定义一个ViewHolder类:
在ListView每一项创建时执行:
这样可以快速获取每一项的视图,而不需要通过findViewById(),从而节省了CPU计算时间提高了效率。
6. 相关文章
http://developer.android.com/training/improving-layouts/index.html