1. 程式人生 > >android merge與include標籤混合使用

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中有效,對於使用程式碼定義的佈局不起作用。