W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
編寫(xiě):yuanfentiank789 - 原文:http://developer.android.com/training/basics/firstapp/building-ui.html
在本小節(jié)里,我們將學(xué)習(xí)如何用 XML 創(chuàng)建一個(gè)帶有文本輸入框和按鈕的界面。下一節(jié)課將學(xué)會(huì)使 APP 對(duì)按鈕做出響應(yīng)——按鈕被按下時(shí),文本框里的內(nèi)容被發(fā)送到另外一個(gè) Activity。
Android 的圖形用戶界面由多個(gè)視圖(View)和視圖組(ViewGroup)構(gòu)建而成。View 是通用的 UI 窗體小組件,如:按鈕(Button)、文本框(Text field);而 ViewGroup 則是用來(lái)定義子視圖布局的不可見(jiàn)的容器,如:網(wǎng)格部件(grid)、垂直列表部件(vertical list)。
Android 提供了一系列對(duì)應(yīng)于 View 和 ViewGroup 子類的 XML 標(biāo)簽,以便我們用 XML 創(chuàng)建自己的 UI。
Layouts 是 ViewGroup 的子類。我們將在接下來(lái)的教程中練習(xí)如何使用 LinearLayout。
圖 1 關(guān)于 ViewGroup 對(duì)象如何組織布局分支和包含其他 View 對(duì)象。
可選的布局文件
有很多理由使得我們選擇在 XML 中定義界面布局,而不是在運(yùn)行時(shí)動(dòng)態(tài)生成布局。其中最重要的一點(diǎn)是——這可以讓你為不同大小的屏幕創(chuàng)建不同的布局文件。例如,你可以創(chuàng)建兩個(gè)版本的布局文件,告訴系統(tǒng)在小屏幕上使用其中一個(gè)布局文件,在大屏幕上使用另外一個(gè)布局文件。參見(jiàn) 兼容不同的設(shè)備。
在 Android Studio 中,從 res/layout
目錄打開(kāi) content_my.xml
文件。
上一節(jié)創(chuàng)建新項(xiàng)目時(shí)生成的 BlankActivity 包含一個(gè) content_my.xml
文件,該文件根元素是一個(gè)包含 TextView 的 RelativeLayout。
在 Preview 面板點(diǎn)擊 關(guān)閉右側(cè) Preview 面板。
在 Android Studio 中打開(kāi)布局文件時(shí),可以看到一個(gè) Preview 面板。點(diǎn)擊這個(gè)面板中的標(biāo)簽,可利用 WYSIWYG(所見(jiàn)即所得)工具在 Design 面板看到對(duì)應(yīng)的圖形化效果。但在本節(jié)中,我們將學(xué)習(xí)如何直接修改 XML 文件。
刪除 [<TextView>] 標(biāo)簽。
把 [<RelativeLayout>] 標(biāo)簽改為 [<LinearLayout>]。
為 [<LinearLayout>] 添加 android:orientation 屬性并設(shè)置值為 "horizontal"
。
去掉 android:padding
屬性和 tools:context
屬性。
修改后結(jié)果如下:
res/layout/content_my.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/activity_my">
LinearLayout 是 ViewGroup 的子類,用于放置水平或者垂直方向的子視圖部件,放置方向由屬性 android:orientation 決定。LinearLayout 里的子布局按照 XML 里定義的順序顯示在屏幕上。
所有的 Views 都會(huì)用到 android:layout_width 和 android:layout_height 這兩個(gè)屬性來(lái)設(shè)置自身的大小。
由于 LinearLayout 是整個(gè)視圖的根布局,所以通過(guò)指定 width 和 height 屬性為 "match_parent"
可以使其寬度和高度充滿整個(gè)屏幕。該值表示子 View 擴(kuò)張自己寬度和高度來(lái) 匹配 父控件的寬度和高度。
更多關(guān)于布局屬性的內(nèi)容,請(qǐng)參考 布局向?qū)?/a>。
與其它 View 一樣,我們需要定義 XML 里的某些屬性來(lái)指定 EditText 的屬性值。以下是應(yīng)該在線性布局里指定的一些屬性元素:
在 content_my.xml
文件的 [<LinearLayout>] 標(biāo)簽內(nèi)定義一個(gè) [<EditText>] 標(biāo)簽,并設(shè)置 id
屬性為 @+id/edit_message
。
設(shè)置 layout_width
和 layout_height
屬性為 wrap_content
。
設(shè)置 hint
屬性為一個(gè)名為 edit_message
的字符串。
代碼如下:
res/layout/content_my.xml
<EditText android:id="@+id/edit_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/edit_message" />
各屬性說(shuō)明:
這是視圖的唯一標(biāo)識(shí)符??梢栽诔绦虼a中通過(guò)該標(biāo)識(shí)符引用對(duì)象。例如對(duì)這個(gè)對(duì)象進(jìn)行讀和修改的操作(在下一課里將會(huì)用到)。
當(dāng)需要從 XML 里引用資源對(duì)象時(shí),必須使用 @
符號(hào)。緊隨 @
之后的是資源的類型(這里是 id
),然后是資源的名字(這里使用的是 edit_message
)。
+
號(hào)只在第一次定義一個(gè)資源 ID 的時(shí)候需要。它是告訴 SDK——此資源 ID 需要被創(chuàng)建。在應(yīng)用程序被編譯之后,SDK 就可以直接使用這個(gè) ID。edit_message 是在項(xiàng)目文件 gen/R.java
中創(chuàng)建一個(gè)新的標(biāo)識(shí)符,這個(gè)標(biāo)識(shí)符和 EditText 關(guān)聯(lián)。一旦資源 ID 被創(chuàng)建了,其他資源如果引用這個(gè) ID 就不再需要 +
號(hào)。
不建議指定寬度和高度的具體尺寸,應(yīng)使用 "wrap_content"
。因?yàn)檫@樣可以保證視圖只占據(jù)內(nèi)容大小的空間。如果你使用了 "match_parent"
,這時(shí) EditText 將會(huì)布滿整個(gè)屏幕,因?yàn)樗鼘⑦m應(yīng)父布局的大小。參見(jiàn) 布局向?qū)?/a>。
當(dāng)文本框?yàn)榭盏臅r(shí)候,會(huì)默認(rèn)顯示這個(gè)字符串。對(duì)于字符串 "@string/edit_message"
的值所引用的資源應(yīng)該定義在單獨(dú)的文件里,而不是直接使用字符串。因?yàn)槭褂玫闹凳谴嬖诘馁Y源,所以不需要使用 +
號(hào)。當(dāng)然,由于你現(xiàn)在還沒(méi)有定義字符串,所以在添加 @string/edit_message
的時(shí)候會(huì)出現(xiàn)編譯錯(cuò)誤。在下一節(jié)的教程中你將學(xué)會(huì)如何定義字符串資源,到時(shí)候就不會(huì)報(bào)錯(cuò)了。
資源對(duì)象
資源對(duì)象是與 APP 資源(如:位圖、布局文件、字符串)關(guān)聯(lián)的唯一整數(shù)。
在項(xiàng)目文件
gen/R.java
中,每個(gè)資源都有一個(gè)與之對(duì)應(yīng)的資源對(duì)象。你可以使用R
類中的對(duì)象名稱代指資源(如:在指定 android:hint 屬性時(shí)需要的字符串)。同時(shí),也可以通過(guò) android:id 屬性隨時(shí)為 View 創(chuàng)建資源 ID,以便在代碼中引用這個(gè) View。每次編譯 APP 時(shí),SDK 工具都會(huì)生成
R.java
文件。所以,請(qǐng)永遠(yuǎn)不要修改這個(gè)文件。參閱 資源配備。
注:該字符串資源與 ID 使用了相同的名稱(
edit_message
)。然而,對(duì)于資源的引用是區(qū)分類型的(比如id
和字符串
),因此,使用相同的名稱不會(huì)引起沖突。
默認(rèn)情況下,你的 Android 項(xiàng)目包含一個(gè)字符串資源文件,即 res/values/string.xml
。打開(kāi)這個(gè)文件,為 "edit_message"
增加一個(gè)定義,其值為“Enter a message”。
在 Android Studio 里,編輯 res/values
下的 strings.xml
文件。
添加一個(gè)名為 "edit_message"
的字符串,值為“Enter a message”。
再添加一個(gè)名為 "button_send"
的字符串,值為“Send”。
下一節(jié)中將使用這個(gè)字符串創(chuàng)建按鈕。
下邊就是修改好的 res/values/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="action_settings">Settings</string>
</resources>
當(dāng)你在用戶界面定義一個(gè)文本時(shí),應(yīng)該把每一個(gè)文本字符串列入資源文件。這樣做的好處是:對(duì)于所有字符串值,字符串資源能夠單獨(dú)的修改,在資源文件里你可以很容易的找到并且做出相應(yīng)的修改。通過(guò)選擇定義每個(gè)字符串,還允許你用不同語(yǔ)言本地化 APP。
更多關(guān)于不同語(yǔ)言本字符串資源本地化的問(wèn)題,請(qǐng)參考 兼容不同的設(shè)備。
在 Android Studio 里,編輯 res/layout
下的 content_my.xml
文件。
在 [<LinearLayout>] 內(nèi)部的 [<EditText>] 標(biāo)簽之后定義一個(gè) [<Button>] 標(biāo)簽。
設(shè)置按鈕的 width 和 height 屬性值為 "wrap_content"
以便讓按鈕的大小能完整顯示文字。
定義按鈕的文本使用 android:text 屬性,設(shè)置值為相似上一節(jié)中定義好的 button_send
字符串資源。
此時(shí)的 [<LinearLayout>] 看起來(lái)應(yīng)該是這樣:
res/layout/content_my.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/activity_my">
<EditText android:id="@+id/edit_message"
android:layout_width="wrap_content"
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>
注:寬和高被設(shè)置為
"wrap_content"
,這時(shí)按鈕占據(jù)的大小就是按鈕里文本的大小。這個(gè)按鈕不需要指定 android:id 的屬性,因?yàn)?Activity 代碼中不會(huì)引用該 Button。
當(dāng)前 EditText 和 Button 部件只是適應(yīng)了他們各自內(nèi)容的大小,如圖 2 所示:
圖 2 EditText 和 Button 窗體小組件使用 "wrap_content"
作為寬度屬性的值。
這樣設(shè)置對(duì)按鈕來(lái)說(shuō)很合適,但是對(duì)于文本框來(lái)說(shuō)就不太好了,因?yàn)橛脩艨赡茌斎敫L(zhǎng)的文本內(nèi)容。因此如果能夠占滿整個(gè)屏幕寬度會(huì)更好。LinearLayout 使用 權(quán)重 屬性達(dá)到這個(gè)目,即 android:layout_weight 屬性。
權(quán)重的值指的是每個(gè)部件所占剩余空間的大小,該值與同級(jí)部件所占空間大小有關(guān)。這就類似于飲料的成分配方:“兩份伏特加酒,一份咖啡利口酒”,即該酒中伏特加酒占三分之二。例如,我們定義一個(gè)權(quán)重為 2 的 View,另一個(gè) View 的權(quán)重是 1,那么總數(shù)就是 3;這時(shí)第一個(gè) View 占據(jù) 2/3 的空間,第二個(gè)占據(jù) 1/3 的空間。如果再加入第三個(gè) View,權(quán)重設(shè)為 1,那么第一個(gè) View(權(quán)重為 2 的)會(huì)占據(jù) 1/2 的空間,剩余的另外兩個(gè) View 各占 1/4。(請(qǐng)注意,使用權(quán)重的前提一般是給 View 的寬或者高的大小設(shè)置為 0dp,然后系統(tǒng)根據(jù)上面的權(quán)重規(guī)則來(lái)計(jì)算 View 應(yīng)該占據(jù)的空間。但在很多情況下,如果給 View 設(shè)置了 match_parent 的屬性,那么在計(jì)算權(quán)重時(shí)則不是通常的正比,而是反比。也就是說(shuō),權(quán)重值大的反而占據(jù)空間?。?。
對(duì)于所有的 View 默認(rèn)的權(quán)重是 0,如果只設(shè)置了一個(gè) View 的權(quán)重大于 0,則該 View 將占據(jù)除去別的 View 本身占據(jù)的空間的所有剩余空間。因此這里設(shè)置 EditText 的權(quán)重為 1,使其能夠占據(jù)除了按鈕之外的所有空間。
為讓 EditText 充滿剩余空間,做如下操作:
在 content_my.xml
文件里,設(shè)置 [<EditText>] 的 layout_weight
屬性值為 1
。
設(shè)置 [<EditText>] 的 layout_width
值為 0dp
。
res/layout/content_my.xml
<EditText
android:layout_weight="1"
android:layout_width="0dp"
... />
為了提升布局的效率,在設(shè)置權(quán)重時(shí),應(yīng)該把 EditText 的寬度設(shè)為 0dp。如果設(shè)置寬度為 "wrap_content"
,系統(tǒng)需要計(jì)算這個(gè)部件所占用的寬度;而此時(shí)的 EditText 因?yàn)樵O(shè)置了權(quán)重,所以會(huì)占據(jù)剩余空間;所以,最終導(dǎo)致的結(jié)果是:EditText 的寬度成了不起作用的屬性。
設(shè)置 EditText 權(quán)重后的效果如圖 3:
圖 3 因 EditText 窗體小組件被設(shè)置了全部權(quán)重,所以占據(jù)了 LinearLayout 的剩余空間。
現(xiàn)在看一下完整的布局文件內(nèi)容:
res/layout/content_my.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/activity_my">
<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>
整個(gè)布局默認(rèn)被應(yīng)用于創(chuàng)建項(xiàng)目的時(shí)候 SDK 工具自動(dòng)生成的 Activity,運(yùn)行看下效果:
在 Android Studio 里,點(diǎn)擊工具欄里的 Run 按鈕 。
或者使用命令行,進(jìn)入你項(xiàng)目的根目錄直接執(zhí)行:
$ ant debug
adb install -r app/build/outputs/apk/app-debug.apk
下一小節(jié)將學(xué)習(xí)有關(guān)如何對(duì)按鈕做出相應(yīng),同時(shí)讀取文本中的內(nèi)容,啟動(dòng)另外一個(gè) Activity 等。
下一節(jié):?jiǎn)?dòng)另一個(gè) Activity
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: