# 布局优化
在实际的开发中布局的层次很容易超过 10 层如果超过 15 层就要重视并准备重新做优化,20 层就必须要修改了,实在没办法的话,就需要将复杂的布局层级使用自绘控件来实现。
# 一、减少层级
层级越少,测试和绘制的时间越短,通常减少层级的方法有
- 1、尽量使用 RelativeLayout 和 LinearLayout
- 2、在布局层级相同的情况下,使用 LinearLayout
- 3、使用 LinearLayout 有时候会让层级变得更多,所以应该使用 RelativeLayout,尽量使界面扁平化
RelativeLayout
存在性能低的问题,原因是 RelativeLayout
会对子 View
做两次测量,在 RelativeLayout
中子 View
的排列方式是基于彼此的依赖关系的。因为依赖关系可能和布局中 View
的顺序不一样,在确定每一个子 View
的位置时,需要先给所有的子 View 做一次排序,如果再 RelativeLayout
中允许子 View 横向或者纵向相互依赖,就需要横向和纵向分别在进行一次测量。
LinearLayout
中有 weight
属性,也需要做两次测量,因为没有更多的依赖关系,所以会比 RelativeLayout
效率高。
# 二、Merge 的使用
# 主要使用场景
在使用 Merge 的场合主要有以下两处:
1、在自定义
View
中使用,父元素尽量是FrameLayout
或者LinearLayout
2、在
Activity
中整体布局,根元素需要时FrameLayout。
- 在 `Android` 布局的源码中,如果是 `Merge` 标签,那么直接将其中的子元素添加到 `Merge` 标签的 `Parent` 中,这样就不会引入额外的层级了。 - 如果 `Merge` 代替的布局元素为 `LinearLayout`,在自定义布局代码中将 `LinearLayout` 属性添加到引用上,如垂直和水平布局,背景色等。
# 注意事项
Merge
只能用在布局XML
文件的根元素。- 使用
Merge
来加载一个布局时,必须指定一个 ViewGroup 作为其父元素,并且要设置加载的attchToRoot
参数为 true(也就是inflate(int,ViewGroup,boolean))
- 不能再 Viewstub 中使用 Merge 标签,原因是 ViewStub 的 inflate 方法中根本没有 attachToRoot 的设置
在
Activity
的总布局中使用Merge
,但又想设置整体的属性(比如布局方式和颜色),可以不使用setContentView
方法加载Layout
,而使用(id/content)将FrameLayout
取出。在代码中手动加载布局,但是如果层级压力不大(小于 10 级),则没有必要,因为代码的维护性就很差了。
# 三、提高显示速度使用 ViewStub
ViewStub
是一个轻量级的 View
,它是一个看不见的,并且不占用布局位置,占用资源非常小的视图对象,可以为 ViewStub
指定一个布局,加载布局时,只有 ViewStub
会被初始化,然后当 ViewStub
被设置为可见的时候,或者是调用 ViewStub,inflate()
时候,ViewStub
所指向的布局就会加载和实例化,然后 Vi`ewStub 的布局属性就会传给他指向的布局,这样就可以使用 ViewStub 来设置是否显示某个布局。
# 主要使用场景
- 在程序运行期间,某个布局在加载后就不会有变化,除非销毁该界面重新加载。
- 想要控制显示与隐藏的是一个布局文件,而不是 View
# 注意事项
ViewStub
只能加载一次,之后的ViewStub
对象将会被置空,换句话说,某个被ViewStub
指定加载的布局被加载后,就不能再通过 ViewStub 来控制它了,所以它不适用于按需隐藏的情况(还是只有使用setVisiable
的方式)。ViewStub
只能用来加载一个布局文件,而不是一个具体的 View(除非将一个 View 放入一个布局文件中)。ViewStub
中不能再嵌套Merge
标签了。
# 四、布局复用使用 include 标签
使用 include 标签。
# 五、布局优化总结
影响布局效率的主要是以下几个点:
- 布局层级越少,加载越快
- 减少同一层级控件的数量,加载速度会变快
- 一个控件的属性越少,加载会越快
总结:
- 尽量多使用
RelativiLayout
和LinearLayout
,不要使用AbsoluteLayout
布局。 - 将可复用的组件抽取出来,并通过
<include/>
标签使用 - 使用
<ViewStub/>
标签加载一个不变布局的的布局。 - 使用
<merge/>
标签减少布局的嵌套层次 - 尽可能少用
wrap_content
,wrap_content
会增加布局Measure
的计算成本,已知高为固定值得时候,不要使用 wrap_content - 删除控件中无用的属性。
- 本文链接: https://mrgaogang.github.io/android/performance/%E5%B8%83%E5%B1%80%E4%BC%98%E5%8C%96.html
- 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 许可协议。转载请注明出处!