chapter 3 使用 xml 描述使用者介面hscc.cs.nctu.edu.tw/~lincyu/android/chapter3.pdfchapter 3...

22
Chapter 3 使用 XML 描述使用者介面 作者: 林致孙 在第一章中,筆者已經提過 Android 的應用程式都是利用 Java 語言所完成的, 依筆者在學校的經驗發現,只要跟學生談到 Java ,不少人可能就決定要打退堂鼓 了,不過請讀者先別急著放棄,因為在這一章中,我們完全不會談論到 Java ,然 而我們卻可以寫出幾個程式,包含了學習一個新的程式語言時,常常會寫的第一 個程式 Hello World 。為什麼我們不需要改到 Java 程式便可完成 Hello World 的程 式呢?這是由於 Android 提供兩種建立使用者介面(User Interface)的方法:第一 是直接在程式中設計,第二則是透過以 XML(eXtensible Markup Language)為基礎 的版面設計描述檔來完成。在本章中,我們將詳細地介紹第二種方法。 3.1 XML 簡介 XML 與一般人較為熟知的 HTML (HyperText Markup Language)一樣是屬於標籤 語言的一種。然而 XML 有兩個很大的特點:自定標籤與良好格式。 3.1.1 自定標籤 XML 並不像 HTML 一樣有預設的標籤,例如<IMG>代表著要在網頁中插入一張 圖片、<A>代表著要加入一個超連結等。使用者必頇自己定義各種標籤,一個應 用程式可以自行定義一些標籤,而應用程式的使用者如果想跟應用程式做溝通, 就必頇去瞭解那個應用程式的自定標籤如何使用,例如一個通訊錄應用程式,定 義了<NAME>來表示連絡人姓名、 <TEL>來表示連絡人電話、 <ADDR>來表示連 絡人地址,此時若一個使用者希望應用程式讀進一筆連絡人資料,則使用者就必 頇按照應用程式所定義的標籤,寫出一個 XML 檔案。因此,至此我們應該可以 體驗得出來 XML 是用來描述資訊的內容所代表的意義,而不像 HTML 是用來顯 示資料。 Android 提供了以 XML 為基礎的方式來設計使用者介面的版面,因此 Android 也定義了一些標籤,例如<Button>表示要顯示一個按鈕元件、<ImageView>表示 要顯示一個圖片元件、<TextView>表示要顯示一個文字方塊元件,如同 HTML 的標籤一樣,標籤會有許多的屬性, <TextView>標籤有一個屬性為 android:text其是用來設定文字方塊裡面要顯示的文字內容,至此,我們便可以想像,我們只 要設計一個 XML 檔,使用<TextView>標籤,並將 android:text 屬性設成 Hello World我們就能夠在螢幕上顯示出 Hello World。這也說明了,我們真的可以不需要改 Java 的程式,便能夠寫出簡單的 Android 應用程式。

Upload: others

Post on 06-Jan-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Chapter 3 使用 XML描述使用者介面

作者: 林致孙

在第一章中,筆者已經提過 Android的應用程式都是利用 Java語言所完成的,

依筆者在學校的經驗發現,只要跟學生談到 Java,不少人可能就決定要打退堂鼓

了,不過請讀者先別急著放棄,因為在這一章中,我們完全不會談論到 Java,然

而我們卻可以寫出幾個程式,包含了學習一個新的程式語言時,常常會寫的第一

個程式 Hello World。為什麼我們不需要改到 Java程式便可完成 Hello World的程

式呢?這是由於 Android提供兩種建立使用者介面(User Interface)的方法:第一

是直接在程式中設計,第二則是透過以 XML(eXtensible Markup Language)為基礎

的版面設計描述檔來完成。在本章中,我們將詳細地介紹第二種方法。

3.1 XML簡介

XML與一般人較為熟知的 HTML (HyperText Markup Language)一樣是屬於標籤

語言的一種。然而 XML有兩個很大的特點:自定標籤與良好格式。

3.1.1 自定標籤

XML並不像 HTML一樣有預設的標籤,例如<IMG>代表著要在網頁中插入一張

圖片、<A>代表著要加入一個超連結等。使用者必頇自己定義各種標籤,一個應

用程式可以自行定義一些標籤,而應用程式的使用者如果想跟應用程式做溝通,

就必頇去瞭解那個應用程式的自定標籤如何使用,例如一個通訊錄應用程式,定

