android:layout=“@layout/empty_data”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
/>
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
//加载ViewStub中的布局的两种方式setVisibility或inflate
mViewStub.setVisibility(View.VISIBLE);
mViewStub.inflate();
}
使用ViewStub需注意:当ViewStub通过setVisibility或inflate方法加载后,ViewStub就会被它内部的布局替换掉,这个时候ViewStub就不再是布局结构中的的一部分。目前ViewStub中的layout还不支持使用 标签。
3.5.2尽可能少用布局属性 wrap_content
布局属性 wrap_content 会增加布局测量时计算成本,应尽可能少用
3.6 减少控件的使用(善用控件属性)
在绘制布局中,某些情况下我们可以省去部分控件的使用。下文介绍几种常见的情况:
3.6.1 TextView文字加图片

上图布局,通常想到的是一个相对布局里包含一个TextView和两个ImageView。事实上我们只需要一个TextView就可以实现
<TextView
android:layout_width=“match_parent”
android:layout_height=“50dp”
android:layout_marginTop=“20dp”
android:paddingLeft=“16dp”
android:paddingRight=“16dp”
android:gravity=“center_vertical”
android:drawableLeft=“@mipmap/icon_my_unlock” // 设置左边显示的icon
android:drawablePadding=“10dp” // 设置icon和文本的间距
android:drawableRight=“@mipmap/icon_right” // 设置右边显示的icon
android:text=“@string/account_unlock”
/>3.6.2 LinearLayout分割线

上图布局,通常是用高为1dp的View来显示,实际上LinearLayout本身就能实现
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”
android:layout_width=“match_parent”
android:layout_height=“match_parent”
android:divider=“@drawable/divider_line”
android:dividerPadding=“16dp”
android:showDividers=“middle”
android:orientation=“vertical”>
<TextView
android:layout_width=“match_parent”
android:layout_height=“50dp”
android:paddingLeft=“16dp”
android:paddingRight=“16dp”
android:gravity=“center_vertical”
android:drawableLeft=“@mipmap/icon_my_unlock”
android:drawablePadding=“10dp”
android:drawableRight=“@mipmap/icon_right”
android:background=“@color/color_FFFFFF”
android:text=“@string/account_unlock”
/>
<TextView
android:layout_width=“match_parent”
android:layout_height=“50dp”
android:paddingLeft=“16dp”
android:paddingRight=“16dp”
android:gravity=“center_vertical”
android:drawableLeft=“@mipmap/icon_my_unlock”
android:drawablePadding=“10dp”
android:drawableRight=“@mipmap/icon_right”
android:background=“@color/color_FFFFFF”
android:text=“@string/account_unlock”
/>
<TextView
android:layout_width=“match_parent”
android:layout_height=“50dp”
android:paddingLeft=“16dp”
android:paddingRight=“16dp”
android:gravity=“center_vertical”
android:drawableLeft=“@mipmap/icon_my_unlock”
android:drawablePadding=“10dp”
android:drawableRight=“@mipmap/icon_right”
android:background=“@color/color_FFFFFF”
android:text=“@string/account_unlock”
/>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android=“http://schemas.android.com/apk/res/android”
android:shape=“rectangle”>核心代码就是对LinearLayout设置divider
- divider 设置分割线样式,需注意不能简单只给个颜色值,比如#f00或者@color/xxx这样,drawable一定要是个有长、宽概念的drawable,当然你也可以直接一张图片当divider。
- dividerPadding 设置分割线两边的间距
- showDividers 设置分割线显示位置。其中middle控件之间显示;beginning第一个控件上面显示分割线;end最后一个控件下面显示分割线,none不显示分割线
3.6.3 TextView的行间距和占位符的使用

<TextView
android:id=“@+id/text”
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:lineSpacingExtra=“10dp”
android:text=“@string/test_text”
android:textSize=“20sp”
android:textColor=“@color/colorPrimary”/>通过lineSpacingExtra设置行间隔,test_text内容为:
标题:%1KaTeX parse error: Undefined control sequence: \n at position 2: s\̲n̲时间:%2s\n内容:%3$s
在MainActivity中的使用
mText.setText(String.format(getResources().getString(R.string.test_text), “测试”, “2018-8-9”,“测试测试”));占位符的使用方法:%n表示第n位要被替换的,

d表示整型占位符,$f表示浮点型占位符
4. 布局调优工具
在实际开发中哪怕注意了上述的优化方案,难免还是会出现布局性能的问题。这时我们可使用布局调优工具来分析问题。本文将介绍常用的几种工具。
4.1 Lint
Lint 是Android Studio 提供的 代码扫描分析工具,它可以帮助我们发现代码结构/质量问题,同时提供一些解决方案,而且这个过程不需要我们手写测试用例。 Lint 的使用路径: 工具栏 -> Analyze -> Inspect Code

默认是检查整个项目,我们可以点击 Custom scope 自定义检查范围
- Project Files:所有项目文件
- Project Production Files:项目的代码文件
- Project Test Files:项目的测试文件
- OpenFiles:当前打开的文件
- Module ‘app’:主要的 app 模块
- Current File:当前文件

当然你也可以选择特定的类进行检查点击下图红色箭头标识的地方

点击“+”号新增一个检查范围:
- Local:只能当前项目使用
- Shared:其他 Android Studio 项目也可以使用

