《創建一個簡單的用戶界面》
Android應用程序的圖形用戶界面建立在View
(視圖)和 ViewGroup
(試圖組)層上。 View
對象是常見的界面widgets(控件),例如 buttons(按鈕)
或者 text fields (輸入框)。ViewGroup
對象
是不可見的視圖容器,通常定義子視圖的佈局,比如說網絡型佈局或者垂直列表佈局。
Android 提供一種XML 語法,相當於View
和 ViewGroup
的子集。所以你可以在XML裏利用UI元素的層次結構定義自己的界面。
選擇佈局
用XML說明UI佈局而不用代碼有很多原因,最大的原因就是能夠對不同的屏幕創建不同的佈局。比如說,你可以創建兩個版本佈局,然後告訴系統一個是用在小屏幕上的,一個是用在大屏幕上的。如需瞭解更多內容,請點擊 Supporting Different Devices。
圖 1. 圖解ViewGroup對象的佈局分支裏含有另一個
ViewGroup對象。
在本節課中,你將用XML語言創建一套佈局,他會包含一個文本輸入框和一個按鈕。在下節課中,你就可以使這個按鈕在被按下的時候把文字發送給另一個Activity。
創建一個線性佈局
在 res/layout/
目錄裏打開 activity_main.xml
文件。
注意: 在 Eclipse裏, 當你打開一個佈局文件時,首先看到的是圖形界面編輯器,它會幫你用WYSIWYG 工具創建佈局。在本節課中,你會直接用XML語言工作,所以打開XML編輯器中在點擊上方的activity_main.xml選項卡。
你選擇的空白Activity模版包括了activity_main.xml
文件, 裏面有 RelativeLayout
(相對佈局)根視圖和一個 TextView子視圖
。
首先,刪除<TextView>
部分並且將<RelativeLayout>(相對佈局)
換成 <LinearLayout>(線性佈局)
。之後添加 android:orientation
屬性並設置爲"horizontal"
。
改變的結果看起來應該是這樣的:
<?xml version="1.0" encoding="utf-8"?> |
LinearLayout
是一個視圖組( ViewGroup的子集
)
,會將子視圖垂直排列或水平排列, 按照android:orientation
屬性說明,
在XML裏的 LinearLayout的每一個子集
都會有序的在屏幕上出現。
另外的兩個屬性,android:layout_width
和android:layout_height
,是用來申明後面所有視圖大小的。
由於 LinearLayout
是佈局的根視圖,它應當充滿整個屏幕空間,所以才把應用的寬和高設置成"match_parent"
。這個值聲明瞭視圖的寬和高應當與父視圖的寬和高匹配。
佈局屬性的更多信息,詳見Layout guide。
添加一個文本框
添加一個可編輯的文本框(輸入框),要在<LinearLayout>
裏添加一個<EditText>
元素。
像任一 View
(視圖),你必須爲EditText
定義某些XML
屬性,以下是你要在 <LinearLayout>
裏面聲明的內容:
<EditText android:id="@+id/edit_message" android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="@string/edit_message" /> |
關於資源對象
一個資源對象只是一個與獨特的整數的名字聯繫在一起的應用程序資源,例如一個位圖,佈局文件,或者字符串。
每一個資源都應當在 gen/R.java
文件裏有着對應的定義。 你可以在R
class (R類)中用對象的名稱引用你的資源文件,例如你需要爲android:hint
屬性制定一個字符串值。您還可以創建任意的資源ID,這些資源用android:id
屬性聯繫在一起,從而允許你在其他代碼裏引用它。
SDK 工具在你每次編譯應用程序的時候都會自動生成R.java
文件,你不能手動修改這個文件。
更多信息,移步Providing Resources.
關於這些屬性:
android:id
- 他爲視圖提供了獨一無二的標識,它使你可以從你的應用程序代碼裏引用對象,比如說讀取和操作對象(你將會在下節課中學習到)。
當你在XML裏引用任何資源的時候,必須加上at 符號 (
@
) 。 之後要加上資源類型(在這裏類型是是id
),斜線, 然後是資源名稱(edit_message
)。資源類型後的加號(
+
) 只用在你第一次定義資源的時候。當你編譯的時候,SDK工具會用ID名字在項目的gen/R.java
文件裏創建一個新的資源ID來引用EditText
,一旦資源ID是用這種方式定義的,以後在引用就不用再加上加號了。只有當申明一個新的資源ID並且不需要具體的資源的時候纔會用加號,比如說申明字符串或佈局。 在上面你可以看到關於資源對象的更多信息。 android:layout_width
andandroid:layout_height
- 用
"wrap_content"
值而不是對長度和寬度是用特定大小,是因爲視圖只需要達到足夠填滿整個父視圖就夠了。用"match_parent"
,EditText
會填滿屏幕, 因爲它將匹配父LinearLayout
的大小。 android:hint
- 這是當文本框空的時候默認顯示的字符串。
"@string/edit_message"
在單獨文件裏引用了一個字符串資源,而不直接使用硬編碼的字符串值, 是由於這裏引用了一個具體的資源(不僅僅是一個標識符),同理這裏不需要加號。另外,由於你還沒有定義字符串資源,你會看到一個編譯錯誤,但你會在下節課定義字符串的時候修復它。注意: 這裏的字符串名字和ID一樣,都是:
edit_message
. 通常應用資源的類型都是由資源的類型定義的,例如id
或string
。所以這裏是用一樣的名字不會引起衝突。
添加字符串資源
當你需要在界面中添加文本時,你應當把每一個字符串當作資源來申明。字符串資源文件使你能夠在一個位置管理所有的界面文本,這使你更容易找到並修改文本。字符串的外部化可以使應用程序通過替換定義的字符串資源而支持多種語言。
默認情況下,你的Android項目裏面已經包含了一個字符串資源: res/values/strings.xml,添加一個新的字符串名稱
"edit_message"
並把它設爲
"Enter a message." (你可以刪掉 "hello_world" 字符串)。
然後在這個文件裏再爲按鈕添加一個"Send" 字符串,名稱填"button_send"。
最終strings.xml
內容應該是這樣的:
<?xml version="1.0" encoding="utf-8"?><resources><string name="app_name">My First App</string><string name="edit_message">Enter a message</string><string name="button_send">Send</string><string name="menu_settings">Settings</string><string name="title_activity_main">MainActivity</string> </resources> |
想了解更多關於使用string resources支持多種語言的信息,移步Supporting Different Devices class.
添加一個按鈕Add a Button
現在在佈局裏<EditText>
後面添加 <Button>
:
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button_send" /> |
寬度和高度都設置爲"wrap_content"
,這樣按鈕的大小決定於按鈕文字的多少。這個按鈕不需要android:id
屬性,所以它不能被activity 代碼引用。
Make the Input Box Fill in the Screen Width
目前EditText
和 Button
控件的佈局都是內容自適應的,如圖二:
圖 2. EditText
和 Button
空間的寬度設置值都是"wrap_content"。
按鈕看起來還好,但是文本輸入框看起來就不太好,這是因爲用戶有可能輸入的更長。所以這兩個空間寬度正好填滿屏幕寬度。你可以通過在 LinearLayout添加權重屬性
來達到這樣的效果,這需要你指定android:layout_weight
屬性。
權重值是一個數值,這個數值會指定每個視圖相對於兄弟視圖佔剩餘空間的多少。這有點像在飲料配方的成分佔了量:“2份伏特加酒,1份咖啡利口酒。” 這意味着飲料的三分之二是伏特加,如果你給一個視圖的權重是2而另一個視圖的權重是1,那麼和就是3。所以第一個視圖填充剩餘視圖三分之二,另一個則填充剩餘。如果你再加第三個視圖,設置權重爲1,那第一個視圖(權重爲2)現在就填充剩餘空間的1/2。而剩下的兩個各獲得1/4。
每個視圖的默認權重是0,所以你只能指定一個權重值爲0的視圖,然後他會填充其他視圖填充後的剩餘的所有空間。所以想要使用EditText
填充剩餘空間就給他指定權重爲1,按鈕不設定權重
<EditText android:layout_weight="1" ... /> |
當你指定權重值的時候,爲了提高佈局的效率你應該把EditText
的寬改爲0dp。把寬設定爲0可以改善佈局效率,這是由於使用"wrap_content"
作爲寬會讓系統計算一個最終用不着的值,因爲權重值需要另一個寬度計算才能填充剩餘空間。
<EditText android:layout_weight="1" android:layout_width="0dp" ... /> |
圖三展示你給EditText
分配了所有權重的效果
圖 3. EditText
的權重值賦予了它全部的佈局寬度,所以他會填充LinearLayout(線性佈局)的所有剩餘空間。
這裏是你的佈局文件內容:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <EditText android:id="@+id/edit_message" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" android:hint="@string/edit_message" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button_send" /> </LinearLayout> |
這個佈局應用的是當你創建項目是SDK工具生成的默認的Activity類
,所以你可以運行你的應用開看看成果了:
- 在Eclipse,點擊工具欄裏的 Run (運行)按鈕。
- 或者打開命令行程序,把當前目錄切換成安卓項目的根目錄,然後運行:
ant debug adb install bin/MyFirstApp-debug.apk |
繼續學習下節課程你將學會:爲按鈕添加按下響應,讀取文本輸入框的內容,開始另一個activity等。