義了<NAME>來表示連絡人姓名、<TEL>來表示連絡人電話、<ADDR>來表示連

絡人地址,此時若一個使用者希望應用程式讀進一筆連絡人資料,則使用者就必

頇按照應用程式所定義的標籤,寫出一個 XML檔案。因此,至此我們應該可以

體驗得出來 XML是用來描述資訊的內容所代表的意義,而不像 HTML是用來顯

示資料。

Android提供了以 XML為基礎的方式來設計使用者介面的版面,因此 Android

也定義了一些標籤,例如<Button>表示要顯示一個按鈕元件、<ImageView>表示

要顯示一個圖片元件、<TextView>表示要顯示一個文字方塊元件,如同 HTML

的標籤一樣,標籤會有許多的屬性,<TextView>標籤有一個屬性為 android:text,

其是用來設定文字方塊裡面要顯示的文字內容,至此,我們便可以想像,我們只

要設計一個XML檔,使用<TextView>標籤,並將android:text屬性設成Hello World,

我們就能夠在螢幕上顯示出 Hello World。這也說明了,我們真的可以不需要改

到 Java的程式,便能夠寫出簡單的 Android應用程式。

3.1.2 良好格式

XML另外一個跟 HTML很不一樣的特點是:XML需要有良好的格式。在 HTML

中,有時忘了加上結尾標籤,瀏覽器仍然能夠正常的讀取檔案並顯示內容,然而

在 XML中,每個標籤一定要有結尾標籤,例如使用了<Button>這個標籤,後頭

就需要有一個</Button>標籤,若標籤為沒有結尾標籤的單獨標籤,則在「>」符

號前必頇要有「/」符號。

若我們使用 Eclipse整合開發環境,則在編寫 XML檔時,會適度地幫我們做檢

查,例如在下圖中,<TextView>標籤因為沒有適當的結尾標籤</TextView>且「>」

符號前也沒有「/」符號,因此 Eclipse幫我們以紅線標示出來,此時若將滑鼠游

標移至紅線處,會出現「遺失結尾標籤」的提示訊息。

由於本書的目的並不是介紹 XML,對於 XML的說明只到此為止,對於 XML想

更深入瞭解的讀者可自行參閱相關書籍。事實上,在閱讀本書時,即使讀者對

XML並沒有深入的瞭解,只要讀者對於 HTML有一定程度的瞭解,並能瞭解上

述所提的 XML特點,便足以瞭解本書的內容。接下來我們就要示範如何寫出

Hello World。

3.2 Hello World

3.2.1 建立新專案

在這一節中,我們將一步一步的示範如何完成 Hello World這個程式,首先我們

先開啟一個新的專案(FileNewAndroid Project),如下圖所示,由於這是一個

新建的專案,我們選擇「Create new project in workspace」,有幾個欄位是需要解

說的:

Project name

代表此專案的名稱,Eclipse會於Workspace的目錄下建立一個跟 Project

name同名的資料夾,因此只要是一個可以用來命名資料夾的字串都可以當

作 Project name。而像「X?Y」因為問號並不是命名資料夾的一個合法字元,

因此也就不能夠在 Project name中使用。事實上,當使用者輸入合法的專案

名稱,Eclipse才會允許使用者按下「Finish」按鈕。

Target Name

設定目標平台,Android 1.5代表能夠支援 Android SDK 1.5的模擬器或硬體

裝置,如果要使用 Google Map相關的功能,則要選擇 Google APIs,這是因

為 Google Map 函式庫是個選擇性的 API,我們在後面的章節會有更詳細的

介紹。

Application name

這是顯示在手機上的應用程式名稱,可以是任意字串,甚至允許特殊符號。

當您的應用程式安裝至手機後,便可以看到應用程式的圖示(Icon)以及此應

用程式名稱。

Package name

Package name是應用程式安裝在手機後的檔案名稱,跟 Java的套件名稱一

樣,採用網域名稱(Domain name)的形式來命名,以「.」符號做區隔,至少

需要有兩個項目。

Activity name

Activity在 Android系統中是一個重要的概念,我們會在後面章節做詳細的

介紹,在此我們先只要瞭解 Activity name會成為 Java程式裡某一個類別的

類別名稱,因此命名時必頇遵孚 Java對於類別名稱的命名規則。

3.2.2 專案目錄架構

建立好新專案後,我們可在 Eclipse開發環境的左側(Package Explorer)將專案相

