1. 程式人生 > >Android 佈局優化(merge使用)

Android 佈局優化(merge使用)

目的:減少佈局層數
效果:減少檢視樹中的節點個數,加快檢視的繪製,提高UI效能#

何時使用:

  1. 子檢視不需要指定任何針對父檢視的佈局屬性
  2. 假如需要在LinearLayout裡面嵌入一個佈局(或者檢視),而恰恰這個佈局(或者檢視)的根節點也是LinearLayout,這樣就多了一層沒有用的巢狀,無疑這樣只會拖慢程式速度。而這個時候如果我們使用merge根標籤就可以避免那樣的問題

子檢視不需要指定任何針對父檢視的佈局屬性:

<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" >
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="merge標籤使用" /> </RelativeLayout>

放到一個activity中展示,這個是一個很簡單的介面就是在介面上展示一個textview

public class MainActivity extends Activity {

     @Override
     protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
     }
}

這裡寫圖片描述

我們可以看到這裡是這樣一個關係 Framelayout-Relativelayout-Textview
但是我們根本沒有用到任何Relativelayout的特性,如果改為Linearlayout也是同樣道理
我們並沒有用到他們的特性,so我們可以把Framelayout,Relativelayout合併
這個時候merge就可以使用了

<merge 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" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="merge標籤使用" />

</merge>

這裡寫圖片描述

與之前相比 Framelayout-Relativelayout-Textview 變為了
Framelayout-Textview 少了一層Relativelayout

第二種情況 消除LinearLayout巢狀

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="activity.szgroup.wy.myactivity.MainActivity">

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:clickable="true"/>

    <include
        android:id="@+id/keji"
        layout="@layout/pic_include"

        />

</LinearLayout>

pic_include.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorAccent"
    >
    <TextView
        android:id="@+id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:text="@string/jsx"/>
    <ImageView
        android:id="@+id/pic"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/jinsixiong"
        />


</LinearLayout>

我們可以看到 activity_main 中用到了 pic_include
並且我們的activity_main和pic_include中都是是linearlayout垂直佈局
而且是LinearLayout巢狀LinearLayout這時候我們就可以用merge消除一層佈局
我們將pic_include.xml修改為

<?xml version="1.0" encoding="utf-8"?>
<merge
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="activity.szgroup.wy.myactivity.MainActivity">

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:clickable="true"/>

    <include
        android:id="@+id/keji"
        layout="@layout/pic_include"

        />

</merge>

也就是用一個Linearlayout實現了原本巢狀的頁面

注意事項

  1. merge必須放在佈局檔案的根節點上。
  2. merge並不是一個ViewGroup,也不是一個View,它相當於聲明瞭一些檢視,等待被新增。
  3. merge標籤被新增到A容器下,那麼merge下的所有檢視將被新增到A容器下。
  4. 因為merge標籤並不是View,所以在通過LayoutInflate.inflate方法渲染的時候, 第二個引數必須指定一個父容器,且第三個引數必須為true,也就是必須為merge下的檢視指定一個父親節點。
  5. 如果Activity的佈局檔案根節點是FrameLayout,可以替換為merge標籤,這樣,執行setContentView之後,會減少一層FrameLayout節點。
  6. 自定義View的時候,根節點如果需要設定成LinearLayout,建議讓自定義的View點建議設定成merge,然後自定義的View
  7. 因為merge不是View,所以對merge標籤設定的所有屬性都是無效的。

merge不是view

就比如說剛才說到的linearlayout 我們消除第二個linearlayout的時候,如果我們本身linearlayout有設定背景,我們只是將linearlayout修改為merge那麼是不會有背景效果的