布局标签一般和 标签一起使用从而减少布局的层级。例如当前布局是一个竖直方向的LinearLayout,这个时候如果被包含的布局也采用了竖直方向的LinearLayout,那么显然被包含的布局文件中的LinearLayout是多余的,这时通过 布局标签就可以去掉多余的那一层LinearLayout。如下所示:
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<LinearLayout xmlns:android="schemas.android.com/apk/res/and…"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
3.5 减少初次测量 & 绘制时间
3.5.1使用 标签
ViewStub继承了View,它非常轻量级且宽和高都为0,因此它本身不参与任何的绘制过程,避免资源的浪费,减少渲染时间,在需要的时候才加载View。因此ViewStub的意义在于按需求加载所需的布局,在实际开发中,很多布局在正常情况下不会显示,比如加载数据暂无数据,网络异常等界面,这个时候就没必要在整个界面初始化的时候将其加载进来,通过ViewStub就可以做到在使用时在加载,提高了程序初始化时的性能。如下一个ViewStub的示例:
<LinearLayout xmlns:android="schemas.android.com/apk/res/and…"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@mipmap/ic_empty_order"/>
<TextView
android:layout_below="@+id/iv_empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="暂无数据"/>
<LinearLayout xmlns:android="schemas.android.com/apk/res/and…"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
//view_stub是ViewStub的id,empty是empty_data.xml这个布局根元素的id
<ViewStub
android:id="@+id/view_stub"
android:inflatedId="@+id/empty"
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本身就能实现
<LinearLayout xmlns:android="schemas.android.com/apk/res/and…"
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"
/>
<shape xmlns:android="schemas.android.com/apk/res/and…"
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内容为:
标题:%1s\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绘制所需时间。
所选节点的每个子视图都有三个点,可以是绿色,黄色或红色。
-
左点表示渲染管道的绘制过程。
-
中间点代表布局阶段。
-
右点表示执行阶段。
这些点大致对应于处理管道的度量,布局和绘制阶段。点的颜色表示该节点相对于本地系列中所有其他配置节点的相对性能。
-
绿色 表示视图渲染速度比其他视图中的至少一半快。
-
黄色 表示视图呈现的速度比其他视图的下半部分快。
-
红色 表示视图是最慢的一半视图之一。
所测量的是每个节点相对于兄弟视图的性能,因此配置文件中始终存在红色节点,除非所有视图执行相同,并且它并不一定意味着红色节点执行得很差(仅限于它是最慢的视图)在本地视图组中)。
学习分享
在当下这个信息共享的时代,很多资源都可以在网络上找到,只取决于你愿不愿意找或是找的方法对不对了
很多朋友不是没有资料,大多都是有几十上百个G,但是杂乱无章,不知道怎么看从哪看起,甚至是看后就忘
如果大家觉得自己在网上找的资料非常杂乱、不成体系的话,我也分享一套给大家,比较系统,我平常自己也会经常研读。
2021最新上万页的大厂面试真题
七大模块学习资料:如NDK模块开发、Android框架体系架构…
只有系统,有方向的学习,才能在段时间内迅速提高自己的技术。
这份体系学习笔记,适应人群: **第一,**学习知识比较碎片化,没有合理的学习路线与进阶方向。 **第二,**开发几年,不知道如何进阶更进一步,比较迷茫。 **第三,**到了合适的年纪,后续不知道该如何发展,转型管理,还是加强技术研究。如果你有需要,我这里恰好有为什么,不来领取!说不定能改变你现在的状态呢!