關的資料夾打開(點下「+」符號,使它成為「-」符號),如下圖所示,接下來,

筆者將對重要的幾個目錄做說明:

src/

放置 Java原始碼的資料夾。實際存放在磁碟的資料夾會根據其套件名稱來

決定。

gen/

此處放置的 Java原始碼是自動產生並更新的,使用者並不需要去修改它,

我們會在後面章節做更詳細的說明。

res/

放置資源(resource)的資料夾,裡面有分成幾個子資料:

drawable: 應用程式中會使用到的圖檔通常會放置在此資料夾內。

layout: 版面設計描述檔的存放資料夾,先前我們已經提過,Android允

許我們以 XML來設計使用者介面,相關的 xml檔即放在此資料夾內。

本章我們便會學習如何修改此資料夾內的檔案來達成版面的設計。

values: 此目錄內已建立的 strings.xml是一個允許我們定義一些字串資

源的地方。事事上,除了字串,我們也可定義顏色、尺寸、樣式等資源,

後面的章節會有更詳細的介紹。在本章中,我們也會嘗詴去修改

strings.xml。

AndroidManifest.xml

此為一個 XML檔案,這個檔案描述了此應用程式所提供的服務,以及會使

用到其它程式的哪些服務,會在後面的章節做更詳細的說明。

3.2.3 Hello World

接下來我們終於可以開始設計第一個程式了,在這個程式中我們希望在手機的螢

幕顯示出 Hello World這個字串,因此我們希望版面上有一個類似文字方塊的元

件,而文字方塊的內容則顯示 Hello World。

Android提供了許多介面元件(View),一個畫面通常是由數個介面元件所組成的,

以下圖為例,這個校園導覽應用程式的主畫面包含了三個介面元件,首先是用來

顯示上方圖片的圖片元件(ImageView),再來是顯示作者資料的文字元件

(TextView) ,最後是一個啟動導覽系統的按鈕元件(Button) 。在本節中我們將學

習如何利用文字介面元件(TextView)來顯示 Hello World。

首先我們開啟 res/layout下的 main.xml,並將內容修改成如下:

1 <?xml version="1.0" encoding="utf-8"?>

2 <TextView xmlns:android="http://schemas.android.com/apk/res/android"

3 android:layout_width="fill_parent"

4 android:layout_height="wrap_content"

5 android:text="My Hello World Program!"

6 />

接著我們就來解說這個 XML檔,第 1行是定義此 XML文件的版本和使用的字

碼集,在開發 Android應用程式時,通常我們不需要修改它,第 2行的 TextView

即為 Android自定的標籤,代表要加入一個能夠顯示文字的介面元件,這個標籤

有四個屬性,第一個屬性 xmlns是宣告名稱空間(namespace),在同一個 XML元

素的範圍內,只需要在根元素宣告一次即可,由於在此 XML檔中,TextView是

根元素,因此需要宣告名稱空間,更多關於名稱空間的說明可參閱 XML相關書

籍。我們在此只要知道,與 Android相關的 XML檔案,其根元素都必頇加上此

屬性。

接著,第 3行 android:layout_width屬性代表文字介面元件的寬度,值 fill_parent

則代表填滿可以顯示的空間,其它可能的值還有 wrap_content,其代表依照內容

決定大小,當然也可填上數字,如 100dip等。第 4行 android:layout_height屬性

則代表了文字介面元件的高度。第 5行 adnroid:text屬性則代表文字介面元件要

顯示的文字內容。讀者如果想知道TextView更多的屬性及其用法,可參閱Android

SDK的文件說明。最後別忘了 3.1節中所說的,XML必頇有個結尾標籤,此處

我們使用「/>」來告知這是一個沒有結尾標籤的單獨標籤。

接著,我們就可以開始編譯並執行此程式,在 Eclipse的選單下,執行

RunAndroid Application就可以執行應用程式,如果沒有事先開啟模擬器,

Eclipse會幫我們開啟,模擬器成功開機後,您就可在畫面上看到My Hello World

Program!。我們是不是沒有修改到任何的 Java程式碼就完成了我們的第一個程式

了呢?

現在我們已經完成了第一個程式了,然而讀者可能產生幾個疑問,第一個疑問是

Android提供了哪些 View讓我們使用?在 Android SDK的網站上可找到各種可

用介面元件的列表,在下一節中我們將介紹幾個常用的 View。第二個疑問是,

