android merge與include標籤混合使用
前面一篇部落格講了merge標籤的使用場景以及用法,這篇就講一下include的使用,但是include標籤說起來比較簡單,所以就結合起merge標籤
一起來講。
merge標籤之前說過了,所以就不說了。include標籤的作用在於使得佈局檔案變得可複用,比如你在不同的佈局檔案中要加入相同的按鈕或者
title時,那麼這時候就可以在另外一個佈局檔案中設定好這個按鈕或者title,然後使用include標籤將這個設定好的佈局檔案插入到要新增的佈局
檔案中,這樣就達到了佈局的可複用。
用一個例子說明:
我要在一個佈局檔案中新增兩個按鈕,那麼我可以在另外一個檔案中先定義好這個按鈕,然後使用include將這個檔案插入進去
<?xml version="1.0" encoding="utf-8"?> <Button xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="120dp" android:layout_height="match_parent" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_gravity="center_horizontal" android:id="@+id/test"> </Button>
按鈕xml檔案定義好了之後,接下來就是使用include標籤將這個xml佈局檔案插入到另一個佈局檔案中
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <include layout="@layout/save_cancel_bar_button" android:id="@+id/save" /> <include layout="@layout/save_cancel_bar_button" android:id="@+id/cancel" /> </LinearLayout>
定義好了之後就能夠根據id來獲取button控制元件了。
以上就是include的使用方法。
接下來我們就來講include標籤和merge標籤的結合使用
我們知道merge標籤是layout檔案的根元素,而include標籤的作用複用layout佈局檔案,那麼當include標籤的父layout和其包含的layout的佈局是
相同的,那麼就可以使用merge進行優化了。下面就通過例子來說明include和merge的混合使用。
定義一個Activity xml佈局檔案
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="52dp"
android:background="@drawable/title"
android:id="@+id/title">
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:textColor="#e8f3fb"
android:textSize="22sp"
android:text="設定"/>
</RelativeLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/title">
<include
layout="@layout/picture_scanner"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
</RelativeLayout>
效果圖如下:
從上面的xml檔案程式碼可以看出,他使用include標籤引用了一個佈局檔案picture_scanner
<?xml version="1.0" encoding="utf-8"?>
<merge
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:save_cancel_bar="http://schemas.android.com/apk/res/com.lonuery.merge"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/guide_map1"/>
<com.lonuery.merge.Save_Cancel_Bar
android:id="@+id/bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:paddingTop="8dip"
android:gravity="center_horizontal"
android:background="#AA000000"
save_cancel_bar:savebarlabel="df"
save_cancel_bar:cancelbarlabel="fd">
</com.lonuery.merge.Save_Cancel_Bar>
</merge>
然後在這個佈局檔案中定義好控制元件位置,然後我們可以通過hierarchyviewer來檢視其佈局節點構成
可以看到在include所引入的xml檔案中使用merge標籤時,ImageView和Save_Cancel_Bar和FrameLayout之間沒有間接節點,但是如果不使用merge
標籤呢,改成FrameLayout看下效果
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:save_cancel_bar="http://schemas.android.com/apk/res/com.lonuery.merge"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/guide_map1"/>
<com.lonuery.merge.Save_Cancel_Bar
android:id="@+id/bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:paddingTop="8dip"
android:gravity="center_horizontal"
android:background="#AA000000"
save_cancel_bar:savebarlabel="df"
save_cancel_bar:cancelbarlabel="fd">
</com.lonuery.merge.Save_Cancel_Bar>
</FrameLayout>
使用hierarchyviewer看下效果
我們可以看見ImageView和Save_Cancel_Bar在和之前哪一個FrameLayout之間多出了一個FrameLayout的節點,而且他是前面一個FrameLayout的唯
一子節點,所以這個FrameLayout是可以通過merge優化掉的。
這樣include和merge標籤的結合使用就講完了。通過上面hierarchyviewer的圖可以看出,這個圖還可以有優化的空間,因為Save_Cancel_Bar後面只有
一個唯一子節點LinearLayout,那麼這個LinearLayout是可以優化掉的。好我們就來看Save_Cancel_Bar自定義控制元件的佈局檔案
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:id="@+id/save"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_marginLeft="10dp"
android:layout_marginRight="5dp"/>
<Button
android:id="@+id/cancel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_marginLeft="5dp"
android:layout_marginRight="10dp"/>
</LinearLayout>
我們直接將LinearLayout替換為merge後會發現,在執行介面的佈局會變形,那麼我們在使用merge標籤後使得佈局不變形,看能不能夠達到優化的目的。
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
layout="@layout/save_cancel_bar_button"
android:id="@+id/save" />
<include
layout="@layout/save_cancel_bar_button"
android:id="@+id/cancel" />
</merge>
在這裡我又使用了一個include標籤,因為我發現這兩個button可以使用同一個佈局檔案
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="120dp"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_gravity="center_horizontal"
android:id="@+id/test">
</Button>
通過hierarchyviewer看下優化後的圖:
通過上面圖片我們可以看出,在Button和Save_Cancel_Bar直接的LinearLayout的節點被優化掉了。這樣這個佈局檔案就達到最優的效能了
在上面優化的過程中我總結了merge優化的幾個case:
1、merge的父佈局可以不和merge之前替換的佈局相同,也就是說,你使用merge替換掉了LinearLayout,然後將這個merge xml檔案放在
RelativeLayout中也行,只要佈局不變形,並不是你使用merge替換掉LinearLayout後,這個merge xml就必須放在LinearLayout佈局下。
2、假如merge標籤替換掉LinearLayout,然後將merge xml檔案放在FrameLayout中,那麼merge佈局檔案中的子控制元件所依賴的父佈局就是
FrameLayout這也是為什麼1中的情況會變形,因為merge xml中的控制元件的父佈局右LinearLayout 變成了RelativeLayout。
3、在自定義控制元件中,如我這個例子,Save_Cancel_Bar繼承了LinearLayout,那麼這個控制元件就相當於一個LinearLayout,那麼其佈局檔案
中的LinearLayout就是其一個子節點,那麼這個LinearLayout按照邏輯來說就可以優化掉,但是如果我使用merge標籤替換掉其佈局檔案中
的LinearLayout,這個佈局檔案會變形,可見merge標籤所導致佈局依賴只在xml中有效,對於使用程式碼定義的佈局不起作用。