android layout include merge,Android 布局优化之include与merge
Android 官方提供了三個用來優化布局的標簽,分別是include、merge與ViewStub,其中ViewStub是動態加載視圖到內存,大家可以查閱:Android UI布局優化之ViewStub
一、include布局重用:
在Android的應用程序開發中,標題欄是必不可少的一個元素,大部分頁面都要用到,而且布局都是一樣的,這時候使用include標簽就顯得極其的方便。使用時通常需要注意以下幾點。
include標簽的layout_*屬性會替換掉被include視圖的根節點的對應屬性。
include標簽的id屬性會替換掉被include視圖的根節點id
一個布局文件中支持include多個視圖,但是這樣會導致獲取被include視圖內的控件時,
解決方法請參考:www.coboltforge.com/2012/05/tech-stuff-layout/
下面例子中,titlebar_layout.xml為標題欄布局,而activity_main.xml為主界面布局,activity_setting.xml為設置頁面布局,這這兩個界面中都include了titlebar_layout.xml視圖。
titlebar_layout.xml:
titlebar_layout.xml
android:id="@+id/preference_activity_title_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="2dip"
android:background="@drawable/zns_activity_title_bg">
android:id="@+id/preference_activity_title_text"
android:layout_width="match_parent"
android:layout_height="45dip"
android:gravity="center"
android:text="123"
android:textColor="#ffffff"
android:textSize="18sp" />
android:id="@+id/preference_activity_title_image"
android:layout_width="30dip"
android:layout_height="25dip"
android:layout_gravity="center_vertical"
android:scaleType="fitCenter"
android:layout_marginLeft="5dip"
android:src="@drawable/common_menu_selector_white" />
主界面:
主界面
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#000000">
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="這是內容區域"
android:gravity="center"
android:textSize="25sp"
android:textColor="#ffffff"/>
當然,其他界面使用include同樣能包含該標題欄。
一、通過merge減少視圖節點:
merge翻譯成中文是合并的意思,在Android中通過使用merge能夠減少視圖的節點數,
從而減少視圖在繪制過程消耗的時間,達到提高UI性能的效果。使用merge時通常需要注意以下幾點:
merge必須放在布局文件的根節點上。
merge并不是一個ViewGroup,也不是一個View,它相當于聲明了一些視圖,等待被添加。
merge標簽被添加到A容器下,那么merge下的所有視圖將被添加到A容器下。
因為merge標簽并不是View,所以在通過LayoutInflate.inflate方法渲染的時候, 第二個參數必須指定一個父容器,且第三個參數必須為true,也就是必須為merge下的視圖指定一個父親節點。
如果Activity的布局文件根節點是FrameLayout,可以替換為merge標簽,這樣,執行setContentView之后,會減少一層FrameLayout節點。
自定義View如果繼承LinearLayout,建議讓自定義View的布局文件根節點設置成merge,這樣能少一層結點。
因為merge不是View,所以對merge標簽設置的所有屬性都是無效的。
其中第一點,我們看看LayoutInflate類的源碼說明:
} else if (TAG_MERGE.equals(name)) {
// 如果merge不是根節點,報錯
throw new InflateException(" must be the root element");
}
其中第三點,常用在自定義View中遇到,附上系統LayoutInflate類,對于該現象的源碼:
if (TAG_MERGE.equals(name)) {
// 如果是merge標簽,指定的root為空,或則attachToRoot為false,則拋出異常信息
if (root == null || !attachToRoot) {
throw new InflateException(" can be used only with a valid "
+ "ViewGroup root and attachToRoot=true");
}
rInflate(parser, root, attrs, false, false);
}
針對第五點,做一下對比:
布局文件1:
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:text="頂部Button" />
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="底部Button" />
效果1:
效果一
布局文件2:
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:text="頂部Button" />
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="底部Button" />
效果2:
效果二
我們可以看到,如果使用merge,明顯少了一個FrameLayout節點,這也算一個視圖優化技巧。
下面對第六條(自定義View如果繼承LinearLayout,建議讓自定義View的布局文件根節點設置成merge,這樣能少一層結點)進行分析:
先看看效果,就是一個線性布局,上下各一個TextView,看看使用merge和不使用merge的視圖節點,
以及使用merge的時候layoutInflate類的注意點。
效果圖:
效果圖
第一種情況(不使用merge):
布局文件:
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:background="#000000"
android:gravity="center"
android:text="第一個TextView"
android:textColor="#ffffff" />
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:background="#ffffff"
android:gravity="center"
android:text="第一個TextView"
android:textColor="#000000" />
代碼:
/**
* 自定義的View,豎直方向的LinearLayout
*/
public class MergeLayout extends LinearLayout {
public MergeLayout(Context context) {
super(context);
LayoutInflater.from(context).inflate(R.layout.merge_activity, this, true);
}
}
視圖樹:
視圖樹一
我們發現,MergeLayout這個自定義控件的下面并不是直接跟著兩個TextView,
而是多了一個LinearLayout。
第二種情況(使用merge):
注意因為為merge標簽的設置的屬性都不會生效,所以原來LinearLayout標簽上的屬性需要轉移到java代碼中設置。
布局文件:
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:background="#000000"
android:gravity="center"
android:text="第一個TextView"
android:textColor="#ffffff" />
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:background="#ffffff"
android:gravity="center"
android:text="第一個TextView"
android:textColor="#000000" />
個人習慣在用merge的時候在旁邊標明使用到的屬性,以防忘記。
java代碼中需要設置orientation屬性:
/**
* 自定義的View,豎直方向的LinearLayout
*/
public class MergeLayout extends LinearLayout {
public MergeLayout(Context context) {
super(context);
// 設置為數值方向的布局
setOrientation(VERTICAL);
LayoutInflater.from(context).inflate(R.layout.merge_activity, this, true);
}
}
再看看視圖樹:
視圖樹二
我們發現,LinearLayout節點被去掉了。但是最終顯示給用戶的界面卻是一樣的。
總結
1. 使用include標簽可以增加布局的復用性,提高效率。
2. 使用merge標簽可以減少視圖樹中的節點個數,加快視圖的繪制,提高UI性能。
3. merge標簽的使用,看上去一次只減少一個節點,但是當一個布局嵌套很復雜的時候,
節點的個數可能達到幾百個,這個時候,如果每個地方都多一個節點,視圖的繪制時間相應的也就變長了很多。
UI性能的優化還有另外一個比較重要的知識點ViewStub,它是一個View,但是它幾乎不占用資源,
使用ViewStub能夠加快視圖的繪制,提高性能,關于ViewStub的知識,大家可以參看博文:
Android UI布局優化之ViewStub
總結
以上是生活随笔為你收集整理的android layout include merge,Android 布局优化之include与merge的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 4dda在linux中的意思,Evvai
- 下一篇: android 刷系统,安卓10的刷机教