Android Layout標籤之 - viewStub,requestFocus,merge,include

XML中定義AndroidLayout時,有四個比較特別的標籤是非常重要的,分別是<viewStub/>, <requestFocus />, <merge /> <include />,其中有三個是與資源複用有關。
1<ViewStub />標籤
ViewStub
是一個不可見的,大小爲0View,最佳用途就是實現View的延遲加載,在需要的時候再加載View,和Java中常見的性能優化方法延遲加載一樣。當調用ViewStubsetVisibility函數設置爲可見或則調用inflate()方法初始化該View的時候,ViewStub引用的資源開始初始化,然後引用的資源會替代掉ViewStub,把自己填充在ViewStub的原位置。因此在沒有調用setVisibility(int)inflate()方法之前ViewStub會一直存在組件樹層級結構中,但是由於ViewStub非常輕量級,這對性能影響非常小。可以通過ViewStubinflatedId屬性來重新定義引用的layoutid也就是說,加入我們所引用的layoutidR.layout.prelayout,然後我們在ViewStub中添加屬性android:inflatedId="@+id/subLayout“,那麼我們就可以用R.layout.subLayout來引用這個layout)。

示例:
            <ViewStub android:id="@+id/stub"
            android:inflatedId="@+id/subLayout"
            android:layout="@layout/preLayout"
            android:layout_width="120dip"
            android:layout_height="40dip" />

上面定義的ViewStub我們可以通過findViewById(R.id.stub)來找到,在初始化資源preLayout後,ViewStub從父組件中刪除,然後preLayout替代ViewStub的位置。初始資源preLayout得到的組件可以通過inflatedId 指定的id "subLayout"引用。 然後初始化後的資源被填充到一個120dip寬、40dip高的地方。

推薦使用下面的方式來初始化ViewStub
 
     ViewStub stub = (ViewStub) findViewById(R.id.stub);
     View inflated = stub.inflate();
 
當調用inflate()函數的時候,ViewStub被引用的資源替代,並且返回引用的view 這樣程序可以直接得到引用的view而不用再次調用函數findViewById()來查找了。
ViewStub目前有個缺陷就是還不支持 <merge /> 標籤。

2<include />標籤
可以通過這個標籤直接加載外部的xml到當前結構中,是複用UI資源的常用標籤。
用法:將需要複用xml文件路徑賦予include標籤的Layout屬性。

            <include android:id="@+id/cell1" layout="@layout/ar01" />
            <include android:layout_width="fill_parent" layout="@layout/ar01" />
注:
1.include
標籤只有layout屬性是必須的<include layout="@layout/layout_ID"/>
2.include
標籤若指定了ID屬性,而你的layout也定義了ID,則你的layoutID會被覆蓋
<include android:id="@+id/your_ID" layout="@layout/layout_ID"/>
3.
include標籤中所有的android:layout_*都是有效的。但前提是必須要寫layout_widthlayout_height兩個屬性,否則無效

3<requestFocus />標籤
標籤用於指定屏幕內的焦點View
用法: 將標籤置於Views標籤內部

            <EditText id="@+id/text"
                         android:layout_width="fill_parent"
                         android:layout_height="wrap_content"
                         android:layout_weight="0"
                         android:paddingBottom="4">
                   <requestFocus />
            </EditText>

4<merge />標籤
它在優化UI結構時起到很重要的作用,目的是通過刪減多餘或者額外的層級,從而優化整個AndroidLayout結構。
示例:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent">
    <ImageView android:layout_width="fill_parent"
        android:layout_height="fill_parent" android:scaleType="center"
        android:src="http://ygc87.blog.163.com/blog/@drawable/icon" />
    <TextView android:layout_width="wrap_content"
        android:layout_height="wrap_content" android:layout_marginBottom="20dip"
        android:layout_gravity="center_horizontal|bottom" android:padding="12dip"
        android:background="#AA000000" android:textColor="#ffffffff"
        android:text="Golden Gate" />
</FrameLayout>
運行上邊的layout,然後啓動 tools> hierarchyviewer.bat工具查看當前UI結構視圖:

android的layout定義時常用的標籤 - ygc87 - 我的博客

 我們可以很明顯的看到出現了兩個framelayout節點,這兩個意義完全相同的節點造成了資源浪費(這裏可以提醒大家在開發工程中可以習慣性的通過hierarchyViewer查看當前UI資源的分配情況),那麼如何才能解決這種問題呢(就當前例子是如何去掉多餘的frameLayout節點),這時候就要用到<merge />標籤來處理類似的問題了。我們將上邊xml代碼中的FrameLayout替換成merge
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent">
    <ImageView android:layout_width="fill_parent"
        android:layout_height="fill_parent" android:scaleType="center"
        android:src="http://ygc87.blog.163.com/blog/@drawable/icon" />
    <TextView android:layout_width="wrap_content"
        android:layout_height="wrap_content" android:layout_marginBottom="20dip"
        android:layout_gravity="center_horizontal|bottom" android:padding="12dip"
        android:background="#AA000000" android:textColor="#ffffffff"
        android:text="Golden Gate" />
</merge>
運行程序後在Emulator中顯示的效果是一樣的,可是通過hierarchyviewer查看的UI結構是有變化的,當初多餘的 FrameLayout節點被合併在一起了,或者可以理解爲將merge標籤中的子集直接加到ActivityFrameLayout跟節點下(這裏需要提醒大家注意:所有的Activity視圖的根節點都是FrameLayout)。如果你所創建的Layout並不是用FrameLayout作爲根節點(而是應用LinerLayout等定義root標籤),就不能應用上邊的例子通過merge來優化UI結構。

android的layout定義時常用的標籤 - ygc87 - 我的博客

 
    * <merge />
只可以作爲layout的根節點。
    *
當需要擴充的layout本身是由merge作爲根節點的話,需要將被導入的layout置於viewGroup中,同時需要設置attachToRoottrue

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章