天天看點

android 優化布局的三種形式

這幾天看了一些優化布局的材料,感覺,使用 include merge ViewStub會很好的增強代碼的可讀性,和觀賞性,很大程度的優化了我們自己的布局,下面我寫一些自己學到的東西,大家一起學習!

1.首先是include,

在官網上,

The 

<include />

 does exactly what its name suggests; it includes another XML layout. Using this tag is straightforward as shown in the following example, taken straight from the source code of the Home application that currently ships with Android:

<com.android.launcher.Workspace
    android:id="@+id/workspace"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"

    launcher:defaultScreen="1">

    <include android:id="@+id/cell1" layout="@layout/workspace_screen" />
    <include android:id="@+id/cell2" layout="@layout/workspace_screen" />
    <include android:id="@+id/cell3" layout="@layout/workspace_screen" />

</com.android.launcher.Workspace>      
include裡面包含一些其他的布局檔案xml,這隻需要以上面的形式寫出就可以友善的調用,同時,像例子中的那樣可以重複利用一個xml代碼,要注意幾點:      
1.The above example shows that you can use          android:id                 to specify the id of the root view of the included layout; it will also override the id of the included layout if one is defined.如果在workspace_screen布局裡面已經有id,而include裡面又重新定義了這個id,則會覆寫原來的id      
2.This means that any          android:layout_*                 attribute can be used with the          <include />                 tag.可以使用layout_*的任何屬性
       
2.merge的用法:      
<merge/>标簽在UI的結構優化中起着非常重要的作用,它可以删減多餘的層級,優化UI。merge多用于替換FrameLayout或者當一個布局包含另一個時,merge标簽消除視圖層次結構中多餘的視圖組。例如你的主布局檔案是垂直布局,引入了一個垂直布局的include,這是如果include布局使用的LinearLayout就沒意義了,      
That's where the          <merge />                 tag comes in handy. When the LayoutInflater encounters this tag, it skips it and adds the         <merge />                 children to the          <merge />                 parent. Confused? Let's rewrite our previous XML layout by replacing the         FrameLayout                 with          <merge />                :
       
<merge xmlns:android="http://schemas.android.com/apk/res/android">

    <ImageView  
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
    
        android:scaleType="center"
        android:src="@drawable/golden_gate" />
    
    <TextView
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_marginBottom="20dip"
        android:layout_gravity="center_horizontal|bottom"

        android:padding="12dip"
        
        android:background="#AA000000"
        android:textColor="#ffffffff"
        
        android:text="Golden Gate" />

</merge>      
<merge
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:okCancelBar="http://schemas.android.com/apk/res/com.example.android.merge">

    <ImageView  
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
    
        android:scaleType="center"
        android:src="@drawable/golden_gate" />
    
    <com.example.android.merge.OkCancelBar
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:layout_gravity="bottom"

        android:paddingTop="8dip"
        android:gravity="center_horizontal"
        
        android:background="#AA000000"
        
        okCancelBar:okLabel="Save"
        okCancelBar:cancelLabel="Don't save" />

</merge>      
This new layout produces the following result on a device:
android 優化布局的三種形式
The source code of  OkCancelBar  is very simple because the two buttons are defined in an external XML file, loaded using a LayoutInflate . As you can see in the following snippet, the XML layout  R.layout.okcancelbar  is inflated with the OkCancelBar  as the parent: 自定義view,
public class OkCancelBar extends LinearLayout {
    public OkCancelBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        setOrientation(HORIZONTAL);
        setGravity(Gravity.CENTER);
        setWeightSum(1.0f);
        
        LayoutInflater.from(context).inflate(R.layout.okcancelbar, this, true);
        
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.OkCancelBar, 0, 0);
        
        String text = array.getString(R.styleable.OkCancelBar_okLabel);
        if (text == null) text = "Ok";
        ((Button) findViewById(R.id.okcancelbar_ok)).setText(text);
        
        text = array.getString(R.styleable.OkCancelBar_cancelLabel);
        if (text == null) text = "Cancel";
        ((Button) findViewById(R.id.okcancelbar_cancel)).setText(text);
        
        array.recycle();
    }
}      
The two buttons are defined in the following XML layout. As you can see, we use the  <merge />  tag to add the two buttons directly to the  OkCancelBar . Each button is included from the same external XML layout file to make them easier to maintain; we simply override their id: 這兩個按鈕如下所示,在OkCancelBar裡面我們添加了兩個按鈕,對同一個xml我們重新利用include定義了id
<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <include
        layout="@layout/okcancelbar_button"
        android:id="@+id/okcancelbar_ok" />
        
    <include
        layout="@layout/okcancelbar_button"
        android:id="@+id/okcancelbar_cancel" />
</merge>       
The  <merge />  tag is extremely useful and can do wonders in your code. However, it suffers from a couple of limitation:
  • <merge />

     can only be used as the root tag of an XML layout
  • When inflating a layout starting with a 

    <merge />

    , you must specify a parent 

    ViewGroup

     and you must set

    attachToRoot

     to 

    true

     (see the documentation of the inflate() method)
merge标簽隻能用于xml;當Inflate以merge開頭時,必須指定一個父ViewGroup也必須設定attachToRoot為true      
3.ViewStub:      
To use a          ViewStub                 all you need is to specify an          android:id                 attribute, to later inflate the stub, and an          android:layout                attribute, to reference what layout file to include and inflate. A stub lets you use a third attribute,          android:inflatedId                , which can be used to override the id of the root of the included file. Finally, the layout parameters specified on the stub will be applied to the roof of the included layout. Here is an example:


       
<ViewStub
  android:id="@+id/stub_import"
  android:inflatedId="@+id/panel_import"

  android:layout="@layout/progress_overlay"

  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:layout_gravity="bottom" />      
When you are ready to inflate the stub, simply invoke the inflate() method. You can also simply change the visibility of the stub to VISIBLE or INVISIBLE and the stub will inflate. Note however that the  inflate()  method has the benefit of returning the root  View  of the inflate layout: 當你想加載布局時,,可以在下面選用一種方法:
((ViewStub) findViewById(R.id.stub_import)).setVisibility(View.VISIBLE);
// or
View importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();      
上面的很多内容來自對谷歌官網的一些摘抄,加入了個人的了解,希望對大家有幫助-_-