您好,登錄后才能下訂單哦!
include:
方便復雜布局的重用,使得布局模塊化。最常使用到的地方如在每個Activity中加入統一的狀態欄。
merge:
減少include之后的布局層級。
ViewStub:
提高布局初次加載性能。常用于網絡加載失敗頁,按需加載View等。
include、merge結合使用:
官方對<merge />的介紹中使用vertical的LinearLayout。當需要include的Layout也是vertical的LinearLayout時,會出現兩個vertical的LinearLayout相互嵌套的情況,這除了降低UI性能之外沒有其他作用。這時候可以把需要include的Layout的LinearLayout換成<merge />標簽。這樣在編譯完成后TextView和兩個Button就是同級的,不會再多一層。
注意:在include中如果需要重寫layout_xxx屬性,則必須同時重寫layout_width和Layout_height。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/app_bg"
android:gravity="center_horizontal">
<include layout="@layout/titlebar"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
android:padding="10dp" />
</LinearLayout>
需要include的layout:
這里的LinearLayout和TextView同一層級。兩個Button是其下一層子View。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal">
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/add"/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/delete"/>
</LinearLayout>
把root視圖LinearLayout換成merge:
這里兩個Button和TextView同一層級,LinearLayout在include后已經不存在了。
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/add"/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/delete"/>
</merge>
merge適用于哪些布局類型:
試驗后<merge />適用于我們常用的FrameLayout、LinearLayout、RelativeLayout等。但從官方的介紹中只見到FrameLayout和相同orientation的LinearLayout。因為這兩種情況下需要的include的View和原布局沒有耦合性,也就是沒關系。
而RelativeLayout使用<merge />需要知道兩者布局的情況,比如toRightof的對象是誰等,這反而增加了兩個布局之間的耦合性,而include的作用不就是解耦合么。故此,RelativeLayout不適用。
而如果只用到centerInParent、alignParentTop之類的RelativeLayout的屬性,面對這種低程度的耦合,merge似乎還行。但這時候通常可以考慮更優的方案了。
對于FrameLayout來說,無論嵌套多少層,顯示效果是一樣的,但UI性能更差,對于相同orientation的LinearLayout來說,嵌套多層,顯示效果也是一樣的,但UI性能也是更差。
The <merge /> tag helps eliminate redundant view groups in your view hierarchy when including one layout within another.
譯:merge標簽幫助消除在一個布局中include進另外一個布局后,造成的View層級中冗余的view groups。
為什么會造成冗余:
之所以會造成View層級的冗余嵌套,是因為系統規定了每一個獨立的布局文件都必須只有一個root view。而這個root view與內部的子View不一定存在必須的關系(例如,引用root view的id的情況),可能只是提供一個父布局讓子類的layout_width等layout_xxxxx屬性起作用而已。這個作用可以由include后的再上一層布局提供。這時root view就沒用了。
代碼中加載根標簽為merge的布局文件:
由于merge在加載后就不存在了。就好像岳父拉著女朋友的手交給你,他就走了。這個過程是在inflate中完成的。而merge在子view找到新parent后就安心離開,如果沒找到就不會放手,可憐×××。所以我們需要使用三個參數的inflate方法,在inflate的時候就指定新的parent,并attach。而root不需要再addView。
LayoutInflater.from(this).inflate(R.layout.titlebar, root, true);
不然會報錯:
<merge /> can be used only with a valid ViewGroup root and attachToRoot=true.
tools:showIn="@layout/activity_main"
在merge標簽中加入此屬性,方便在編輯時查看本Layout在布局activity_main中include完成后的模樣,所見即所得,方便修改。
ViewStub如何提高加載性能:
對于一般的View來說,只要在布局文件中聲明了,那么在加載布局文件的時候,該View就會被加載進內存。并非布局中所有的View在首次加載時都需要,可以把首次不需要的放在ViewStub中。
ViewStub是一個不可見的、寬高為0、draw方法為空的輕量級的View,用于在運行時再加載指定布局資源從而優化布局加載速度。只有當setVisibility(Visible/InVisible)或inflate()方法被調用,才會加載布局資源替換自身在父布局中的位置,并使用ViewStub的布局參數。
ViewStub和include的對比:
都是用于引入其他的布局,和直接在布局文件中寫入View相比,使用include的方式沒有性能上的優勢,反而可能降低性能。而使用ViewStub則能提高加載性能,例如,把一個復雜布局放在ViewStub中加載,則在該復雜布局不需要加載的時候,開銷變成了加載ViewStub的輕量開銷。
ViewStub注意:
1、ViewStub只能被加載一次,然后被inflate的layout所替換掉
2、不支持<merge />標簽
不要使用ViewStub的對象,使用inflate返回的布局對象:
if (inflatedView == null) {
ViewStub viewStub = findViewById(R.id.stub);
inflatedView = viewStub.inflate();
}
TextView text = inflatedView.findViewById(R.id.text);
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。