技术咨询、项目合作、广告投放、简历咨询、技术文档下载 点击这里 联系博主

# 布局优化

在实际的开发中布局的层次很容易超过 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 标签。

# 五、布局优化总结

影响布局效率的主要是以下几个点:

  • 布局层级越少,加载越快
  • 减少同一层级控件的数量,加载速度会变快
  • 一个控件的属性越少,加载会越快

总结:

  • 尽量多使用 RelativiLayoutLinearLayout,不要使用 AbsoluteLayout 布局。
  • 将可复用的组件抽取出来,并通过<include/>标签使用
  • 使用<ViewStub/>标签加载一个不变布局的的布局。
  • 使用<merge/>标签减少布局的嵌套层次
  • 尽可能少用 wrap_content,wrap_content 会增加布局 Measure 的计算成本,已知高为固定值得时候,不要使用 wrap_content
  • 删除控件中无用的属性。
【未经作者允许禁止转载】 Last Updated: 2/4/2024, 6:06:40 AM