一.核心思想
减少布局文件的层次
布局的层次少了,意味着Android绘制时的工作量少了,程序的性能自然就提高了。
二.方法
1.删除布局中无用的控件和层级
2.有选择的使用ViewGroup
3.采用<include>标签,<merge>标签,ViewStub
详解
1.删除布局中无用的控件和层级 不详解
2.有选择的使用ViewGroup
如果布局中既可以用
LinearLayout
也可以用RelativeLayout
,优先采用LinearLayout
。(RelativeLayout
功能比较复杂,布局过程需要花费更多的CPU时间;FrameLayout
和LinearLayout
一样都是一种简单高效的ViewGroup
)
3.采用<include>标签,<merge>标签,ViewStub
- <include>标签 将一个指定的布局文件加载到当前布局文件中
<?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:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello World!" />
<include
android:id="@+id/include"
layout="@layout/include_text"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
@layout/include_text指定了另一个布局,这种方式可以复用这个布局,比如常用的titlebar
注:
- <include>标签只支持android:id 跟 以android:layout_开头的属性
- <include>标签指定的属性同时被包含的布局文件也指定了,以<include>标签为准 (在被包含的布局文件设置的background,会以include和被包含的布局文件中设定的两者最小面积为准)
- <merge>标签一般与<include>标签一起使用,减少布局的层次
上例中,当前布局是一个竖直方向的LinearLayout,如果被包含的布局也采用了竖直方向的LinearLayout,那显然被包含的布局文件中的LinearLayout是多余的,通过<merge>标签可以去掉这层多余的LinearLayout
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:text="Hello World!"
/>
</merge>
- ViewStub继承自View,非常轻量,宽高都为0,因此不参与任何的布局和绘制过程。它的意义在于按需加载所需的布局文件。比如网络异常的页面,正常情况下不会显示,这时候没必要在初始化时就将其加载进来,用ViewStub将其在使用的时候加载,提高程序在初始化时的性能
<?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:orientation="vertical"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello World!"
/>
<include
android:id="@+id/include"
layout="@layout/include_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<ViewStub
android:id="@+id/view_stub"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inflatedId="@+id/ll_root"
android:layout="@layout/view_stub"
>
</ViewStub>
</LinearLayout>
android:layout="@layout/view_stub"其中@layout/view_stub为按需加载的布局,注意跟<include>标签中的 layout="@layout/include_text" 属性引用不一样
android:inflatedId="@+id/ll_root" 其中@+id/ll_root为按需加载布局文件中的根元素id
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:text="Hello World!"
/>
</LinearLayout>
如何按需加载?两种方式
findViewById(R.id.view_stub).setVisibility(View.VISIBLE);
或者
((ViewStub)findViewById(R.id.view_stub)).inflate();
当加载后,ViewStub就会被它内部的布局替换掉,这时候ViewStub就不再是整个布局结构中的一部分了。另 ViewStub不支持<merge>标签。
参考任玉刚的Android开发艺术探索
网友评论