當我們想在一個螢幕上 顯示多個 View時 (例如在先前所提的校園導覽的主畫

面中,我們看到了三個 View),我們如何安排這些 View的呈現方式?這個問題

我們將在 3.4節中得到解答,我們學習到幾個概念,如View Hierarchy、View Group、

Layout等。

3.3 各種介面元件(View)

在介紹各種介面元件之前,我們先跟大家介紹 Android SDK提供的 ApiDemos這

個應用程式,先開啟一個新的專案(FileNewAndroid Project),然而這一次我

們不是選擇「Create new projects in workspace」,而是選擇「Create project from

existing source」,接著在「Location」的選項,將 AipDemos的存放路徑填上,此

處以 Android 1.6 Platform為例,AipDemos是存在放 SDK目錄下的

/platforms/android-1.6/samples/ApiDemos,請依自己的版本做適當的調整,若找

不到 ApiDemos所在目錄時,可利用作業系統中尋找檔案的功能,搜尋字串使用

「ApiDemos」。

接著於模擬器上執行 ApiDemos,在主畫面中我們會看到如下圖的一個列表,我

們選擇 Views,進去後,讀者可以自行去體驗各種的介面元件,而若想觀看其程

式碼,ApiDemos這個 Project於 Eclipse的 src目錄下尋找,為了不給大家太多的

負擔與恐懼,我們先跳過此部份。接下來,我們將只介紹兩個常用的介面元件,

第一個是 ImageView,筆者希望藉著 ImageView的範例,讓讀者瞭解資源索引檔

的相關概念,第二個則是 Button,筆者希望藉著 Button的範例,告訴讀者為什

麼我們最後還是要回到 Java設計程式。

3.3.1 ImageView

在學校教授程式語言,會發現現在的學生都被漂亮的圖形介面寵壞了,因此在學

習程式語言時,如果只是出現冷冰冰的文字,一定很難激起學習的欲望。所以,

我們第二個程式就來建立一個能夠顯示圖片的介面元件(ImageView)。

讀者可以開啟一個新的專案,而在修改 XML檔案之前,我們必頇先在

res/drawable/目錄下放入我們所要顯示的圖檔,在此筆者放入了一個檔名為

asialogo.png的圖檔,接著到 res/layout/的目錄下修改 main.xml,將其內容修改成

如下所示:

1 <?xml version="1.0" encoding="utf-8"?>

2 <ImageView xmlns:android=

3 "http://schemas.android.com/apk/res/android"

4 android:layout_width="fill_parent"

5 android:layout_height="wrap_content"

6 android:src="@drawable/asialogo"

7 />

我們比較感到陌生的,應該只有第 7行,android:src屬性是用來指定圖檔的來源,

其值@drawable/asialog代表系統會讀取識別名稱為 asialog的圖檔資源,讀者可

以嘗詴開啟 gen/目錄下的 R.java,這個檔案是所有資源檔案的索引,我們可以發

現 R類別中,又定義了一個 drawable類別,裡面有一行類似這樣的程式碼:

public static final int asialogo=0x7f020000;

對於 Java稍有瞭解的讀者,可以知道 asialogo是 drawable類別的成員變數,此

變數可以被其它套件的類別所存取(public),我們不需要建立一個 R類別的物件

便能使用此變數(static),此變數的值不能再被修改(final),此變數的資料型別為

整數(int)。如果對上面的說明完全不瞭解的讀者,仍然可以繼續地往下讀,筆者

列出此行程式碼只是想告訴讀者,為何我們使用的是@drawable/asialogo而不是

@drawable/asialogo.png,這是因為系統幫我們建立的資源索引的變數名稱是

asialogo。這邊有兩件事情要提醒讀者:(1) R.java是系統自動產生的檔案,我們

是不需要去修改它的,(2) 當 drawable的目錄存在一個 asialogo.png時,您就不

能再放入一個 asialogo.jpg,事實上當您嘗詴放入時,Eclipse也會顯示錯誤訊息。

關於更多 R類別的說明,可參閱 Android SDK的文件。

修改完 main.xml之後,只要編譯與執行,模擬器便會顯示您所放上的圖片。

為了對資源索引的概念做更進一步的解說,我們嘗詴去修改第一個 Hello World

程式,首先我們開啟 res/values/目錄下的 strings.xml,將其內容改成如下所示:

1 <?xml version="1.0" encoding="utf-8"?>

2 <resources>

3 <string name="app_name">Hello World!</string>

4 <string name="myhelloworld">My Hello World Program!</string>

5 </resources>

第 3行 app_name所指的字串,其實就是我們在建立新專案時所填寫的Application

name,第 4行我們定義了一個新的字串,並設定一個值給 name屬性。改完之後,

我們再開啟 R.java,我們發現 R類別下有一個 string類別,而 myhelloworld則是

string類別的一個成員變數,此時若我們要在 main.xml中存取此字串,可仿傚讀

取圖檔的方式,使用@string/myhelloword。亦即,原本「android:text="My Hello

World Program!"」那一行改成

「android:text="@string/myhelloworld"」。使用這種分離字串的設計方式有個優點

是,使用者的程式可以很容易地支援多國語言,我們在 res/目錄下建立新的資料

夾,資料夾的名稱必頇與您要支援的語言相符,讀者可參見下表:

語言 資料夾名稱

繁體中文 values-zh-rTW

簡體中文 values-zh-rCN

日文 values-ja

英式英文 values-en-rUK

美式英文 values-en-rUS

在此,我們建立 values-zh-rTW與 values-ja這兩個新的資料夾,並且把原本位於

values下的 strings.xml分別複製到這兩個新的資料夾,如下圖所示:

然後將位於 values-zh-rTW內的 strings.xml中的第 4行改成「<string

name="myhelloworld">您好,世界!</string>」(注意:您完全不需要更改 name

屬性的值),再將 values-ja內的 strings.xml中的第 4行改成「<string

name="myhelloworld">こんにちは世界</string>」。完成後便可編譯並執行,執行

後我們發現仍然是英文的,此時,在模擬器內先退出我們的程式,選擇

SettingsLocale & textSelect localeChinese (Taiwan),選擇完後,我們發現整

個手機的介面已全部換成中文,這時再度執行我們的程式時,就會出現「您好,

世界!」。類似的操作,當語言選擇日文時,就會出現「こんにちは世界」。最後

要提醒的是,由於我們並沒有修改 name屬性的值,因此我們不需要修改

main.xml。

3.3.2 Button

接著,我們再介紹一個簡單且常用的介面元件:按鈕(Button)。我們可以先建立

一個新專案,然後修改 main.xml,將原本的內容修改成如下所示:

1 <?xml version="1.0" encoding="utf-8"?>

2 <Button xmlns:android="http://schemas.android.com/apk/res/android"

3 android:layout_width="wrap_content"

4 android:layout_height="wrap_content"

5 android:layout_gravity="center"

6 android:text="This is a button"

7 />

相信讀者對於前 4行程式都已經相當瞭解,第 5行 android:layout_gravity屬性的

值為 center,這代表著這個按鈕會被放在顯示區域的正中央,由於目前的可顯示

區域是整個螢幕,因此這個按鈕會出現在螢幕的正中央。而第 6行 android:text

則是代表著要顯示在按鈕上的文字,能夠舉一反三的讀者應該可以馬上想得到,

我們亦可以使用前一小節所提到的方法,將按鈕上的顯示文字定義在 strings.xml

中,例如在 strings.xml中增加一行「<string name="btn_text">This is a

button</string>」接著將第 6行改成「@string/btn_text」也會呈現相同的結果。下

面即為程式的執行畫面:

到目前為止,我們已經初步瞭解如何於 XML檔案內,加入一個介面元件,然而

也出現了兩個需要解決的問題。第一個問題是,我們通常會希望一個畫面中有一

個以上的介面元件,例如在先前提到的校園導覽主畫面中,我們有一個

ImageView顯示學校的 Logo,一個 TextView顯示設計者資訊,一個 Button讓使

用者按下,當有多個介面元件需要同時顯示時,如何安排各元件的位置?這我們

會在下一節「版面設計(Layout)」中做說明。

第二個問題是,我們發現我們設計的 Button按下去後並無任何的動作,為了解

決這個問題,我們必頇在 Java程式中建立一個 Button物件,然後設定那個 Button

物件的傾聽者(Listener),傾聽者也是一個物件,傾聽者物件會有一個方法(Method)

為 onClick,我們只要實作出此 onClick方法,將按下按鈕的動作寫在 onClick方

法裡面,此按鈕便能發揮按鈕該有的功能,看到這邊,有些讀者可能臉上已經畫