选择Shared,默认按项目显示,检查的文件数为 0 。下图红色框中4个按钮表示要操作的类型
- Include:包括当前文件夹内的文件,但不包括他的子文件夹
- Include Recursively:包括当前文件夹以及它的子文件夹内所有的文件夹,递归添加
- Exclude:移除当前文件夹,不包括子文件夹
- Exclude Recursively:移除当前文件夹及所有子文件夹

我们左击想扫描的文件,点击右边对应的按钮。可以看到文件边色了,红框显示需扫描24个文件,点击OK→OK

稍等一会儿,会弹出 Inspection 对话框,显示检查结果。

Lint 的警告严重程度有以下几种:
- Unused Entry:没有使用的属性,灰色,很不起眼
- Typo:拼写错误,绿色波浪下划线,也不太起眼
- Server Problem:服务器错误?好像不是
- Info:注释文档,绿色,比较显眼
- Weak Warning:比较弱的警告,提示比较弱
- Warning:警告,略微显眼一点
- Error:错误,最显眼的一个

本文对Lint的介绍就到此如果对Lint想了解更多的小伙伴可以点击Lint
4.2 Hierarchy Viewer
Hierarchy Viewer 是Android Studio 提供的UI性能检测工具。可获得UI布局设计结构 & 各种属性信息,帮助我们优化布局设计 。
使用Hierarchy Viewer ,您的设备必须运行Android 4.1或更高版本。如果您是使用真机的话需注意以下两点:
- 在您的设备上启用开发者选项。
- 在开发计算机上设置环境变量 ANDROID_HVPROTO=ddm 。
此变量告诉Hierarchy Viewer使用ddm 协议连接到设备,该协议与DDMS协议相同。需要注意的是,主机上只能有一个连接到设备的进程,因此您必须终止任何其他DDMS会话才能运行Hierarchy Viewer。
Hierarchy Viewer 的使用路径: 工具栏 ->Tools->Android->Android Device Monitor(默认是显示DDMS窗口,更改可点击Open Perspective->Hierarchy Viewer,也可以直接点击 Hierarchy Viewer Button),如下图所示:

更改后显示Hierarchy Viewer的窗口如下图所示:

如果您看的的视图排列不一样,可选择 Window->Reset Perspective 返回默认布局。下面介绍下基本窗口:
- Window(左上角)显示设备信息,app以包名显示,双击选中。
- View Properties(左上角)显示视图的属性
- Tree View(中心):显示视图层次结构的树视图。您可以使用鼠标拖动树和缩放树,并在底部使用缩放控件。每个节点都指示它的View类名和ID名称。
- Tree Overview(右上角):使您可以鸟瞰应用程序的完整视图层次结构。移动灰色矩形以更改树视图中可见的视口。
- Layout View(右下角):显示布局的线框视图。当前所选视图的轮廓为红色,其父视图为浅红色。单击此处的视图也会在树视图中选择它,反之亦然。[图片上传失败…(image-85c4d7-1602740598908)]

上图图标的使用左到右介绍:
- 重新加载视图层次结构
- 该视图弹窗
- 使布局无效
- 请求布局
- 重新加载视图层次结构
- 分析视图,显示视图的耗时

所选的节点上方会有个小窗口显示子View数和Measure,Layout,Draw绘制所需时间。
所选节点的每个子视图都有三个点,可以是绿色,黄色或红色。
- 左点表示渲染管道的绘制过程。
- 中间点代表布局阶段。
- 右点表示执行阶段。
这些点大致对应于处理管道的度量,布局和绘制阶段。点的颜色表示该节点相对于本地系列中所有其他配置节点的相对性能。
- 绿色 表示视图渲染速度比其他视图中的至少一半快。
- 黄色 表示视图呈现的速度比其他视图的下半部分快。
- 红色 表示视图是最慢的一半视图之一。
所测量的是每个节点相对于兄弟视图的性能,因此配置文件中始终存在红色节点,除非所有视图执行相同,并且它并不一定意味着红色节点执行得很差(仅限于它是最慢的视图)在本地视图组中)。
本文对Hierarchy Viewer的介绍就到此了,想了解更多的小伙伴可以点击Hierarchy Viewer
4.3 开发者选项(调试GPU过度绘制)
开发者选项是Android 系统为开发者提供的一个APP验证、调试、优化等各种功能的入口(需Android 4.1以上)。本文主要对GPU过度绘制菜单介绍,对其他菜单功能有兴趣的小伙伴可以参考探索Android手机开发者选项
GPU过度绘制是指在屏幕上某个像素在同一帧的时间内被绘制多次,产生的主要原因有两个:
- 在XML布局中,控件有重叠却都设置背景
- View的OnDraw中同一区域绘制多次
4.3.1 开启开发者选项
不同手机开发商都对手机界面做了定制化处理,打开手机开发者选项的方式各不相同,但基本的功能菜单都是类似的。由于笔者现在用的是小米5s Plus,因此打开方式是设置->我的设备->全部参数->连续点击MIUI版本,提示开发者模式开启即可(不同MIUI版本开启路径也不一样)。然后设置->更多设置,高级设置或者其他设置等等菜单中即可看到开发者选项的菜单了。
4.3.2 开启GPU过度绘制
在开发者选项中点击调试GPU过度绘制,如下图所示


这时屏幕会出现各种颜色,每种颜色的定义为:
- 原色: 没有过度绘制 – 每个像素在屏幕上绘制了一次。
















