Android基礎知識-佈局優化
在Android中介面繪製是比較費時的,尤其是巢狀比較複雜的介面,所以我們會用一些技巧來優化佈局。
Android提供了以下標籤或控制元件來供我們優化佈局:
1.<include>
這個標籤允許我們在當前佈局檔案中,引用另一個佈局檔案。
最常見的一個例子就是頁面頭佈局,我們經常會封裝一個統一樣式的佈局(比如包含標題,以及左右操作按鈕等),然後在需要的介面,使用<include>
引用即可。
這裡有一點需要注意:
在
<include>
標籤當中,我們可以覆寫所有layout屬性,即include中指定的layout屬性將會覆蓋掉所引用佈局中指定的layout屬性,同時我們想要在<include>
標籤當中覆寫layout屬性,必須要將layout_width和layout_height這兩個屬性也進行覆寫,否則覆寫效果將不會生效。
2.<merge>
<merge>
標籤主要是用來解決佈局巢狀的。因為巢狀越深,介面繪製所需時間越久。
舉個例子。假如我們當前Activity用的佈局檔案內容如下:
<?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="wrap_content" android:orientation="vertical" > <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="這是外邊的" /> </LinearLayout>
然後有一個外部layout檔案,裡邊兒有兩個按鈕,app所以介面都可以用到:
<?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="wrap_content" android:orientation="vertical" > <Button android:id="@+id/ok" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:text="OK" /> <Button android:id="@+id/cancel" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:layout_marginRight="20dp" android:layout_marginTop="10dp" android:text="Cancel" /> </LinearLayout>
我們當然可以直接使用<include>
來引用這個佈局,但是在繪製的時候,整個佈局層次是這樣的
FrameLayout
LinearLayout
Button
LinearLayout
Button
Button
可以看到,這裡第二個LinearLayout
是完全多餘的,因為它和第一個LinearLayout
設定的佈局方向都是垂直的,所以這時可以使用<merge>
標籤,這個標籤相當於把所引用佈局的內容直接放到當前佈局中,不會再次繪製它自己的根佈局。使用之後佈局層次如下:
FrameLayout
LinearLayout
Button
Button
Button
3.ViewStub
控制元件
ViewStub
是Android提供的一種非常輕量級的控制元件,它也是View的一種,但是它沒有大小,沒有繪製功能,也不參與佈局,資源消耗非常低,將它放置在佈局當中基本可以認為是完全不會影響效能的。
一般使用場景:佈局中某些View最初是隱藏的,觸發到某個條件後才會可見,這時候就可以使用ViewStub
來優化。
…
<Button
android:id="@+id/button"
android:text="show_view_stub"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<ViewStub
android:id="@+id/view_stub"
android:layout="@layout/profile_extra"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
...
比如這裡我們引用佈局檔案profile_extra
,當button被點選的時候,我們才真正將其加載出來:
public void onClick() {
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);
}
}
這裡呼叫viewStub.inflate()
或者viewStub.setVisibility()
都是可以的,其實點進去setVisibility
看下原始碼,如果沒有inflate
過,最終也是會呼叫到inflate
來完成載入的:
public void setVisibility(int visibility) {
if (mInflatedViewRef != null) {
View view = mInflatedViewRef.get();
if (view != null) {
view.setVisibility(visibility);
} else {
throw new IllegalStateException("setVisibility called on un-referenced view");
}
} else {
super.setVisibility(visibility);
if (visibility == VISIBLE || visibility == INVISIBLE) {
inflate();
}
}
}
以上就是常用的三種優化佈局方式,佈局太複雜的話載入著確實很難受。。。