Android用戶界面設計:相對佈局

理解佈局對於良好的Android程序設計非常重要。在這個教程裡,你將學到相對佈局的所有知識,相對佈局用於將用戶界面控件或小工具相對於其它控件或它們的父級佈局組織在屏幕上。當使用正確的時候,相對佈局可以是很強大和靈活佈局,很多有趣的Android程序用戶界面都可以基於它來設計。

什麼是相對佈局

除瞭將控件顯示在一行或一列的線性佈局,相對佈局也是Android用戶界面設計使用得很普遍的佈局類型。和其它佈局很相似,相對佈局可以通過XML佈局資源來定義也可以用Java程序來定義。相對佈局的功能就像它的名字表達的一樣:它相對其它控件或父控件本身來組織控件。

這是什麼意思呢?意思是子控件,比如ImageView,TextView,和Button控件,可以放在另外一個控件的上面,下面,或是左邊或者右邊。子控件可以相對於父控件(相對佈局容器)放置,包括放置在佈局的頂部,底部,左部或右部邊緣。

相對佈局子控件位置使用規則來定義。這些規則定義瞭相對佈局內的控件如何顯示。相對佈局的完整規則列表請參見RelativeLayout類的Android SDK文檔。相關的用於XML資源的XML屬性也可以在文檔中找到。

註意:規則要求每個子控件恰當地設置瞭它的id屬性。

一個簡單的相對佈局

相對佈局最好使用例子來解釋。假設我們要設計一個屏幕,包含一個EditText控件和一個Button控件。我們希望Button顯示在EditText控件的右邊。因此,我們可以定義一個包含兩個子控件的相對佈局:子控件分別是EditText和Button。EditText控件可能有一個規則說:將這個控件放置在父控件(佈局)的左手邊並且在第二個控件(Button)的左邊。同時,Button控件可能有一個規則:將這個控件放置在父控件(佈局)的右手邊。

下面的圖片就展示瞭這樣一個相對佈局,分別是豎屏和橫屏模式。這個相對佈局有兩個子控件:一個EditText控件和一個Button控件。

 

 

定義帶有相對佈局的XML資源文件

設計程序用戶界面最方便和可維護的方法是創建XML佈局資源。這個方法極大地簡化瞭UI設計過程,將很多靜態創建和用戶界面控件的佈局以及控件屬性的定義移到XML中去,取代瞭寫代碼。

XML佈局資源必須存儲在/res/layout項目目錄下。讓我們看看前一節介紹的相對佈局。這個佈局資源文件,恰當地命名為/res/layout/relative.xml,在XML中如下定義:

 xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_height="fill_parent" 
 android:layout_width="fill_parent">  
 android:id="@+id/EditText01" 
 android:hint="Enter some text…" 
 android:layout_alignParentLeft="true" 
 android:layout_width="fill_parent" 
 android:layout_toLeftOf="@+id/Button01" 
 android:layout_height="wrap_content">  
 android:id="@+id/Button01" 
 android:text="Press Here!" 
 android:layout_width="wrap_content" 
 android:layout_alignParentRight="true" 
 android:layout_height="wrap_content"> 

回憶一下,在Activity中,隻需要在onCreate()方法中添加一行代碼來在屏幕上加載和顯示佈局資源。如果佈局資源存放在/res/layout/relative.xml文件中,這行代碼應該是:

setContentView(R.layout.relative); 這個相對佈局設置瞭寬和高填充整個屏幕,並且它的子控件配置瞭三個規則:

•EditText01:對齊到佈局的左手邊
•EditText01:顯示在Button01的左邊
•Button01:對齊到佈局的右手邊
用程序定義相對佈局

你也可以用程序創建和配置相對佈局。這通過使用RelativeLayout類(android.widget.Relative)來實現。你會在RelativeLayout.LayoutParams類中找到具體的參數。同樣地,典型的佈局參數(android.view.ViewGroup.LayoutParams),比如layout_height和layout_width,以及邊距參數(ViewGroup.MarginLayoutParams),也能用在RelativeLayout對象上。

