Android用戶界面設計:線性??布局
理解布局對于良好的Android程序設計來說很重要。在這個教程中,你將學習到所有關于線性布局的東西,它在屏幕上垂直地或水平地組織用戶界面控件或者小工具。使用得當,線性布局可以作為基本的布局,基于這個布局來可以設計出許多有趣的Android程序用戶界面。
什么是線性布局
線性布局是最簡單,Android開發者使用得最多的布局類型之一,開發者用它來組織你們的用戶界面上的控件。線性布局的作用就像它的名字一樣:它將控件組織在一個垂直或水平的形式。當布局方向設置為垂直時,它里面的所有子控件被組織在同一列中;當布局方向設置為水平時,所有子控件被組織在一行中。
線性布局可以在XML布局資源文件中定義,也可以用Java代碼在程序中動態的定義。
下圖展示了一個包含7個TextView控件的線性布局。這個線性布局方向被設置為垂直,導致每個TextView控件被顯示在一列當中。每一個TextView控件的文本屬性都是一個顏色值,背景色就是這個顏色;通過將控件的layout_width屬性設置為fill_parent,每個控件都拉伸到屏幕寬度。
用XML布局資源定義線性布局
設計程序用戶界面最方便和可維護的方法是創建XML布局資源。這個方法極大地簡化了UI設計過程,它將很多靜態創建和用戶界面控件的布局以及控件屬性的定義移到了XML中,而不是寫代碼。
XML布局資源必須被存儲在項目目錄的/res/layout下。讓我們看看前一節介紹的彩虹線性布局。這個屏幕基本上就是一個設置為鋪滿整個屏幕的垂直線性布局,這通過設置它的layout_width和layout_height屬性為fill_parent來實現。適當地將其命名為/res/layout/rainbow.xml,XML定義如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <TextView android:text="RED" android:id="@+id/TextView01" android:layout_height="wrap_content" android:background="#f00" android:layout_width="fill_parent" android:layout_weight=".14" android:gravity="center" android:textColor="#000"></TextView> <TextView android:text="ORANGE" android:id="@+id/TextView02" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_weight=".15" android:background="#ffa500" android:gravity="center" android:textColor="#000"></TextView> <TextView android:text="YELLOW" android:id="@+id/TextView03" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_weight=".14" android:background="#ffff00" android:gravity="center" android:textColor="#000"></TextView> <TextView android:text="GREEN" android:id="@+id/TextView04" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_weight=".15" android:background="#0f0" android:gravity="center" android:textColor="#000"></TextView> <TextView android:text="BLUE" android:id="@+id/TextView05" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_weight=".14" android:background="#00f" android:gravity="center" android:textColor="#fff"></TextView> <TextView android:text="INDIGO" android:id="@+id/TextView06" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_weight=".14" android:background="#4b0082" android:gravity="center" android:textColor="#fff"></TextView> <TextView android:text="VIOLET" android:id="@+id/TextView07" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_weight=".14" android:background="#ee82ee" android:gravity="center" android:textColor="#000"></TextView> </LinearLayout>
可能你會注意到這個線性布局的每一個子控件都有很多有趣的屬性,包括一個叫做layout_weight的屬性。一會我們會講到更多關于它的內容。
下面兩張圖片展示了這個布局在設備的豎屏和橫屏模式下的樣子:
回憶一下,在Activity中,只需要一行有onCreate()方法的代碼來在屏幕上加載和顯示一個布局資源。如果這個布局資源被存儲在/res/layout/rainbow.xml文件中,這行代碼應該是:
setContentView(R.layout.rainbow);
用程序動態定義線性布局
你也可以通過程序來創建和配置線性布局。這通過LinearLayout(android.widget.LinearLayout)類來實現。你能在LinearLayout.LayoutParams類中找到子級細節。同樣地,典型的布局參數(android.view.ViewGroup.LayoutParams),如layout_height和layout_width, 以及邊距參數(ViewGroup.MarginLayoutParams)也能用在LinearLayout對象上。
使用以前介紹過的setContentView()方法代替直接加載布局資源,你需要用Java創建屏幕內容,然后向setContentView()方法提供一個父級布局對象,這個對象包括了所有要作為它的子視圖展示的控件內容。在這種情況下,你的父級布局對象是線性布局。
例如,下面的代碼示例了如何用程序在Activity中實例化一個線性布局并在它的onCreate()方法中將三個TextView對象放入其中:
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // setContentView(R.layout.rainbow); TextView tv1 = new TextView(this); tv1.setText("FIRST"); tv1.setTextSize(100); tv1.setGravity(Gravity.CENTER); TextView tv2 = new TextView(this); tv2.setTextSize(100); tv2.setGravity(Gravity.CENTER); tv2.setText("MIDDLE"); TextView tv3 = new TextView(this); tv3.setTextSize(100); tv3.setGravity(Gravity.CENTER); tv3.setText("LAST"); LinearLayout ll = new LinearLayout(this); ll.setOrientation(LinearLayout.VERTICAL); ll.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); ll.setGravity(Gravity.CENTER); ll.addView(tv1); ll.addView(tv2); ll.addView(tv3); setContentView(ll); }
下面兩張圖片展示了這個布局在設備豎屏和橫屏下的樣子:
讓我們更近一步地研究一下上面的Java代碼。首先,創建并配置三個TextView控件。每個控件都有文本大?。ㄗ煮w大?。?,文本對齊,以及文本值本身。然后,創建一個垂直方向的線性布局。它的布局參數允許它填充整個父級對象(在這里就是整個屏幕),并且它的對齊導致所有子控件都排列在屏幕中間,而不是從左上角開始。每個TextView控件通過addView方法作為子控件添加到線性布局中。最后,當父級控件要在屏幕上顯示時,線性布局被傳到setContentView()方法中。
如你所見,當越來越多的控件要添加到屏幕時,代碼量會很快地增長。為了易組織和可維護性,用程序定義并使用布局最好是用在特殊情況而不是一般情況。
探討線性布局的重要特性和屬性
現在讓我們來看看有助于配置線性布局和它的子控件的一些重要屬性。
一些特別的屬性應用到線性布局。你會使用到線性布局最重要的屬性包括:
- 方向屬性(必須),取值可以是vertical或horizontal(類:LinearLayout)
- 對齊屬性(可選),控制子控件在線性布局中如何排列和顯示(類:LinearLayout)
- layout_weight屬性(可選,應用到每個子控件)指定每個子控件在父級線性布局中的相對重要性(類:LinearLayout.LayoutParams)
此外,通用的ViewGroup-style屬性也應用到線性布局。這些屬性包括:
- 通用布局參數如layout_height (必須)和layout_width (必須) (類:ViewGroup.LayoutParams)
- 邊距布局參數如margin_top,margin_left,margin_right和margin_bottom (類:ViewGroup. MarginLayoutParams)
- 布局參數如layout_height和layout_width (類:ViewGroup.LayoutParams)
給子控件賦權
絕大部分線性布局的屬性都是自明性的。然而layout_weight屬性需要一些額外的討論。與其它線性布局屬性不同,其它屬性應用在線性布局視圖本身,而這個屬性是應用在它的子控件上的。權值本身應該是一個數字(比如0.5,0.25,0.10,0.10,0.05),如果你把所有子控件的權值加起來等于1(100%)。
子控件的權值控件它在父線性布局中有多“重要”或者留給其多少“空間”。這一點最好通過例子來說明。讓我們回到我們前面用的彩虹線性布局。為了允許所有子控件相同地“拉伸”填充線性布局,不管屏幕的大小,我們使用layout_weight來對每個TextView賦予相對權值。因為有7種我們想賦相同權值的顏色,我們將1除以7大約得到0.143.然而,既然我們想要權值之和最后為1,因此5個控件權值設為0.14,另外兩個為0.15——一個微小的區別使得總和剛剛好為1,但是這對于第一個和最后一個控件來說還是很明顯的。
當屏幕上有足夠空間來正確的展示所有控件的時候,這個權值技巧很有效。那就是說,當空間很緊的時候,權值屬性可能會被其它因素覆蓋,比如視圖裁剪或者在TextView下試圖不環繞文本。當我們改變rainbow.xml布局文件以包含相似水平布局(layout_height 還是設置為 fill_parent)的時候,這變得很明顯。
下面的兩張圖片展示這個相同的布局(只是改變到水平方向)在設備豎屏和橫屏模式下可能的樣子:
我們期望的是紅色和紫色區域(權值0.15)比其它顏色(權值為0.14)會略大一些,但是顯示出來卻不是這樣。如果你仔細看紅色TextView,它應該比它邊上橙色的TextView占用更多空間。然而,因為“Red”是一個短單詞,而“Orange”不是,因此系統自動的作了一些沖撞調整,為了使得每個單詞不會折行。這樣的結果更令人高興,但是這可能會有一些煩惱,如果這不是想要的效果的話。
總結
Android程序用戶界面使用布局來定義,而線性布局是最基本的布局類型之一。線性布局允許子控件被組織在一行或一行(水平)或一列(豎直)上。子控件的位置可以使用對齊和權值屬性進一步設置。[English]
轉載請注明:
作者:RockUX–WEB前端
出自:Android用戶界面設計:線性布局
原創辛苦,請多多支持!
- 目前還沒評論,等你發揮!