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中如下定義:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="fill_parent" android:layout_width="fill_parent"> <EditText 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"></EditText> <Button android:id="@+id/Button01" android:text="Press Here!" android:layout_width="wrap_content" android:layout_alignParentRight="true" android:layout_height="wrap_content"></Button> </RelativeLayout>
回憶一下,在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控件,就像前面一節展示的布局一樣:
public void 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資源文件應該看起來像這樣:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="fill_parent" android:layout_width="fill_parent"> </RelativeLayout>
步驟2:確定子控件
接下來,我們確定需要什么樣的子控件。在這里,我們需要7個TextView控件(第個一種顏色)。像平常一樣配置它們,設置文本屬性為字符串,背景色,字號等等。將這些控件都放到相對布局中。
步驟3:定義相對布局規則
接下來,我們為每個子控件定義規則,以使它們被繪制到合適的位置:
- RED TextView控件沒有特別的設置。默認地,這個控件將會被繪制到父布局的左上角。
- ORANGE TextView控件在父布局中水平居中。因為所有控件默認都會靠向屏幕的左上角,這有效地將控件定位到父布局的邊緣頂部中間。
- YELLOW TextView控件定位到父布局的右邊緣。因為所有控件默認都會靠向屏幕的左上角,這有效的定位控件到父布局的右上角。
- GREEN TextView控件在父布局中垂直居中,并且設置為顯示在BLUE TextView控件的左邊。
- BLUE TextView控件被定位在父控件的中心(水平和垂直)。這將它顯示在屏幕的中心位置。
- INDIGO TextView控件在父局中垂直居中,并且設置為顯示在BLUE TextView控件的右邊。
- VIOLET TextView控件被定位到父布局的底部邊緣。它的寬度也被設置為填滿父容器,允許它延伸到屏幕的底部邊緣。
如果你在你的XML資源文件中定義這些規則,XML文件代碼將看起如下:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="fill_parent" android:layout_width="fill_parent"> <TextView 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"></TextView> <TextView 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"></TextView> <TextView 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"></TextView> <TextView 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"></TextView> <TextView 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"></TextView> <TextView 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"></TextView> <TextView 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"></TextView> </RelativeLayout>
相對布局使用技巧
這里是一些使用相對布局的技巧。
- 相對布局的子控件必須有唯一的id屬性以使規則正確應用。
- 當心循環規則。循環規則發生在兩個控件具有互相指向的規則時。如果你在布局設計中使用了循環規則,你將會得到以下錯誤信息:
IllegalStateException: Circular dependencies cannot exist in a RelativeLayout(相對布局中不允許存在循環依賴)
- 回憶一下相對布局規則的應用被一次處理是很有用的
- 保持你的相對布局規則最小化。這減小了循環規則的機率并且使得你的布局更加可維護和靈活。
- 一般地,記住測試一下你的布局設計在橫屏和豎屏模式下,以及在不同的屏幕大小和解決方案下是不是符合預期的。
- 使用相對布局代替嵌套線性布局以改進程序性能和響應能力。
總結
Android程序用戶界面使用布局來定義,相對布局是用于使得程序屏幕更加靈活和強大的布局類型之一。相對布局允許子控件相對于其它子控件和相對于父控件(邊緣以及水平和垂直居中)來組織。一旦你掌握了如何使用相對布局的規則,它們可以有非常多的用處,使你能夠創建復雜布局,而不需要過多嵌套不同的布局,因此也改進了性能。[English]
轉載請注明:
作者:RockUX–WEB前端
出自:Android用戶界面設計:相對布局
- 目前還沒評論,等你發揮!