注:本文翻譯自Google官方的Android Developers Training文檔,譯者技術(shù)一般,由于喜愛安卓而產(chǎn)生了翻譯的念頭,純屬個人興趣愛好。
原文鏈接: http://developer.android.com/training/basics/firstapp/building-ui.html
?
一.?構(gòu)建一個簡單UI
一個Android應(yīng)用通過
View
和
ViewGroup
對象所組成的層次結(jié)構(gòu)來構(gòu)建圖形用戶接口(GUI)。通常
View
對象是一些UI控件,比如按鈕(
buttons
),文本框(
text fields
)等。
ViewGroup
對象則是一些可見的裝載
View
對象的“容器”,同時它定義了它的子
View
對象是如何布局的,比如,定義子對象是應(yīng)該在網(wǎng)格狀布局列表中還是再垂直布局的列表中。
Android為每一種 View 和 ViewGroup 的子類提供了在XML中所對應(yīng)的詞匯,所以用戶可以在XML中通過使用一個UI元素的層次關(guān)系來定義自己的UI。 ?
圖1.? ViewGroup 的分支布局結(jié)構(gòu),每個 ViewGroup 下包含了其他的 View 對象。
在這堂課中,你將會通過XML語句創(chuàng)建一個布局,這當(dāng)中包含了一個文本框和一個按鈕。在后續(xù)課程中,你將會實現(xiàn)按鈕按下后的響應(yīng)操作:把文本框中的內(nèi)容發(fā)送給另一個Activity。
實現(xiàn)布局方式的選擇 :在XML中聲明UI布局而不是在運行時通過代碼來聲明是更加有效的,這其中有一些原因,最重要的,是你可以為不同規(guī)格的屏幕創(chuàng)建不同的布局。比如,你可以創(chuàng)建兩個版本的布局文件,并且告訴一同在小屏幕設(shè)備上使用其中一種布局,在大屏幕設(shè)備上使用另一種。可以通過閱讀 Supporting Different Devices 獲取更多這方面的信息。
?
一). 創(chuàng)建一個線性布局
在“ res/layout/ ”這一目錄下,打開文件:“ activity_main.xml ”
注 :在Eclipse中,當(dāng)你打開一個布局文件,你首先看到的將會是圖形布局編輯器( Graphical Layout editor ),通過使用 WYSIWYG工具(譯者注: WYSIWYG意為所見即所得 ),這個工具可以幫助你構(gòu)建布局。在這一堂課當(dāng)中,你將直接通過XML語句實現(xiàn)布局,所以點擊屏幕底部 activity_main.xml 這一標(biāo)簽進入XML編輯器。
當(dāng)你創(chuàng)建這個項目工程的時候,你選擇的
BlankActivity模板包含了這個
activity_main.xml
布局文件,在該文件當(dāng)中,有一個
RelativeLayout
的根View和一個
TextView
的子
View
。
首先,刪除
?
<TextView>
這一標(biāo)簽,同時將
<RelativeLayout>
改為
<LinearLayout>
,并且加上
android:orientation
這一屬性字段,將它設(shè)置為:
“
horizontal
”。修改后的結(jié)果如下:
<?
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"
>
</
LinearLayout
>
這里
LinearLayout
是一個View Group對象(
ViewGroup
的一個子類),從方向上來說,它將它的子View布局在水平方向或垂直方向上,具體的方向由
android:orientation
這一屬性字段定義。每一個
LinearLayout
的子View在屏幕上出現(xiàn)的先手順序與它在XML代碼里出現(xiàn)的先后順序一致。
另外兩個屬性字段:
android:layout_width
和
android:layout_height
對所有View對象來說都是必須的,因為它們定義了View的尺寸。
由于
LinearLayout
是布局的根View,所以應(yīng)該通過把它的寬和高設(shè)置為
"match_parent"
,以此使它填滿整個屏幕區(qū)域。上述提到的這一屬性值的含義即將該View的寬和高延展只和它的父View的寬高一致。
更多信息,可以閱讀 Layout 幫助文檔。
?
二). 添加一個文本框
為了創(chuàng)建一個用戶可編輯的文本框,添加一個
<EditText>
標(biāo)簽在
<LinearLayout>
中。
如同每一個
View
對象,你必須通過定義特定的XML屬性字段來定義
EditText
對象的屬性。這里展示你應(yīng)該在
<LinearLayout>
標(biāo)簽中如何聲明它:
<
EditText
android:id
="@+id/edit_message"
android:layout_width
="wrap_content"
android:layout_height
="wrap_content"
android:hint
="@string/edit_message"
/>
? 關(guān)于這些屬性字段 :
為該View提供唯一的Id標(biāo)識,在你的應(yīng)用代碼中,你可以通過它來引用該對象,進而讀取和操作這一對象(在下一次課程中將會學(xué)習(xí)的內(nèi)容)。
這個at(@)的符號,是當(dāng)你在XML中引用任意資源對象所必須的。緊隨它之后的是資源的類型(在此例中,類型是id),一個斜線,和資源對象的名字( edit_message )?
這個在資源類型前的加(+)號,僅在你第一次定義一個資源ID時需要。當(dāng)你編譯你的應(yīng)用時,SDK工具使用這個ID名字在你項目中的“
gen/R.java
”這一文件下會創(chuàng)建一個新的資源ID,該新ID會代表我們的
EditText
元素。一旦這個資源ID通過這種方式聲明好后,在其他地方對這個ID的引用就不在需要加號了。記住:僅在聲明一個新的
資源ID
的時候需要使用加號,對于一些固有的資源,比如字符串(string),布局(layout)來說則不需要。
關(guān)于資源對象 :
簡單的來說,一個資源對象就是與一個應(yīng)用資源(比如一個位圖,一個布局文件或一個字符串)唯一關(guān)聯(lián)起來的整形形式的名字。在你的項目工程的 gen/R.java 文件下,每一個資源有一個與之對應(yīng)的資源對象。你可以通過使用在R類中的對象名稱來引用它對應(yīng)的資源,比如:當(dāng)你需要為
android:hint 這一屬性字段定義一個字符串的值時。同時你也可以通過在android:id 這一屬性字段,創(chuàng)建一個與該View關(guān)聯(lián)的資源ID,以此使你可以在其他的代碼位置對這個View進行引用。當(dāng)你每次編譯你的應(yīng)用時,SDK工具會自動生成 R.java 文件,你應(yīng)該永遠都不要手動修改這一文件。
閱讀 Providing Resources 來獲取更多信息。
android:layout_width
和
android:layout_height
除了為寬和高定義特定的尺寸,使用
"
wrap_content
"這一屬性值意味著該View的大小剛好能適應(yīng)于它的內(nèi)容。如果你使用
"
match_parent
",這個
EditText
控件將會充滿整個屏幕,因為它將會和它的父View(
LinearLayout
)的尺寸保持一致。閱讀
Layouts
獲得更多信息。
這是一個當(dāng)文本框內(nèi)容為空時,默認顯示的字符串。除了直接定義字符串的值外,還可以通過
"
@string/edit_message
"
?這樣的方法來引用一個在其他文件定義了的字符串資源。因為這個引用是指向一個固有的資源(不是一個ID標(biāo)識),所以不需要加上加號。然后,因為你還沒有定義這個字符串資源,所以你將會看到一個編譯錯誤,你將在下一節(jié)通過定義這個字符串來解決這個問題。
注 :這個字符串資源和這個空間的ID有著相同的名字:
edit_message ,然而,對資源的引用會被限制在不同資源類型特定的作用域內(nèi),因此在此例中,使用相同的名字也不會產(chǎn)生命名沖突。
?
三). 添加字符串資源
當(dāng)你需要在UI中添加文本時,你應(yīng)該經(jīng)常講字符串定義為資源的形式,字符串資源可以允許你在同一個地方統(tǒng)一管理所有的UI文字,使得尋找和更新文字變得輕松。同時,將字符串放在外部可以允許你通過為每一個字符資源提供不同的定義,解決你的應(yīng)用對于不同語言的本地化問題。
默認的,你的Android項目工程包含了一個字符串資源文件,這個文件位于:“ res/values/strings.xml ”。現(xiàn)在我們添加一個新的字符串,將它命名為“ edit_message ”,并且把它的值定義為“ Enter a message ”(你可以將字符串“ Hello World ”刪除)。
與此同時,添加一個值為“ Send ”的字符串,它的名字為“ button_send ”,這是為之后將要添加的按鈕控件做的準(zhǔn)備工作。
修改后的 strings.xml 變?yōu)椋?
<?
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
="action_settings"
>
Settings
</
string
>
<
string
name
="title_activity_main"
>
MainActivity
</
string
>
</
resources
>
?
關(guān)于使用字符串資源解決應(yīng)用對于不同語言的本地化問題,更多的信息可以閱讀: Supporting Different Devices
?
四). 添加一個按鈕
現(xiàn)在在布局中添加一個
<Button>
標(biāo)簽,它緊接著
<EditText>
標(biāo)簽:
<
Button
android:layout_width
="wrap_content"
android:layout_height
="wrap_content"
android:text
="@string/button_send"
/>
把高度和寬度設(shè)置為“
wrap_content
”,這樣按鈕的大小正好適應(yīng)于按鈕的文字。這個按鈕控件暫時不需要
android:id
這一屬性字段,因為它在
activity
的代碼中暫時不會被引用到。
?
五). 使輸入框的寬度與屏幕寬度對應(yīng)
現(xiàn)在的布局被設(shè)計成
EditText
和
Button
這兩個控件的大小和它們的內(nèi)容相適應(yīng),如圖2所示:
圖2. 寬度設(shè)置為“
wrap_content
”后的
EditText
和
Button
這樣做對于按鈕來說沒有什么問題,但是對文本框來說可能就不太好,因為用戶可能會輸入更長的字符串。所以最好是屏幕中沒有用到的寬度給文本框使用。我們可以在
LinearLayout
中使用
比重(Weight)
屬性來實現(xiàn),具體來說是使用
android:layout_weight
這一屬性字段。
比重 的值是一個數(shù)字,這個數(shù)字用來表征每個View相對于它兄弟View所消耗的空間來說,可以使用的剩余的空間大小。可以理解為飲料的配方:“2份伏特加和1份咖啡甜酒”,這就意味著飲料中的三分之二是伏特加。例如:如果你給了一個View的 比重 是2,而另一個View的 比重 是1,那么他們的和是3,所以第一個View消耗剩余空間的三分之二,而第二個View消耗三分之一。如果你又添加了第三個View,它的 比重 是1,那么現(xiàn)在第一個View將會獲得剩余空間的一半,另外兩個則是四分之一。
默認所有的View的
比重
是0,所以如果你僅對一個View的
比重
定義為大于0的任何數(shù),那么這個View將會拿到剩余的所有空間,而其他View則僅擁有他們所需要的空間。所以,為了讓
EditText
把剩余空間填滿,把它的
比重
設(shè)置為1,同時讓按鈕沒有
比重
就可以實現(xiàn)了。
<
EditText
android:layout_weight
="1"
...
/>
當(dāng)你定義了
比重
時,為了提高布局的效率,我們把
EditText
的寬度設(shè)置為0(0dp)。將寬度設(shè)置為0有利于提高布局性能,因為使用"
wrap_content
"作為寬度的話需要系統(tǒng)計算控件的寬度,而這是不必要的,因為這個寬度值需要另一個控件的寬度計算結(jié)果,以此來進一步的填滿屏幕的寬度。
<
EditText
android:layout_weight
="1"
android:layout_width
="0dp"
...
/>
圖3展示了把
比重
全部分配給
EditText
后的運行結(jié)果:
圖3.?
EditText
擁有了布局的所有
比重
,所以它填滿了
LinearLayout
剩余的空間
現(xiàn)在,修改后的布局文件應(yīng)該是這樣的:
<?
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
>
這個布局將會被當(dāng)你創(chuàng)建項目工程時,SDK工具生成的默認 Activity 類所應(yīng)用,現(xiàn)在你可以運行這個應(yīng)用來看看結(jié)果:
- 在Eclipse中,點擊工具欄中的“ 運行 ”。
- 或者在命令行下,將工作目錄切換至該Android項目的根目錄,然后執(zhí)行:
ant debug
adb install bin/MyFirstApp-debug.apk
?
下一節(jié)課程將會進一步學(xué)習(xí)按鈕的響應(yīng),從文本框中讀取數(shù)據(jù)和啟動一個新的 activity 等知識。
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

