優(yōu)化布局層次
Google建議View 的高度不應(yīng)超過(guò)10層曼库,避免嵌套過(guò)多。
盡量減少布局層級(jí)和復(fù)雜度
- 盡量不要嵌套使用RelativeLayout.
- 盡量不要在嵌套的LinearLayout中都使用weight屬性.
- Layout的選擇, 以盡量減少View樹(shù)的層級(jí)為主.
- 去除不必要的父布局.
- 善用TextView的Drawable減少布局層級(jí)
- 如果H Viewer查看層級(jí)超過(guò)5層, 你就需要考慮優(yōu)化下布局了~
善用Tag
<include>
<include>標(biāo)簽可以允許在一個(gè)布局當(dāng)中引入另外一個(gè)布局略板,那么比如說(shuō)我們程序的所有界面都有一個(gè)公共的部分,這個(gè)時(shí)候最好的做法就是將這個(gè)公共的部分提取到一個(gè)獨(dú)立的布局文件當(dāng)中慈缔,然后在每個(gè)界面的布局文件當(dāng)中來(lái)引用這個(gè)公共的布局叮称。
在<include>標(biāo)簽當(dāng)中,我們是可以覆寫(xiě)所有l(wèi)ayout屬性的藐鹤,即include中指定的layout屬性將會(huì)覆蓋掉原布局中指定的layout屬性瓤檐。
<?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" >
<include
android:layout_width="match_parent"
android:layout_height="wrap_content"
layout="@layout/titlebar" />
......
</LinearLayout>
<merge>
<merge>標(biāo)簽是作為<include>標(biāo)簽的一種輔助擴(kuò)展來(lái)使用的,它的主要作用是為了防止在引用布局文件時(shí)產(chǎn)生多余的布局嵌套娱节。大家都知道挠蛉,Android去解析和展示一個(gè)布局是需要消耗時(shí)間的,布局嵌套的越多肄满,那么解析起來(lái)就越耗時(shí)谴古,性能也就越差,因此我們?cè)诰帉?xiě)布局文件時(shí)應(yīng)該讓嵌套的層數(shù)越少越好稠歉。
一般<merge>會(huì)和<include>標(biāo)簽 配合使用掰担。
<ViewStub>
有的時(shí)候我們會(huì)遇到這樣的場(chǎng)景,就是某個(gè)布局當(dāng)中的元素非常多怒炸,但并不是所有元素都一起顯示出來(lái)的带饱,而是普通情況下只顯示部分常用的元素,而那些不常用的元素只有在用戶進(jìn)行特定操作的情況下才會(huì)顯示出來(lái)。
<?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" >
<EditText
android:id="@+id/edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="10dp"
android:hint="@string/edit_something_here" />
<Button
android:id="@+id/more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginRight="20dp"
android:layout_marginBottom="10dp"
android:text="More" />
<ViewStub
android:id="@+id/view_stub"
android:layout="@layout/profile_extra"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<include layout="@layout/ok_cancel_layout" />
</LinearLayout>
可以看到勺疼,這里我們新增了一個(gè)More Button教寂,這個(gè)按鈕就是用于去加載那些不常用的元素的,然后在Button的下面定義了一個(gè)ViewStub执庐。在ViewStub控件中酪耕,我們先是通過(guò)id屬性給它指定了一個(gè)唯一標(biāo)識(shí),又通過(guò)layout屬性將profile_extra布局傳入進(jìn)來(lái)耕肩,接著給ViewStub指定了一個(gè)寬高因妇。注意,雖然ViewStub是不占用任何空間的猿诸,但是每個(gè)布局都必須要指定layout_width和layout_height屬性婚被,否則運(yùn)行就會(huì)報(bào)錯(cuò)。
接著修改ProfileActivity中的代碼梳虽,在Activity中添加More Button的點(diǎn)擊事件址芯,并在點(diǎn)擊事件中進(jìn)行如下邏輯處理:
private EditText editExtra1;
private EditText editExtra2;
private EditText editExtra3;
public void onMoreClick() {
ViewStub viewStub = (ViewStub) findViewById(R.id.view_stub);
if (viewStub != null) {
View inflatedView = viewStub.inflate();
editExtra1 = (EditText) inflatedView.findViewById(R.id.edit_extra1);
editExtra2 = (EditText) inflatedView.findViewById(R.id.edit_extra2);
editExtra3 = (EditText) inflatedView.findViewById(R.id.edit_extra3);
}
}
當(dāng)點(diǎn)擊More Button之后我們首先會(huì)調(diào)用findViewById()方法將ViewStub的實(shí)例獲取到,拿到ViewStub的實(shí)例之后就很簡(jiǎn)單了窜觉,調(diào)用inflate()方法或者setVisibility(View.VISIBLE)都可以將隱藏的布局給加載出來(lái)谷炸,而加載的這個(gè)布局就是剛才在XML當(dāng)中配置的profile_extra布局。
調(diào)用inflate()方法之后會(huì)將加載出來(lái)的布局進(jìn)行返回禀挫,之后我們就可以對(duì)這個(gè)布局進(jìn)行任意的操作了旬陡,再次隱藏顯示,或者獲取子元素的實(shí)例等语婴。注意這里我對(duì)ViewStub的實(shí)例進(jìn)行了一個(gè)非空判斷描孟,這是因?yàn)閂iewStub在XML中定義的id只在一開(kāi)始有效,一旦ViewStub中指定的布局加載之后砰左,這個(gè)id也就失敗了匿醒,那么此時(shí)findViewById()得到的值也會(huì)是空。
另外需要提醒大家一點(diǎn)缠导,ViewStub所加載的布局是不可以使用<merge>標(biāo)簽的廉羔,因此這有可能導(dǎo)致加載出來(lái)的布局存在著多余的嵌套結(jié)構(gòu),具體如何去取舍就要根據(jù)各自的實(shí)際情況來(lái)決定了僻造,對(duì)于那些隱藏的布局文件結(jié)構(gòu)相當(dāng)復(fù)雜的情況憋他,使用ViewStub還是一種相當(dāng)不錯(cuò)的選擇的,即使增加了一層無(wú)用的布局結(jié)構(gòu)髓削,仍然還是利大于弊举瑰。