Android性能优化(四)布局优化

在进行Android应用的界面编写时,如果创建的布局层次结构比较复杂,View树潜逃的层次比较深,那么将会使得页面展现的时间比较长,导致应用允许起来越来越慢,Android布局的优化是实现应用响应灵敏的基础,遵循一些通用的编码准则则有利于实现这个

include标签共享布局


在使用XML文件编写Android应用的界面布局时,经常会遇到在不同的页面中需要实现相同的布局,这时候就会写出重复的代码,例如,由于几乎每个页面都有标题栏,因此,在每个页面都要是实现标题栏的XML代码,这种方式显然是不建议的,最佳实践是将通用的布局抽取出来,独立成一个XML文件,然后再需要用到的页面中使用include 标签引入进来,不仅减少了代码量,而且在需要修改标题栏的时候,只需修改这个独立的文件,而不是到每个页面中进行重复的修改劳动,假设我们抽取出来的标题栏布局名为layout_common_title.xml:

Android性能优化(四)布局优化_第1张图片

在页面MainActivity的布局中,使用到这个标题栏,引入的方式如下:

Android性能优化(四)布局优化_第2张图片

ViewStub标签实现延迟加载


ViewStub是一种不可视并且大小为0的视图,它可以延迟到运行时才填充(inflate)布局资源。当ViewStub设置为可见或者被inflate之后,就会填充布局资源,之后这个ViewStub就会被填充的视图所替代,跟普通的视图不在有任何区别,ViewStub的使用场景在于某个页面需要根据用户交互或者其他条件动态调整显示的视图,例如某个页面是从服务端获取数据进行展现的,正常情况下会展示获取到的数据,但在网络不可用的情况下,需要展示一张不可用的图片和相关提示信息,大多数情况下,这个不可用的视图是不需要显示出来的,如果不使用ViewStub,只是把不可用视图隐藏,那么它还是会被inflate并占用资源,如果使用ViewStub,则可以在需要显示的时候才会进行视图的填充,从而实现延迟加载的目的,假设页面加载数据失败时会展示一张网络出错的图片,这个图片的布局如下所示,它就是我们的ViewStub会显示的视图

Android性能优化(四)布局优化_第3张图片

页面使用ViewStub加载这个布局的代码如下

Android性能优化(四)布局优化_第4张图片

其中的android:inflateId的值是在Java代码种调用ViewStub的inflate()或者setVisibility()方法时返回的ID,这个ID就是被填充的View的ID。

merge标签减少布局层次


merge 标签在某些场景下可以用来减少布局的层次,由于Activity的ContentView的最外层容器是一个FrameLayout,因此,当一个独立的布局文件最外层是FrameLayout,且这个布局不需要设置背景android:background或者android:padding等属性时,可以使用标签来代替标签,从而减少一层多余的FrameLayout布局,另外一个可以使用标签的情况是当前布局作为另外一个布局的子布局,使用标签引用时,我们使用前面include,可以考虑把layout_common_title.xml文件中的RelativeLayout替换成merge

Android性能优化(四)布局优化_第5张图片

尽量使用CompoundDrawable


在LinearLayout布局中,如果存在相邻的ImageView和TextView,语句如下:

Android性能优化(四)布局优化_第6张图片

那么一般来说可以使用compound drawable 合二为一成为一个TextView,ImageView中的图片变成TextView的如下属性之一:drawableTop,drawableLeft,drawableRight或者drawableBottom。原来两个View之间的间隔使用TextView的属性drawablePadding来代替

Android性能优化(四)布局优化_第7张图片

使用Lint


Android Lint除了可以对Java代码进行静态检查之外,也可以用来检查应用的布局是否存在可优化的地方。Lint的如下规则是专门为优化布局设置的:

1 AndroidLintUseCompoundDrawable:就是前面介绍的尽量使用CompoundDrawable

2 MergeRootFrame:就是前面介绍的merge标签减少布局层次

3 TooManyViews:单个布局中存在太多的View,默认情况下,单个布局中的View的个数最多只能是80个,可以考虑使用CompoundDrawables等来减少View的个数

4 TooDeepLayout:避免过深的布局嵌套,默认情况下,单个布局中最多层次是10,可以考虑使用RelativeLayout来减少布局的层次

5 UseLessParent:当一个布局满足以下条件时,可以将它移除掉,并将它的子View移动到它的父容器中,已得到更扁平的布局层次:这个布局中只有一个子View,也就是子View不存在小兄弟View,这个布局不是一个ScrollView或者根布局,这个布局没有设置背景android:background

6 NestedWeights: android:layout_weight属性会使得View控件被测量两次,当一个LinearLayout拥有非0dp值得android:layout_widget属性,这时如果将它嵌套在另一个拥有非0dp得android:layout_weight得LinearLayout,那么这时测量的次数将呈值数级别增加

7 UselessLeaf:一个布局如果既没有子View也没有设置背景,那么它将是不可见的,通常可以移除它,这样可以得到更扁平和高效的布局层次

8 InefficientWeight:当LinearLayout中只有一个子View定义了android:layout_weight属性,更高性能的做法是使用0dp的android:layout_height或者android:layout_width来替换它,这样这个子View就不需要测量它自身对应的大小

你可能感兴趣的:(Android性能优化(四)布局优化)