出三條線,完全聽不懂了,若沒有學習過物件導向程式設計,不知道什麼是物件,

什麼是方法,則看不懂上面的敘述是正常的,那是不是該放棄學習Android了呢?

本書的目的就是希望讀者能夠在物件導向程式設計的基礎都不夠的情況下,能夠

寫出 Android應用程式,因此千萬不要放棄,後面的章節中,筆者會給予讀者許

多的範例程式,筆者會告訴讀者,如何透過模仿的技巧,改寫書本上的範例,進

而完成自己的應用程式。

3.4 版面設計(Layout)

在這一節中,我們將討論如何將多個介面元件顯示在同一個螢幕上。首先,我們

先介紹 View Hierarchy與 ViewGroup的概念,在 Android中,顯示在螢幕上的所

有 View可以表示成一個樹狀階層架構,稱為 View Hierarchy,其中樹的節點是

由 View和 ViewGroup所形成的,如下圖所示:

我們已經瞭解 View是什麼了,那什麼是 ViewGroup呢?顧名思義,就是將 View

群組(Group)起來,我們可利用 Android提供的各種版面設計(Layout)將 View群

組起來,本節會介紹三種常用的版面設計,分別是 LinearLayout、RelativeLayout

與 TableLayout。

3.4.1 LinearLayout

LinearLayout 會將數個 View以垂直或水平的方式做線性(Linear)排列,我們以一

個例子來說明,首先開啟一個新專案,並將 main.xml的內容改寫成如下:

1 <?xml version="1.0" encoding="utf-8"?>

2 <LinearLayout

3 xmlns:android="http://schemas.android.com/apk/res/android"

4 android:layout_height="fill_parent"

5 android:layout_width="fill_parent"

6 android:orientation="vertical">

7 <ImageView

8 android:layout_height="300dip"

9 android:layout_width="300dip"

10 android:src="@drawable/asialogo"

11 />

12 <TextView

13 android:layout_height="wrap_content"

14 android:layout_width="wrap_content"

15 android:text="TextView1"

16 />

17 <LinearLayout

18 android:layout_width="fill_parent"

19 android:layout_height="wrap_content"

20 android:orientation="horizontal">

21 <Button

22 android:layout_width="wrap_content"

23 android:layout_height="wrap_content"

24 android:text="Button1"

25 />

26 <Button

27 android:layout_width="wrap_content"

28 android:layout_height="wrap_content"

29 android:text="Button2"

30 />

31 </LinearLayout>

32 <Button

33 android:layout_width="fill_parent"

34 android:layout_height="wrap_content"

35 android:text="Button3"

36 />

37 </LinearLayout>

這份 XML文件若以先前提到的樹狀架構來表示,則如下圖所示:

首先,最外層的 LinearLayout標籤就是代表樹根(root)的那一個 ViewGroup,裡

面依序包含了一個 ImageView、一個 TextView、一個 LinearLayout ViewGroup、

以及一個 Button。在第 6行,我們看到一個陌生的屬性 adnroid:orientation,其值

vertical,代表著在樹第二層的這四個 View/ViewGroup會依垂直(vertical)的方向

做排列,可從執行畫面得到驗證(第二層的 LinearLayout包含了兩個依水平方向

做線性排列的按鈕)。而在第二層的 LinearLayout這個 ViewGroup中則包含了兩

個 Button,程式第 20行:adndroid:orientation="horizontal",代表這兩個 Button

會依水平的方向做線性排列,因此在執行畫面中,我們可看到這兩個按鈕水平地

並排在一起。相信透過這個例子,讀者能對 LinearLayout有初步的瞭解,讀者可

自行嘗詴更改屬性值,甚至嘗詴增加/刪除 View或 ViewGroup。

3.4.2 RelativeLayout

RelativeLayout 也是一個可以將 View群組起來的 ViewGroup,它會將 View依相

對位置做排列,我們直接以一個例子來解說(請將 main.xml修改成如下所示):

1 <?xml version="1.0" encoding="utf-8"?>

2 <RelativeLayout

3 xmlns:android="http://schemas.android.com/apk/res/android"

4 android:layout_height="fill_parent"

5 android:layout_width="fill_parent"

6 >

7 <TextView android:id="@+id/tv"

8 android:layout_width="fill_parent"

9 android:layout_height="wrap_content"

10 android:text="Your Name?"

11 />

12 <Button android:id="@+id/btn"

13 android:layout_width="wrap_content"

14 android:layout_height="wrap_content"

15 android:layout_alignParentBottom="true"

16 android:text="Button"

17 />

18 <LinearLayout

19 android:layout_height="wrap_content"

20 android:layout_width="fill_parent"

21 android:layout_above="@id/btn"

22 android:orientation="horizontal">

23 <ImageView

24 android:layout_width="wrap_content"

25 android:layout_height="wrap_content"

26 android:src="@android:drawable/star_big_on"

27 />

28 <ImageView

29 android:layout_width="wrap_content"

30 android:layout_height="wrap_content"

31 android:src="@android:drawable/star_big_on"

32 />

33 <ImageView

34 android:layout_width="wrap_content"

35 android:layout_height="wrap_content"

36 android:src="@android:drawable/star_big_on"

37 />

38 </LinearLayout>

39 <EditText

40 android:layout_width="fill_parent"

41 android:layout_height="wrap_content"

42 android:layout_below="@id/tv"

43 />

44 </RelativeLayout>

這份 XML文件的樹狀架構如下圖所示:

首先,最外層的 RelativeLayout標籤就是代表樹根(root)的那一個 ViewGroup,裡

面包含了一個 TextView、一個 Button、一個 LinearLayout ViewGroup、以及一個

EditText,其中 EditText是我們新認識的介面元件,其用途是讓使用者輸入文字

資料。接著,在第 7 行中,我們看到了一個新的屬性 android:id="@+id/tv",這是

幫那個介面元件設定 id的屬性,我們已經瞭解如何利用@[資源類別]/[識別名稱]

來讀取資源,可是這次我們看到「@」符號後面跟著一個「+」符號,這是因為

在第 7行,我們並不是要參考到一個資源,而是要建立一個資源(我們可發現當

我們寫上第 7行後,R類別中會出現一個 id類別,而 tv會是 id類別的成員變數),

因此必頇加上一個「+」符號。

接著,第 15行我們看到了一個新的屬性 android:layout_alignParentBottom,其值

為 true或 false,代表是否要排在 Parent的底部,這邊的 Parent指的就是

RelativeLayout那個ViewGroup(請參考上面的樹狀架構圖),而因為RelatvieLayout

填滿了整個螢幕,因此 Button就會位於螢幕的底部。接著,第 21行:

android:layout_above="@id/btn",這一行代表 LinearLayout這個 ViewGroup要位

於 id為 btn的介面元件的上方(在第 12行我們設定 Button的 id為 btn),因此

LinearLayout這個 ViewGroup就會位於 btn的上方(注意:定義"@+id/btn"的地方

一定要寫在"@id/btn"之前)。LinearLayout裡面放了三個 ImageView,我們使用系

統提供的圖檔: "@android:drawable/star_big_on",讀者可可參閱 SDK文件中的

R.drawable類別得知有哪些系統圖檔可供我們使用。最後,第 42行的屬性

android:layout_below與 layout_above類似,只是相對位置不一樣,一個在下一個

在上。執行的結果如下圖所示:

讀者對於 RelativeLayout的概念應該很清楚了,其實就是指定各介面元件的相對

位置,可是讀者可能有個疑問,我如何知道有哪些屬性可以使用呢,除了從

Android開發者網站上查詢之外,筆者要教大家一個小技巧,在 Eclipse環境下編

寫 XML文件時,當您打完「android:」之後稍為等待一下,這時 Eclipse會提示

您可用的屬性列表(隨著打字的增加列表的項目數會越少),並且會有適當的說明,

如下圖所示:

Eclipse提供的說明告訴我們 android:layout_above這個屬性的值必頇是個 ID,而

且會讓使用者個屬性的 View/ViewGroup在指定 id的那個 View的上方。

3.4.3 TableLayout

通常一個表格(Table)是由數個列(Row)以及數個行(Column)所組成的,我們最後

的介紹的 TableLayout允許我們像建立表格般安排 View/ViewGroup的位置。我們

會用到兩個標籤,首先使用 TableLayout標籤指定佈局方式,接著使用 TableRow

這個標籤來放置每一列的 View/ViewGroup,範例如下:

1 <?xml version="1.0" encoding="utf-8"?>

2 <TableLayout

3 xmlns:android="http://schemas.android.com/apk/res/android"

4 android:layout_height="fill_parent"

5 android:layout_width="fill_parent"

6 >

7 <TableRow>

8 <TextView android:text="NCTU"/>

9 <TextView android:text="Hsinchu"/>

10 <TextView android:text="300"/>

11 </TableRow>

12 <ImageView

13 android:layout_width="wrap_content"

14 android:layout_height="wrap_content"

15 android:layout_centerHorizontal="true"

16 android:layout_centerVertical="true"

17 android:src="@android:drawable/star_big_on"

18 />

19 <TableRow>

20 <TextView

21 android:text="Asia University"

22 android:paddingRight="15px"

23 />

24 <TextView

25 android:text="Taichung"

26 android:paddingRight="15px"

27 />

28 <TextView android:text="413"/>

29 </TableRow>

30 <ImageView

31 android:layout_width="wrap_content"

32 android:layout_height="wrap_content"

33 android:layout_centerHorizontal="true"

34 android:layout_centerVertical="true"

35 android:src="@android:drawable/star_big_on"

36 />

37 <TableRow>

38 <TextView android:text="NCU"/>

39 <TextView android:text="Chungli"/>

40 <TextView android:text="320"/>

41 </TableRow>

42 </TableLayout>

首先,在第 2行的 TableLayout標籤代表著要使用 TableLayout的佈局方式。內部

我們可以使用 TableRow標籤定義每一列所包含的 View,例如在第 7行到第 11

行中,我們定義了三個 TextView,其實也就代表著這一列有三欄。而在

TableLayout中我們仍然可以定義一般的 View,而不使用 TableRow標籤,例如

在第 12行,我們定義了一個 ImageView,從結果畫面可看出,它會佔據一列。

執行結果如下圖所示:

接著,在 19~29行,程式再度利用 TableRow標籤定義了一個包含三欄的列,可

是我們在第 22行看到一個新屬性 android:paddingRight,padding是補上空白的意

思,而 paddingRight就是指往右邊補上空白,而其值 15px指的是要補上空白的

長度,Android允許我們使用的單位有 px (pixels), dip (device independent pixels),

sp (scaled pixels), pt (points), in (inches), mm (millimeters),筆者是建議初學者可以

先不用理會這些單位的差異,然而讀者可以詴著自行調整其值,並從模擬器上觀

看結果,直到滿意為止。回到正題,為什麼我們需要加上這個屬性呢?這是因為

若沒有這一屬性,Taichung就會緊接在 Asia University後面,而形成 Asia

UniversityTaichung的情況,因此適當的留白屬性可讓外觀更加順眼。

然而,讀者可能又會有一個疑問,那為什麼第 8行或者第 38行的地方不需要加

上 padding相關的屬性呢?這是因為第 8行的"NCTU"與第 38行的"NCU"其字串

長度都比"Asia University"要短,再加上第二欄會自動地對齊,因此我們可以不

加上 padding相關屬性。

3.5 摘要

在這一章中,我們學習到如何透過 XML來做版面的設計,我們瞭解了 View、

ViewGroup、View Hierarchy等幾個觀念。我們學習了一些 View的使用方法,如

TextView、ImageView、Button等,也學習了 ViewGroup的使用方法,如

LinearLayout、RelativeLayout、TableLayout等。當讀者熟悉了以 XML來設計版

面後,可能覺得在文字編輯器上撰寫XML的方式還是不夠便利,如同寫網頁時,

當我們熟悉 HTML的語法之後,我們會希望有個視覺化的網頁編輯軟體來輔助

我們,那麼 Android平台上是否有工具可用呢,事實上,網路上已經有視覺化的

介面開發工具,例如 DroidDraw,讀者可自行至 DroidDraw官方網站下載安裝

[1]。

讀者可發現,我們幾乎沒有談論到 Java程式,我們就已經可以在模擬器上執行

我們所設計的程式,是不是比較有信心了呢?然而,我們不難發現,我們所設計

的按鈕都沒有作用,這也告訴我們,學習之路還相當的漫長,我們還必頇學習更

多的東西。

3.6 作業

1. 改寫 main.xml,並利用 LinearLayout排出下面的版面。

2. 改寫 main.xml,並利用 RelativeLayout排出下面的版面。

3. 改寫 main.xml,並利用 TableLayout排出下面的版面。

3.7 參考資料

[1] DroidDraw: Graphical User Interface Editor for Android Cell Phone Development

and Programming, http://www.droiddraw.org/