你必須用Java創建屏幕內容,然後向setContentView()方法提供一個包含所有要作為子視圖顯示的控件內容的父佈局對象,而不是像前面所示直接使用setContentView()方法來加載佈局資源。在這裡,你的父佈局就是相對佈局。例如,下面的代碼示例瞭如何用程序在活動中實例化一個RelativeLayout並且在它的onCreate()方法中向它添加一個TextView和一個Button控件,就像前面一節展示的佈局一樣:

publicvoid onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState);
 // setContentView(R.layout.relative);
EditText ed = new EditText(this); 
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT,
 LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);  // use same id as defined when adding the button
params.addRule(RelativeLayout.LEFT_OF, 1001); 
ed.setLayoutParams(params); 
ed.setHint("Enter some text…."); 
Button but1 = new Button(this); 
RelativeLayout.LayoutParams params2 = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
 LayoutParams.WRAP_CONTENT);
params2.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
 but1.setLayoutParams(params2);
 but1.setText("Press Here!");  // give the button an id that we know
but1.setId(1001); 
RelativeLayout layout1 = new RelativeLayout(this);
 layout1.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
 layout1.addView(ed);  layout1.addView(but1);
 setContentView(layout1);
 } 

讓我們仔細看一下上面的Java代碼。首先我們像平常一樣創建一個EditText控件。我們給它一些RelativeLayout參數,然後設置它的規則。在這裡,我們為EditText控件創建2個規則。

接下來,我們創建一個Button控件並且設置它的規則(對齊到父佈局右邊緣)。最後,我們創建一個RelativeLayout對象,設置它的參數,使用addView()方法添加兩個控件並且使用setContentView()方法加載顯示相對佈局。

如你所見,當越來越多的控件要添加到屏幕時,代碼量會很快地增長。為瞭易組織和可維護性,用程序定義並使用佈局最好是用在特殊情況而不是一般情況。

探討相對佈局的重要特性和屬性

現在讓我們來討論一些幫助配置相對佈局和它的子控件的屬性。一些特定的屬性用於相對佈局,也就是子規則,包括:

•用於子控件在父佈局中居中的規則,包括:水平居中,垂直居中,或者兩者皆居中。
•用於子控件在父佈局中排佈的規則,包括:在頂部,底部,左,右邊緣放置。
•用於子控件相對於其它子控件排佈的規則,包括:在另一個控件頂,底,左,右邊緣放置。
•用於子控件相對於其它子控件放置的規則,包括:在另一個控件上面,底下,左邊或右邊放置。
同樣的,通用的 ViewGroup-style屬性也可以應用於相對佈局。這些屬性包括:

•通用佈局參數比如layout_height(必須)和layout_width(必須)(類:ViewGroup.LayoutParams)
•邊距佈局參數比如margin_top, margin_left, margin_right和margin_bottom (類:ViewGroup.
MarginLayoutParams)
佈局參數比如layout_height和layout_width (類:ViewGroup.LayoutParams)

現在讓我們來實踐這些規則吧!

使用佈局規則

讓我們看一個更復雜的屏幕設計。為瞭這個練習,我們從查看最終屏幕效果開始,然後再倒回來工作,並討論這個相對佈局的特性和為瞭達到最終結果所使用的規則。 

為瞭使用相對佈局來設計這個屏幕,參考以下步驟。

步驟1:在你的XML資源文件中定義一個相對佈局

首先,在你的XML資源文件中定義一個相對佈局。因為你想這個佈局控制整個屏幕的內容,所以設置它的高和寬屬性為fill_parent。你的XML資源文件應該看起來像這樣:

 xmlns:android=http://schemas.android.com/apk/res/android
 android:layout_height="fill_parent"
 android:layout_width="fill_parent">

步驟2:確定子控件

接下來,我們確定需要什麼樣的子控件。在這裡,我們需要7個TextView控件(第個一種顏色)。像平常一樣配置它們,設置文本屬性為字符串,背景色,字號等等。將這些控件都放到相對佈局中。

步驟3:定義相對佈局規則

接下來,我們為每個子控件定義規則,以使它們被繪制到合適的位置:

•RED TextView控件沒有特別的設置。默認地,這個控件將會被繪制到父佈局的左上角。
•ORANGE TextView控件在父佈局中水平居中。因為所有控件默認都會靠向屏幕的左上角,這有效地將控件定位到父佈局的邊緣頂部中間。
•YELLOW TextView控件定位到父佈局的右邊緣。因為所有控件默認都會靠向屏幕的左上角,這有效的定位控件到父佈局的右上角。
•GREEN TextView控件在父佈局中垂直居中,並且設置為顯示在BLUE TextView控件的左邊。
•BLUE TextView控件被定位在父控件的中心(水平和垂直)。這將它顯示在屏幕的中心位置。
•INDIGO TextView控件在父局中垂直居中,並且設置為顯示在BLUE TextView控件的右邊。
•VIOLET TextView控件被定位到父佈局的底部邊緣。它的寬度也被設置為填滿父容器,允許它延伸到屏幕的底部邊緣。
如果你在你的XML資源文件中定義這些規則,XML文件代碼將看起如下:

xmlns:android=http://schemas.android.com/apk/res/android
android:layout_height="fill_parent"
android:layout_width="fill_parent">
android:text="RED"
android:id="@+id/TextView01"
android:layout_height="wrap_content"
android:background="#f00"
android:gravity="center"
android:textColor="#000"
android:layout_width="wrap_content"
android:padding="25dp">
android:text="ORANGE"
android:layout_height="wrap_content"
android:background="#ffa500"
android:gravity="center"
android:textColor="#000"
android:id="@+id/TextView02"
android:layout_width="wrap_content"
android:layout_centerHorizontal="true"
android:padding="25dp">
android:text="YELLOW"
android:layout_height="wrap_content"
android:background="#ffff00"
android:gravity="center"
android:textColor="#000"
android:id="@+id/TextView03"
android:layout_width="wrap_content"
android:layout_alignParentRight="true"
android:padding="25dp">
android:text="GREEN"
android:layout_height="wrap_content"
android:background="#0f0"
android:gravity="center"
android:textColor="#000"
android:id="@+id/TextView04"
android:layout_width="wrap_content"
android:layout_toLeftOf="@+id/TextView05"
android:padding="25dp"
android:layout_centerVertical="true">
android:text="BLUE"
android:layout_height="wrap_content"
android:background="#00f"
android:gravity="center"
android:textColor="#fff"
android:id="@+id/TextView05"
android:layout_width="wrap_content"
android:layout_centerInParent="true"
android:layout_margin="10dp"
android:padding="25dp">
android:text="INDIGO"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#fff"
android:id="@+id/TextView06"
android:layout_width="wrap_content"
android:layout_toRightOf="@+id/TextView05"
android:background="#4b0082"
android:padding="25dp"
android:layout_centerVertical="true">
android:text="VIOLET"
android:layout_height="wrap_content"
android:background="#ee82ee"
android:gravity="center"
android:textColor="#000"
android:id="@+id/TextView07"
android:layout_alignParentBottom="true"
android:layout_width="fill_parent"
android:padding="25dp"> 

相對佈局使用技巧

這裡是一些使用相對佈局的技巧。

•相對佈局的子控件必須有唯一的id屬性以使規則正確應用。
•當心循環規則。循環規則發生在兩個控件具有互相指向的規則時。如果你在佈局設計中使用瞭循環規則,你將會得到以下錯誤信息:
IllegalStateException: Circular dependencies cannot exist in a RelativeLayout(相對佈局中不允許存在循環依賴)
•回憶一下相對佈局規則的應用被一次處理是很有用的
•保持你的相對佈局規則最小化。這減小瞭循環規則的機率並且使得你的佈局更加可維護和靈活。
•一般地,記住測試一下你的佈局設計在橫屏和豎屏模式下,以及在不同的屏幕大小和解決方案下是不是符合預期的。
•使用相對佈局代替嵌套線性佈局以改進程序性能和響應能力。
總結

Android程序用戶界面使用佈局來定義,相對佈局是用於使得程序屏幕更加靈活和強大的佈局類型之一。相對佈局允許子控件相對於其它子控件和相對於父控件(邊緣以及水平和垂直居中)來組織。一旦你掌握瞭如何使用相對佈局的規則,它們可以有非常多的用處,使你能夠創建復雜佈局,而不需要過多嵌套不同的佈局,因此也改進瞭性能。

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *