首页 > 代码库 > Android-性能优化之布局优化

Android-性能优化之布局优化

  系统在渲染UI界面的时候会消耗大量的资源,一个好的UI不仅仅应该具有良好的视觉效果,更应该具有良好的使用体验,因此布局优化就显得非常的重要。

1.Android UI渲染机制

  人眼所感觉到的流畅画面,需要画面的帧数达到40帧每秒到60帧每秒。在Android中,系统通过VSYNC信号触发对UI的渲染和重绘,其间隔时间是16ms。这个16ms其实就是1000ms中显示60帧的画面的单位时间,即1000/60。如果系统每次渲染的时间都保持在16ms之内,那么我们看到的UI界面是非常的流畅,但这也需要将所有的逻辑都保持在16ms之内。

2.优化布局层级

  在Android中,系统对View进行测量、布局和绘制时,都是通过对View树的遍历来进行操作的。如果一个View树的高度太高了,就会严重的影响测量、布局和绘制的速度,因此优化布局的第一个方法就是降低View树的高度,Google也在其API文档中建议View树的高度不宜超过10层。

  在早期的Android版本中,Google建议我们使用LinearLayout作为默认创建的XMl文件的跟布局,而现在的Android中,Google已经使用RelativeLayout来替代LinearLayout作为默认的跟布局,其原因就是通过扁平的RelativeLayour来降低通过对LinearLayout嵌套所产生跟布局树的高度,从而提高UI渲染的效率。

  (1)避免嵌套过多无用的布局

  嵌套的布局会让View树的高度变的越来越高,因此在布局时,需要根据自身布局的特点来选择不同的Layout组件,从而避免通过一种Layout组件来实现功能时局限性,从而造成嵌套过多的情况发生。

  (2)使用<include> 标签重用Layout

  在一个应用程序界面中为了风格上的统一,很多的界面都会存在你一些共同的UI,比如一个应用的TopBar、BottomBar等。对于这些共通的UI,如果在每一个界面都来复制一段这样的代码,不仅不利于后期代码的维护,更加的增加了程序的冗余度。因此,可以使用<include>标签来定义这样一个共同的UI。

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="0dp"
 4     android:layout_height="0dp"
 5     android:orientation="vertical">
 6 
 7     <TextView
 8         android:layout_width="match_parent"
 9         android:layout_height="match_parent"
10         android:gravity="center"
11         android:text="这是一个TextView"
12         android:textSize="20sp" />
13 </LinearLayout>

使用<include>标签对上面的XML代码进行重用

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical">
 6 
 7     <include
 8         layout="@layout/common"
 9         android:layout_width="match_parent"
10         android:layout_height="match_parent"></include>
11 </LinearLayout>

  (3)使用<ViewStub>标签实现View的延迟加载

  除了把一个View作为共同的UI,之外,我们还可以使用<ViewStub>标签来实现对一个View的引用并实现延迟加载。<ViewStub>标签是一个非常轻量级的组件。

  首先,创建一个布局,这个布局在初始化加载时不需要显示,只在某些情况下才显示出来,例如在查看用户信息时,只有点击某个按钮时,用户详细信息才显示出来。

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:gravity="center"
 6     android:orientation="vertical">
 7 
 8     <TextView
 9         android:layout_width="wrap_content"
10         android:layout_height="wrap_content"
11         android:gravity="center"
12         android:text="这是一个隐藏的TextView"
13         android:textSize="20sp" />
14 </LinearLayout>

接下来使用<ViewStub>标签对布局进行引用。

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical">
 6 
 7     <ViewStub
 8         android:id="@+id/id_viewStub"
 9         android:layout_width="match_parent"
10         android:layout_height="match_parent"
11         android:layout="@layout/common" />
12 
13     <LinearLayout
14         android:layout_width="match_parent"
15         android:layout_height="wrap_content"
16         android:layout_alignParentBottom="true"
17         android:orientation="horizontal">
18 
19         <Button
20             android:id="@+id/id_visible"
21             android:layout_width="0dp"
22             android:layout_height="match_parent"
23             android:layout_weight="1"
24             android:text="显示" />
25 
26         <Button
27             android:id="@+id/id_load"
28             android:layout_width="0dp"
29             android:layout_height="match_parent"
30             android:layout_weight="1"
31             android:text="加载" />
32     </LinearLayout>
33 </RelativeLayout>

  在这里不仅有一个疑问,<ViewStub>标签与设置VIew.GONE这种方式来隐藏一个View有什么区别?的确,他们的共同点都是初始化是不会显示,但是<ViewStub>标签只会在显示时,才去渲染整个布局,而View.GONE,在初始化布局树的时候就已经添加在布局树中,相比之下,<ViewStub>标签的布局具有更高的效率。

Android-性能优化之布局优化