FrameLayou和佈局優化

轉: http://android.blog.51cto.com/268543/308090

FrameLayout
     先來看官方文檔的定義:FrameLayout是最簡單的一個佈局對象。它被定製爲你屏幕上的一個空白備用區域,之後你可以在其中填充一個單一對象 — 比如,一張你要發佈的圖片。所有的子元素將會固定在屏幕的左上角;你不能爲FrameLayout中的一個子元素指定一個位置。後一個子元素將會直接在前一個子元素之上進行覆蓋填充,把它們部份或全部擋住(除非後一個子元素是透明的)。
     我的理解是,把FrameLayout當作畫布canvas,固定從屏幕的左上角開始填充圖片,文字等。看看示例,原來可以利用android:layout_gravity來設置位置的:
  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <FrameLayout 
  3.   xmlns:android="http://schemas.android.com/apk/res/android" 
  4.   android:layout_width="fill_parent" 
  5.   android:layout_height="fill_parent" > 
  6.  
  7.     <ImageView 
  8.         android:id="@+id/image" 
  9.         android:layout_width="fill_parent"  
  10.         android:layout_height="fill_parent" 
  11.         android:scaleType="center" 
  12.         android:src="@drawable/candle" 
  13.         /> 
  14.     <TextView 
  15.         android:id="@+id/text1" 
  16.         android:layout_width="wrap_content" 
  17.         android:layout_height="wrap_content" 
  18.         android:layout_gravity="center" 
  19.         android:textColor="#00ff00" 
  20.         android:text="@string/hello" 
  21.         /> 
  22.     <Button 
  23.         android:id="@+id/start" 
  24.         android:layout_width="wrap_content" 
  25.         android:layout_height="wrap_content" 
  26.         android:layout_gravity="bottom" 
  27.         android:text="Start" 
  28.         /> 
  29. </FrameLayout> 
效果圖

FrameLayout          hierarchyviewer       hierarchyviewer

佈局優化

     使用tools裏面的hierarchyviewer.bat來查看layout的層次。在啓動模擬器啓動所要分析的程序,再啓動hierarchyviewer.bat,選擇模擬器以及該程序,點擊“Load View Hierarchy”,就會開始分析。可以save as png。  
  
<merge> 減少視圖層級結構
     從上圖可以看到存在兩個FrameLayout,紅色框住的。如果能在layout文件中把FrameLayout聲明去掉就可以進一步優化佈局代碼了。 但是由於佈局代碼需要外層容器容納,如果
直接刪除FrameLayout則該文件就不是合法的佈局文件。這種情況下就可以使用<merge> 標籤了。
修改爲如下代碼就可以消除多餘的FrameLayout了:
  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <merge  xmlns:android="http://schemas.android.com/apk/res/android"> 
  3.     <ImageView 
  4.         android:id="@+id/image" 
  5.         android:layout_width="fill_parent"  
  6.         android:layout_height="fill_parent" 
  7.         android:scaleType="center" 
  8.         android:src="@drawable/candle" 
  9.         /> 
  10.     <TextView 
  11.         android:id="@+id/text1" 
  12.         android:layout_width="wrap_content" 
  13.         android:layout_height="wrap_content" 
  14.         android:layout_gravity="center" 
  15.         android:textColor="#00ff00" 
  16.         android:text="@string/hello" 
  17.         /> 
  18.     <Button 
  19.         android:id="@+id/start" 
  20.         android:layout_width="wrap_content" 
  21.         android:layout_height="wrap_content" 
  22.         android:layout_gravity="bottom" 
  23.         android:text="Start" 
  24.         /> 
  25. </merge> 
<merge>也有一些使用限制: 只能用於xml layout文件的根元素;在代碼中使用LayoutInflater.Inflater()一個以merge爲根元素的
佈局文件時候,需要使用View inflate (int resource, ViewGroup root, boolean attachToRoot)指定一個ViewGroup 作爲其容器,並且要設置attachToRoot 爲true。
 
<include> 重用layout代碼
     如果在某個佈局裏面需要用到另一個相同的佈局設計,可以通過<include> 標籤來重用layout代碼:
  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  3.     android:orientation="vertical" 
  4.     android:layout_width="fill_parent" 
  5.     android:layout_height="fill_parent"> 
  6.          
  7.     <include android:id="@+id/layout1" layout="@layout/relative" /> 
  8.     <include android:id="@+id/layout2" layout="@layout/relative" /> 
  9.     <include android:id="@+id/layout3" layout="@layout/relative" /> 
  10.  
  11. </LinearLayout> 
效果圖

include

     這裏要注意的是,"@layout/relative"不是引用Layout的id,而是引用res/layout/relative.xml,其內容是前面文章介紹RelativeLayout的佈局代碼。
    另外,通過<include>,除了可以覆寫id屬性值,還可以修改其他屬性值,例如android:layout_width,android:height等。
 
<viewstub> 延遲加載
 
    ViewStub 是一個不可見的,大小爲0的View,最佳用途就是實現View的延遲加載,在需要的時候再加載View,可Java中常見的性能優化方法延遲加載一樣。
 
     當調用ViewStub的setVisibility函數設置爲可見或則調用 inflate初始化該View的時候,ViewStub引用的資源開始初始化,然後引用的資源替代ViewStub自己的位置填充在ViewStub的 位置。因此在沒有調用setVisibility(int) 或則 inflate()函數之前 ViewStub一種存在組件樹層級結構中,但是由於ViewStub非常輕量級,這對性能影響非常小。 可以通過ViewStub的inflatedId屬性來重新定義引用的layout id。 例如:
  1. <ViewStub android:id="@+id/stub" 
  2.           android:inflatedId="@+id/subTree" 
  3.           android:layout="@layout/mySubTree" 
  4.           android:layout_width="120dip" 
  5.           android:layout_height="40dip" /> 
   上面定義的ViewStub ,可以通過id “stub”來找到,在初始化資源“mySubTree”後,stub從父組件中刪除,然後"mySubTree"替代stub的位置。初始資源"mySubTree"得到的組件可以通過inflatedId 指定的id "subTree"引用。 然後初始化後的資源被填充到一個120dip寬、40dip高的地方。 
 
    推薦使用下面的方式來初始化ViewStub:
  1. ViewStub stub = (ViewStub) findViewById(R.id.stub); 
  2. View inflated = stub.inflate(); 
    當調用inflate()函數的時候,ViewStub 被引用的資源替代,並且返回引用的view。 這樣程序可以直接得到引用的view而不用再次調用函數 findViewById()來查找了。
 
    ViewStub目前有個缺陷就是還不支持 <merge /> 標籤。
 
layoutopt (Layout Optimization工具)
    這工具可以分析所提供的Layout,並提供優化意見。在tools文件夾裏面可以找到layoutopt.bat。
    用法
    layoutopt  <list of xml files or directories>
    參數
    一個或多個的Layout xml文件,以空格間隔;或者多個Layout xml文件所在的文件夾路徑
    例子
    layoutopt  G:\StudyAndroid\UIDemo\res\layout\main.xml


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