1. 程式人生 > >抽象佈局——include、merge 、ViewStub

抽象佈局——include、merge 、ViewStub

   在佈局優化中,Androi的官方提到了這三種佈局<include />、<merge />、<ViewStub />,並介紹了這三種佈局各有的優勢,下面也是簡單說一下他們的優勢,以及怎麼使用,記下來權當做筆記。

1、佈局重用<include />

<include />標籤能夠重用佈局檔案,簡單的使用如下:

[html] view plain copy  print?在CODE上檢視程式碼片派生到我的程式碼片
  1. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  2.     android:orientation
    ="vertical"
  3.     android:layout_width=”match_parent”  
  4.     android:layout_height=”match_parent”  
  5.     android:background="@color/app_bg"
  6.     android:gravity="center_horizontal">
  7.     <includelayout="@layout/titlebar"/>
  8.     <TextViewandroid:layout_width=”match_parent”  
  9.               android:layout_height
    ="wrap_content"
  10.               android:text="@string/hello"
  11.               android:padding="10dp"/>
  12.     ...  
  13. </LinearLayout>

    1)<include />標籤可以使用單獨的layout屬性,這個也是必須使用的。

    2)可以使用其他屬性。<include />標籤若指定了ID屬性,而你的layout也定義了ID,則你的layoutID會被覆蓋,解決方案

    3)在include標籤中所有的都是有效的,前提是必須要寫layout_width

layout_height兩個屬性

    4)佈局中可以包含兩個相同的include標籤,引用時可以使用如下方法解決(參考):

[html] view plain copy  print?在CODE上檢視程式碼片派生到我的程式碼片
  1. View bookmarks_container_2 = findViewById(R.id.bookmarks_favourite);   
  2. bookmarks_container_2.findViewById(R.id.bookmarks_list);  

2、減少檢視層級<merge />

    <merge/>標籤在UI的結構優化中起著非常重要的作用,它可以刪減多餘的層級,優化UI。例如你的主佈局檔案是垂直佈局,引入了一個垂直佈局的include,這是如果include佈局使用的LinearLayout就沒意義了,使用的話反而減慢你的UI表現。這時可以使用<merge/>標籤優化。

[html] view plain copy  print?在CODE上檢視程式碼片派生到我的程式碼片
  1. <mergexmlns:android="http://schemas.android.com/apk/res/android">
  2.     <Button
  3.         android:layout_width="fill_parent"
  4.         android:layout_height="wrap_content"
  5.         android:text="@string/add"/>
  6.     <Button
  7.         android:layout_width="fill_parent"
  8.         android:layout_height="wrap_content"
  9.         android:text="@string/delete"/>
  10. </merge>

注意:當merge所在佈局用於getLayoutInflater().inflate(R.layout.merge_item, new LinearLayout(this), true);時,方法inflate()中引數root和attachToRoot必須賦值,且attachToRoot必須為true;

3、需要時使用<ViewStub />

   <ViewStub />標籤最大的優點是當你需要時才會載入,使用他並不會影響UI初始化時的效能。

  在開發應用程式的時候,經常會遇到這樣的情況,會在執行時動態根據條件來決定顯示哪個View或某個佈局。那麼最通常的想法就是把可能用到的View都寫在上面,先把它們的可見性都設為View.GONE,然後在程式碼中動態的更改它的可見性。這樣的做法的優點是邏輯簡單而且控制起來比較靈活。但是它的缺點就是,耗費資源。雖然把View的初始可見View.GONE但是在Inflate佈局的時候View仍然會被Inflate,也就是說仍然會建立物件,會被例項化,會被設定屬性。也就是說,會耗費記憶體等資源。

      推薦的做法是使用Android.view.ViewStub,ViewStub是一個輕量級的View,它一個看不見的,不佔佈局位置,佔用資源非常小的控制元件。可以為ViewStub指定一個佈局,在Inflate佈局的時候,只有ViewStub會被初始化,然後當ViewStub被設定為可見的時候,或是呼叫了ViewStub.inflate()的時候,ViewStub所向的佈局就會被Inflate和例項化,然後ViewStub的佈局屬性都會傳給它所指向的佈局。這樣,就可以使用ViewStub來方便的在執行時,要還是不要顯示某個佈局。

首先來說說ViewStub的一些特點:

         1. ViewStub只能Inflate一次,之後ViewStub物件會被置為空。按句話說,某個被ViewStub指定的佈局被Inflate後,就不會夠再通過ViewStub來控制它了。

         2. ViewStub只能用來Inflate一個佈局檔案,而不是某個具體的View,當然也可以把View寫在某個佈局檔案中。

     基於以上的特點,那麼可以考慮使用ViewStub的情況有:

         1. 在程式的執行期間,某個佈局在Inflate後,就不會有變化,除非重新啟動。

              因為ViewStub只能Inflate一次,之後會被置空,所以無法指望後面接著使用ViewStub來控制佈局。所以當需要在執行時不止一次的顯示和隱藏某個佈局,那麼ViewStub是做不到的。這時就只能使用View的可見性來控制了。

         2. 想要控制顯示與隱藏的是一個佈局檔案,而非某個View。

              因為設定給ViewStub的只能是某個佈局檔案的Id,所以無法讓它來控制某個View。

     所以,如果想要控制某個View(如Button或TextView)的顯示與隱藏,或者想要在執行時不斷的顯示與隱藏某個佈局或View,只能使用View的可見性來控制。

總之:ViewStub小控制元件佔用記憶體小,比View.GONE更節省記憶體資源,缺點是隻能對佈局進行單次inflate顯示操作,
        即只適合於需要佔用記憶體小,而在必要時顯示佈局的情況。

[html] view plain copy  print?在CODE上檢視程式碼片派生到我的程式碼片
  1. <ViewStub
  2.     android:id="@+id/stub_import"
  3.     android:layout="@layout/progress_overlay"
  4.     android:layout_width="fill_parent"
  5.     android:layout_height="wrap_content"
  6.     android:layout_gravity="bottom"/>

android:layout=“”這裡是要替換的佈局檔案,佈局中的屬性要在ViewStub中設定,如android:layout_marginLeft="5dip";android:background=""等屬性設定。

當你想載入佈局時,可以使用下面其中一種方法:

[java] view plain copy  print?在CODE上檢視程式碼片派生到我的程式碼片
  1. ((ViewStub) findViewById(R.id.stub_import)).setVisibility(View.VISIBLE);  
  2. // or
  3. View importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();  

當呼叫inflate()函式的時候,ViewStub被引用的資源替代,並且返回引用的view,

但是顯示設定用android:visibility="visible"則不起作用。另外ViewStub目前有個缺陷就是還不支援 <merge />標籤。