Android SDK上手指南:用戶(hù)界面設(shè)計(jì)
譯文內(nèi)容簡(jiǎn)介
我們將為應(yīng)用程序項(xiàng)目添加布局方案,在這方面XML與Eclipse ADT接口將成為工作中的得力助手——不過(guò)在后面兩節(jié)中還會(huì)用到一部分Java開(kāi)發(fā)知識(shí)。XML與Java在Android平臺(tái)的開(kāi)發(fā)工作當(dāng)中可謂無(wú)處不在,如果大家對(duì)二者還缺乏基本的了解,請(qǐng)盡快想辦法補(bǔ)補(bǔ)課。對(duì)于剛剛?cè)腴T(mén)的讀者朋友來(lái)說(shuō),本文所介紹的要點(diǎn)將成為各位日后開(kāi)發(fā)工作的重要基礎(chǔ)。
1. XML基礎(chǔ)知識(shí)
在我們開(kāi)始討論布局之前,先來(lái)梳理作為標(biāo)記語(yǔ)言的XML的基礎(chǔ)知識(shí)。如果大家對(duì)于XML已經(jīng)很熟悉,可以直接跳過(guò)本節(jié)。XML是一種用于保存數(shù)據(jù)值的語(yǔ)言。XML文件在多個(gè)領(lǐng)域發(fā)揮作用。它們?cè)谀承╉?xiàng)目中的功能與數(shù)據(jù)庫(kù)非常相近,而且通常被作為網(wǎng)頁(yè)的輸出機(jī)制。如果大家之前曾經(jīng)使用過(guò)HTML,應(yīng)該會(huì)對(duì)XML的基本功能感到熟悉。
在XML中,數(shù)據(jù)值被保存在元素當(dāng)中。單一元素通常包含一個(gè)開(kāi)始標(biāo)記與一個(gè)結(jié)束標(biāo)記,如下所示:
- <product>Onion</product>
如大家所見(jiàn),開(kāi)始標(biāo)記與結(jié)束標(biāo)記幾乎完全一樣,惟一的區(qū)別在于結(jié)束標(biāo)記中多了一個(gè)“/”符號(hào)。在上面的例子中,數(shù)據(jù)值也就是元素內(nèi)容,即文本字符串“Onion”。開(kāi)始標(biāo)記也可以容納與數(shù)據(jù)項(xiàng)目相信的其它屬性信息,如下所示:
- <product type="vegetable">Onion</product>
每項(xiàng)屬性都有一個(gè)名稱(chēng)與一個(gè)值,其中值就是引號(hào)內(nèi)的部分。元素中還可以包含其它元素:
- <section name="food"><font></font>
- <product type="vegetable">Onion</product><font></font>
- <product type="fruit">Banana</product><font></font>
- </section><font></font>
在這種結(jié)構(gòu)中,我們將section元素稱(chēng)為主元素、products元素則被稱(chēng)為子元素。兩個(gè)子元素之間屬于“兄弟關(guān)系”。在XML文檔當(dāng)中,必須存在一個(gè)root元素作為主元素,或者被稱(chēng)為“嵌套”。這就構(gòu)成了一種tree結(jié)構(gòu),其中子元素作為自主元素延伸出去的分支。如果某個(gè)子元素之下還包含其它子元素,那么它本身同時(shí)也具有主元素屬性。
大家還會(huì)遇到另一種自結(jié)束元素,其中開(kāi)始與結(jié)束標(biāo)記并非獨(dú)立存在:
- <order number="12345" customerID="a4d45s"/>
其中元素末尾的“/”符號(hào)代表結(jié)束。
我們?cè)贏ndroid平臺(tái)上所使用的全部資源文件都要用到XML標(biāo)記,其中包括布局文件、可繪制元素、數(shù)據(jù)值以及Manifest。
2. Android布局
第一步
當(dāng)大家在安裝了ADT的Eclipse IDE當(dāng)中使用XML時(shí),輸入過(guò)程中顯示的相關(guān)背景提示能讓編碼過(guò)程變得更輕松一些。在編輯器中打開(kāi)新應(yīng)用中的主布局文件,確保XML編輯標(biāo)簽已經(jīng)被選中,這樣我們就能直接對(duì)代碼進(jìn)行編輯了。我們首先要處理的是用于主屏幕的布局方案,用戶(hù)在啟動(dòng)應(yīng)用之后最先看到的就是它。Eclipse會(huì)提供一套基礎(chǔ)布局,供我們進(jìn)行個(gè)性化修改:
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"<font></font>
- xmlns:tools="http://schemas.android.com/tools"<font></font>
- android:layout_width="match_parent"<font></font>
- android:layout_height="match_parent"<font></font>
- android:paddingBottom="@dimen/activity_vertical_margin"<font></font>
- android:paddingLeft="@dimen/activity_horizontal_margin"<font></font>
- android:paddingRight="@dimen/activity_horizontal_margin"<font></font>
- android:paddingTop="@dimen/activity_vertical_margin"<font></font>
- tools:context=".MainActivity" ><font></font>
- <TextView<font></font>
- android:layout_width="wrap_content"<font></font>
- android:layout_height="wrap_content"<font></font>
- android:text="@string/hello_world" /><font></font>
- </RelativeLayout><font></font>
如大家所見(jiàn),root元素是一項(xiàng)布局元素,在上面的示例中為RelativeLayout。Android當(dāng)中還提供其它幾種布局類(lèi)型,我們可以將一種布局嵌套到另一種當(dāng)中。這里的root布局元素?fù)碛袔醉?xiàng)額外屬性且與布局效果密切相關(guān),例如寬度、高度以及邊距等等。布局元素當(dāng)中的TextView允許開(kāi)發(fā)人員顯示一條文本字符串。TextView是View的一種,View屬于可見(jiàn)及交互性元素,用以構(gòu)成我們的應(yīng)用程序UI。因此,應(yīng)用程序中的每套分屏方案都要選擇一種View,并在其中包含一種或者多種布局機(jī)制。在Android系統(tǒng)中,這些布局被稱(chēng)為ViewGroup對(duì)象,每個(gè)ViewGroup內(nèi)包含一套或者多套View。
第二步
為了專(zhuān)注于一套布局的基礎(chǔ)創(chuàng)建工作,我們要把主布局文件中的現(xiàn)有內(nèi)容全部刪掉,這樣才能從零開(kāi)始著手設(shè)計(jì)。正如我們之前所提到,大家可以利用Java代碼創(chuàng)建自己的布局或者View,不過(guò)Android上的多種工具允許開(kāi)發(fā)者利用XML設(shè)計(jì)自己的應(yīng)用UI——這樣各位就可以在創(chuàng)建元素的同時(shí)直接觀察設(shè)計(jì)效果了。在某些實(shí)例中,大家可能見(jiàn)過(guò)單純通過(guò)Java代碼創(chuàng)建一些或者全部UI的做法,但現(xiàn)實(shí)情況下大部分創(chuàng)建工作還是要由XML完成的。這種做法還能保證應(yīng)用程序邏輯與顯示元素彼此獨(dú)立。
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"<font></font>
- android:layout_width="fill_parent"<font></font>
- android:layout_height="fill_parent"<font></font>
- android:orientation="vertical" ><font></font>
- <!-- views go here --><font></font>
- </LinearLayout><font></font>
LinearLayout會(huì)沿橫向或者縱向顯示我們打算使用的View。在以上示例中顯示方向?yàn)榇怪?,因此每個(gè)View都會(huì)沿屏幕下方依次排列。如果采取橫向布局,那么各個(gè)View將由左至右依次排列。如果使用“layout width”與“layout height”兩種屬性(在Android當(dāng)中,它們往往被稱(chēng)為布局參數(shù)),那么布局會(huì)被拉伸至橫向與縱向的最大長(zhǎng)度。
在“layout height”聲明行之后再添加一條新行,通過(guò)鍵入“android:”準(zhǔn)備開(kāi)始輸入屬性。當(dāng)大家輸入對(duì)應(yīng)內(nèi)容,Eclipse就會(huì)提供一套與該屬性相關(guān)的列表。大家可以繼續(xù)輸入內(nèi)容以縮小屬性列表,也可以直接在列表中用鼠標(biāo)進(jìn)行點(diǎn)選?,F(xiàn)在我們選擇“android:gravity”屬性。
鍵入“center_horizontal”作為gravity值,這樣其中包含的元素就會(huì)以X軸為中心加以顯示:
- android:gravity="center_horizontal"
這種方式適用于布局中的一切元素。我們可以添加其它幾種額外顯示屬性,例如填充、邊距以及背景等。不過(guò)在今天的文章中,我們先從最簡(jiǎn)單的項(xiàng)目入手。
3. 添加View
第一步
正面我們開(kāi)始向布局中添加View。所謂View,是指UI當(dāng)中的可見(jiàn)元素。讓我們首先添加一些文本內(nèi)容和一個(gè)按鈕。進(jìn)入LinearLayout元素(在開(kāi)始忹結(jié)束標(biāo)記之間),輸入“<”之后Eclipse就會(huì)提示大家與屬性相關(guān)的可用元素列表。
在列表中選擇TextView。請(qǐng)注意,與大部分View一樣,這是一種自結(jié)束元素。為T(mén)extView設(shè)置兩種屬性,分別為layout width與layout height(鍵入‘android:’并選擇對(duì)應(yīng)提示):
- <TextView<font></font>
- android:layout_width="wrap_content"<font></font>
- android:layout_height="wrap_content" /><font></font>
通過(guò)“wrap_content”,我們可以保證View的寬度足以容納其顯示內(nèi)容——這就避免了像布局那樣以填充方式顯示元素?,F(xiàn)在再為T(mén)extView添加另一項(xiàng)屬性,這一次通過(guò)列舉文本字符串實(shí)現(xiàn)顯示功能:
- android:text="Hello there"
在保存文件之后,大家會(huì)看到Eclipse顯示出一條警告消息。如果將鼠標(biāo)懸停在消息之上,編輯器的邊框處將顯示該文本——這部分內(nèi)容也會(huì)同時(shí)顯示在Problem視圖當(dāng)中。警告內(nèi)容為“Hardcoded string……should use @string resource(硬編碼字符串……應(yīng)使用@string資源)。”系統(tǒng)推薦的做法是將每一個(gè)文本字符串值保存為一項(xiàng)值資源,而不應(yīng)將其直接包含在布局XML當(dāng)中。盡管從起步階段來(lái)看這樣的處理方式既麻煩又毫無(wú)意義,但一旦養(yǎng)成良好習(xí)慣、大家會(huì)在今后的工作中逐漸發(fā)現(xiàn)其在大型項(xiàng)目中的價(jià)值。通過(guò)Package Explorer找出“res/values/strings.xml”文件并打開(kāi),切換到“strings.xml”標(biāo)簽并對(duì)代碼進(jìn)行編輯。
可以看到,Eclipse已經(jīng)添加了幾條字符串。要另行添加,只需為其設(shè)定名稱(chēng)與值:
- <string name="hello">Hello there</string>
這意味著如果大家需要在應(yīng)用程序UI當(dāng)中不止一次使用同一條字符串,而且稍后又需要對(duì)其進(jìn)行修改,則只需在一處做出變更即可。保存字符串文件并切換到布局文件。將TextView的“text”屬性引用到值文件的對(duì)應(yīng)字符串中:
- android:text="@string/hello"
我們通過(guò)在字符串名稱(chēng)前加上“@string”的方式告知Android工具需要在哪里尋找字符串資源。這樣一來(lái),警告信息就不會(huì)再出現(xiàn)了。Eclipse通常會(huì)在我們編碼的過(guò)程中發(fā)出這些提醒,從而通知我們當(dāng)前存在的錯(cuò)誤或者警示問(wèn)題。大家可以選擇遵循或者忽略警告信息的內(nèi)容,但對(duì)于錯(cuò)誤則必須加以調(diào)整,否則應(yīng)用程序?qū)o(wú)法正常工作。
第二步
在TextView之后添加一個(gè)Button:
- <Button<font></font>
- android:layout_width="wrap_content"<font></font>
- android:layout_height="wrap_content"<font></font>
- android:text="@string/click" /><font></font>
在我們的示例中,Button使用的屬性與TextView相同。不過(guò)在其它情況下,它可能會(huì)使用更多屬性,而且一般來(lái)說(shuō)不同視圖需要配合不同屬性。按鈕上顯示的是“text”屬性值。將這條字符串同之前一樣添加到我們的“res/values/strings.xml”文件當(dāng)中:
- <string name="click">Click Me!</string>
在接下來(lái)的教程中,我們將處理按鈕的點(diǎn)擊效果。切換到布局文件,查看編輯器右側(cè)的Outline視圖——它顯示的是另一套指向文件元素的界面。雙擊列出的項(xiàng)目以跳轉(zhuǎn)到對(duì)應(yīng)代碼位置。大家也可以展開(kāi)或者折疊主元素。當(dāng)布局變得更加復(fù)雜時(shí),這種處理方式就變得非常實(shí)用。
提示:要整理Eclipse編輯中所打開(kāi)的全部文件,我們只需按下“Ctrl+A”對(duì)其進(jìn)行全選,然后按下“Ctrl+I”即可。
4. Graphical Layout
第一步
確保我們的布局文件已經(jīng)正確保存,然后切換到Graphical Layout標(biāo)簽。
大家可以看到自己所設(shè)計(jì)的布局已經(jīng)能夠直接查看。界面左側(cè)的Palette區(qū)域允許我們選擇UI項(xiàng)目并將其拖動(dòng)到布局當(dāng)中。不過(guò)我們應(yīng)該首先使用XML,直至對(duì)基本框架擁有初步概念。XML能幫助我們控制細(xì)節(jié)設(shè)計(jì),所以即使在使用圖形化工具的時(shí)候,我們也可能需要對(duì)XML結(jié)果進(jìn)行編輯。
在Graphical Layout視圖上方是一套下拉清單,我們可以從中選擇用于查看布局效果的設(shè)備類(lèi)型,其中也提供切換顯示方向及縮放效果的工具。大家需要在設(shè)計(jì)布局的過(guò)程中不斷利用Graphical Layout對(duì)效果加以控制。另外,這里也提供其它一些值得嘗試的布局元素與設(shè)置。
第二步
大家可能已經(jīng)注意到,在這一次的布局設(shè)計(jì)當(dāng)中可見(jiàn)元素的顯示位置與屏幕上邊緣靠得比較近。下面就來(lái)解決這個(gè)問(wèn)題。切換到XML編輯標(biāo)簽并向LinearLayout當(dāng)中添加邊距屬性:
- android:layout_margin="10dp"
我們使用“dp”來(lái)設(shè)置像素的獨(dú)立密度,這樣設(shè)計(jì)就會(huì)讓像素密度自動(dòng)與用戶(hù)設(shè)備相匹配。保存文件并切換到Graphical Layout以查看實(shí)際效果。
在我們進(jìn)行布局設(shè)計(jì)時(shí),Graphical Layout是一款非常實(shí)用的參考工具,但只能起到引導(dǎo)的效果。要了解我們的布局在應(yīng)用程序運(yùn)行時(shí)以怎樣的方式顯示、又能實(shí)現(xiàn)怎樣的功能,大家需要將其載入虛擬或者物理設(shè)備進(jìn)行實(shí)際難。我們會(huì)在后續(xù)文章中進(jìn)一步討論這個(gè)話(huà)題。
5. 選項(xiàng)
大家可以在應(yīng)用程序屏幕中包含各類(lèi)布局類(lèi)型以及View,但其基本處理方式都是一致的。我們前面所使用的是LinearLayout,但還有其它多種方案可供選擇,其中比較常見(jiàn)的有RelativeLayout、FrameLayout、AbsoluteLayout以及GridLayout。大家可以在LinearLayout Palette當(dāng)中找到這些類(lèi)型,建議各位放松心態(tài)、在自己的View中任意選擇并觀察其顯示效果。當(dāng)添加來(lái)自Graphical Layout工具的元素時(shí),請(qǐng)務(wù)必切換到XML以觀察新元素的加入會(huì)產(chǎn)生什么樣的標(biāo)記代碼。
Android平臺(tái)針對(duì)多種常見(jiàn)需求提供View方案,例如單選按鈕、復(fù)選框以及文本輸入?yún)^(qū)等。這些方案能夠大大節(jié)約我們需要手動(dòng)執(zhí)行的功能數(shù)量;但如果各位需要使用非自帶UI元素,則需要?jiǎng)?chuàng)建一個(gè)自定義View類(lèi)。一般來(lái)說(shuō),最好是在沒(méi)有其它選擇時(shí)再這樣處理,畢竟標(biāo)準(zhǔn)化UI元素在用戶(hù)設(shè)備上的表現(xiàn)更為可靠,同時(shí)也能節(jié)約開(kāi)發(fā)及測(cè)試的時(shí)間。
結(jié)論
在今天的教程中,我們討論了Android平臺(tái)上用戶(hù)界面布局的基本設(shè)計(jì)流程,但并未做深層次挖掘。在本系列文章的下一部分,我們將嘗試在應(yīng)用程序添加用戶(hù)交互元素、檢測(cè)并響應(yīng)按鈕點(diǎn)擊。接下來(lái),我們將著眼于同Android開(kāi)發(fā)關(guān)系最密切的Java相關(guān)概念,并進(jìn)一步探討應(yīng)用程序開(kāi)發(fā)過(guò)程中所涉及的要素及實(shí)踐方式。
原文鏈接:
http://mobile.tutsplus.com/tutorials/android/android-sdk-user-interface-design/
原文標(biāo)題:Android SDK: User Interface Design