问题:

布局层级太多怎么优化

答复:

View全体布局是经过深度优先的方式来进行组织的,全体形似一颗树,所以优化布局层级主要经过三个方历来实施:

  • 下降布局深度:运用merge标签或许布局层级优化等手法来削减View树的深度;
  • 布局懒加载:运用ViewStub,AsyncLayoutInflater等布局加载手法,来保证只有当需要该布局时,该布局才会被创立,优化布局加载速度;
  • 布局重用:经过include等标签重用界面布局,削减GPU重复作业

解析:

<merge/>

<merge/>标签通常用于将其包裹的内容直接添加到父布局以到达下降布局深度的目的,一个一般的layout布局文件及其结构如下图所示:

面试串讲009-布局层级太多怎么优化?

当将该布局文件的根标签修改为<merge/>标签后,得到的布局结构如下图所示:

面试串讲009-布局层级太多怎么优化?

能够看出<merge/>标签内人元素的父布局均变更为顶上的FrameLayout,进而使得布局深度减1.

结合以上比如,我们能够得出 <merge/>标签的主要作业原理是将本应在<merge/>标签节点的Layout与该节点的父布局进行重用,以到达优化布局深度的目的,对<merge/>标签内包含的其他布局结构而言并不能起到优化深度的作用

运用<merge/>标签有以下注意事项:

  • 布局文件中<merge/>标签只能作为根标签;
  • 运用LayoutInflater加载<merge/>标签为根的布局文件时,必须设置attachToRoot为true,以保证重用父布局;
  • <merge/>标签带着的参数没有实际意义
  • <merge/>标签并不是实在存在的View或许ViewGroup,其相当于一种标记,用来表示其所包裹的内容应被添加到其上级布局,实在存在的ViewGroup是引用<merge/>标签布局的上一级布局

<ViewStub/>

<ViewStub/>标签通常用于声明布局中能够被延时加载的部分,在首次布局文件加载时处于占位状况,当调用inflate或许setVisible时才会完结加载动作,一个一般的运用<ViewStub/>布局文件及其结构如下图所示:

面试串讲009-布局层级太多怎么优化?

当执行ViewStub.inflate之后,得到的布局结构如下图所示:

面试串讲009-布局层级太多怎么优化?

能够看出ViewStub区域被其对应的布局结构替换掉了。

结合上述比如,我们能够得出运用<ViewStub/>标签能够办理在页面首次初始化时不需要加载的布局,提高渲染速度,比及需要这部分UI时再进行加载

<include/>

<include/>标签能够将一些公共布局文件在多处重复引用,以便提高布局效率,例如各个页面都有的状况栏,当运用自定义布局完成后,则能够运用<include/>标签进行重复引用。

<include/>标签运用示例代码如下:

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent">
​
  <LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
​
    <include
      android:id="@+id/view_stub"
      layout="@layout/test"/>
​
    <com.poseidon.looperobserver.customview.CustomView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_gravity="center"
      android:id="@+id/custom_view"
      android:text="move me!" />
​
  </LinearLayout>
​
</merge>

运用<include/>标签得到的布局结构如下图所示:

面试串讲009-布局层级太多怎么优化?

能够看出从布局结构来讲并无显着差异,在初次加载就会直接构建在View树上。