15
使用者介面設計 在第 1 章,快速入門中,我們利用 Android Eclipse 插件,在短短幾 分鐘的時間內兜成一支簡單的"Hello, Android" 程式。在第二部分, Android 基礎中,我們將建立更實際的範例︰數獨遊戲(Sudoku )。 透過逐步為該遊戲新增功能,你將學到有關 Android 編程的諸多面 向。讓我們從使用者介面開始吧! 你可以在 http://pragprog.com/titles/eband3 上找到本書所使用的全部 樣本程式碼,如果你讀的是 PDF 版本,就可以點擊程式碼前面的灰 色小矩形,直接下載程式碼檔案。 3.1 數獨範例簡介 數獨遊戲對 Android 而言是個很好的樣本程式,因為遊戲本身非常單 純。你有 81 個方格(9 9 列),試著用數字填滿它們,讓每一 欄、每一列,以及每個 3 ×3 方格所構成的區塊皆由 1 9 的數字構 成(每個數字恰好出現一次)。遊戲開始時,有些數字已經被填入 (已知條件),玩家必須做的就是將其餘數字填上。標準的數獨謎題 只存在唯一解。 數獨通常是用鉛筆和紙來玩的,然而電腦化的版本也十分普遍。使用 紙筆版本時,很容易因為早先所犯下的錯誤,而必須回過頭來擦掉你 所完成的大部分工作。在 Android 版本裡,你可以隨心所欲地不斷修 改,而不必清除一堆惱人的橡皮擦屑。

使用者介面設計 - 碁峰資訊epaper.gotop.com.tw/pdf/ACL029700.pdf使用者介面設計 在第1 章,快速入門中,我們利用Android Eclipse插件,在短短幾 分鐘的時間內兜成一支簡單的"Hello,

  • Upload
    others

  • View
    23

  • Download
    0

Embed Size (px)

Citation preview

Page 1: 使用者介面設計 - 碁峰資訊epaper.gotop.com.tw/pdf/ACL029700.pdf使用者介面設計 在第1 章,快速入門中,我們利用Android Eclipse插件,在短短幾 分鐘的時間內兜成一支簡單的"Hello,

使用者介面設計

在第 1 章,快速入門中,我們利用 Android Eclipse 插件,在短短幾

分鐘的時間內兜成一支簡單的"Hello, Android"程式。在第二部分,

Android 基礎中,我們將建立更實際的範例︰數獨遊戲(Sudoku)。

透過逐步為該遊戲新增功能,你將學到有關 Android 編程的諸多面

向。讓我們從使用者介面開始吧!

你可以在 http://pragprog.com/titles/eband3 上找到本書所使用的全部

樣本程式碼,如果你讀的是 PDF 版本,就可以點擊程式碼前面的灰

色小矩形,直接下載程式碼檔案。

3.1 數獨範例簡介

數獨遊戲對 Android 而言是個很好的樣本程式,因為遊戲本身非常單

純。你有 81 個方格(9 欄 9 列),試著用數字填滿它們,讓每一

欄、每一列,以及每個 3×3 方格所構成的區塊皆由 1 到 9 的數字構

成(每個數字恰好出現一次)。遊戲開始時,有些數字已經被填入

(已知條件),玩家必須做的就是將其餘數字填上。標準的數獨謎題

只存在唯一解。

數獨通常是用鉛筆和紙來玩的,然而電腦化的版本也十分普遍。使用

紙筆版本時,很容易因為早先所犯下的錯誤,而必須回過頭來擦掉你

所完成的大部分工作。在 Android 版本裡,你可以隨心所欲地不斷修

改,而不必清除一堆惱人的橡皮擦屑。

Page 2: 使用者介面設計 - 碁峰資訊epaper.gotop.com.tw/pdf/ACL029700.pdf使用者介面設計 在第1 章,快速入門中,我們利用Android Eclipse插件,在短短幾 分鐘的時間內兜成一支簡單的"Hello,

Android手機開發平台速習講座 32

數獨小花絮

大多數人以為數獨是某種古老的日本遊戲,但實際上並不是。雖

然類似的解謎遊戲可以追溯到 19 世紀的一本法文雜誌,但多數專

家相信現代數獨遊戲係由一位退休的美國建築師—— Howard

Garns —— 所發明的,最早於 1979 年被刊載於一本美國雜誌

(Dell Magazines),當時的遊戲名稱叫作 Number Place。

Android 版的數獨遊戲(參見圖 3.1)也會給你一些提示,減少一些

解題上的困難,在極端情形下,它甚至可以為你解題,但那樣對你又

有什麼意思呢?因此,我們必須在協助與挑戰之間取得平衡,而不要

讓它變得太過容易。

圖 3.1︰數獨遊戲的 Android範例程式

Page 3: 使用者介面設計 - 碁峰資訊epaper.gotop.com.tw/pdf/ACL029700.pdf使用者介面設計 在第1 章,快速入門中,我們利用Android Eclipse插件,在短短幾 分鐘的時間內兜成一支簡單的"Hello,

Chapter 3 使用者介面設計 33

3.2 宣告式設計

使用者介面可透過兩種方式之一來設計︰程序式(procedural)和宣

告式(declarative)。程序式設計的意思就是使用程式碼。例如,在

建立 Swing 應用程式時,你撰寫 Java 程式碼,建立及操控所有的使

用者介面物件,像是 JFrame與 JButton。因此,Swing是程序式的。

另一方面,宣告式設計並未涉及任何程式碼。在設計簡單網頁時,你

使用 HTML,一種奠基於 XML 的標記語言,描述你想要在頁面上看

見什麼,而不是你想要如何做。因此,HTML是宣告式的。

Android 試圖跨越程序式設計與宣告式設計之間的間隙—— 透過讓你

使用兩種風格中的任何一種來建立使用者介面。你幾乎可以完全倚靠

Java 程式碼,也可以幾乎完全仰賴 XML 描述子。如果你去查詢任何

Android使用者介面元件的文件說明,會同時看到 Java API以及完成

同樣工作的相對應宣告式 XML屬性。

該使用哪一種?兩者皆有效,但 Google 的建議是盡可能使用宣告式

XML。XML代碼往往比相對應的 Java程式碼更簡短且更容易理解,

並且比較不會在未來版本中發生變動。

現在讓我們來看看,如何利用這項資訊建立數獨遊戲的起始畫面。

3.3 建立起始畫面

我們將從由 Eclipse 插件所建立的 Android 程式骨架開始。就像你在

第 1.2 節,建立你的第一支程式所做的一樣,先建立一個新的

“Hello, Android”專案,但是這一次,我們使用下列的值︰

當然,在真實的程式裡,你會在這裡使用屬於你自己的名稱。套件名

稱(package name)尤其重要。系統裡的每一支應用程式都必須有獨

特的套件名稱,一旦選定套件名稱,要改變它就有點麻煩,因為它會

被使用在相當多的地方。

Page 4: 使用者介面設計 - 碁峰資訊epaper.gotop.com.tw/pdf/ACL029700.pdf使用者介面設計 在第1 章,快速入門中,我們利用Android Eclipse插件,在短短幾 分鐘的時間內兜成一支簡單的"Hello,

Android手機開發平台速習講座 34

我喜歡讓 Android 模擬器視窗持續保持在執行狀態,每當程式碼有改

變時就跑跑看,因為只需要花費幾秒鐘的時間。如果你現在就這麼做

並且讓程式跑跑看,你會看到一個幾乎空白的畫面,內容僅包含

“Hello World, Sudoku”,首要之務就是將它改變成遊戲的起始畫

面,包含一些按鈕,讓玩家能開啟新遊戲、繼續之前的遊戲、取得關

於遊戲的資訊,或者退出。那麼,我們必須做什麼改變,才能完成這

項工作呢?

如第 2 章,核心概念所討論的,Android 應用程式是一組鬆散的活動

集合,每個活動皆定義了一個使用者介面的畫面。當你建立 Sudoku

專案時,Android插件會在 Sudoku.java裡為你產生一個活動︰

Android呼叫活動的 onCreate() 方法,將它初始化。setContentView()

呼叫利用 Android的視圖(view)Widget,為活動的畫面填入內容。

我們也可以使用幾行 Java 程式碼,可能是另一個或二個類別,以程

序式的手法定義這個使用者介面,然而,Android 插件選擇了宣告式

的做法,而我們也會繼續遵循這個路線。在先前的程式碼中,

R.layout.main 是一個資源識別符( resource identifier),參照到

res/layout 目錄裡的 main.xml 檔案(參見圖 3.2)。main.xml 以

XML 宣告使用者介面,因此那是我們必須修改的檔案。在執行時

期,Android 會剖析(parse)並且實例化(instantiate)XML 裡所定

義的資源,並且將它設定為目前活動的視圖(view)。

Page 5: 使用者介面設計 - 碁峰資訊epaper.gotop.com.tw/pdf/ACL029700.pdf使用者介面設計 在第1 章,快速入門中,我們利用Android Eclipse插件,在短短幾 分鐘的時間內兜成一支簡單的"Hello,

Chapter 3 使用者介面設計 35

圖 3.2︰Sudoku專案裡的初始資源

務必注意自動由 Android插件管理的 R類別,當你把檔案放進 res目

錄裡的任何地方時,插件會注意到這個改變,並且替你在 gen 目錄裡

的 R.java 中增加資源識別符。假如你移除或改變資源檔,R.java 也

會同步改變。如果你用編輯器打開該檔案,看起來會像這樣︰

Page 6: 使用者介面設計 - 碁峰資訊epaper.gotop.com.tw/pdf/ACL029700.pdf使用者介面設計 在第1 章,快速入門中,我們利用Android Eclipse插件,在短短幾 分鐘的時間內兜成一支簡單的"Hello,

Android手機開發平台速習講座 36

十六進制的數字只是整數,Android 資源管理器用它們來載入實際的

資料、字串和其他被編譯到套件裡的資訊,你不必擔心它們的值,只

要記住,它們是要用來參照實際資料的柄碼(handle),而不是包含

實際資料的物件本身。那些物件一直到需要被用到時才會被實例化?

注意,幾乎每一支 Android程式,包括基礎的 Android框架本身,都

具有 R 類別。關於你能夠使用的全部內建資源,請參見 android.R 的

線上文件說明1。

既然已經知道必須修改 main.xml,讓我們好好研究一下它的根本定

義,看看有什麼是必須改變的。在 Eclipse裡雙擊 main.xml以便打開

它,取決於你如何安裝 Eclipse,你可能會看到一個視覺化佈置編輯

器,或者看到一個 XML 編輯器。在目前的 ADT 版本中,視覺化佈

置編輯器還不是那麼有用,因此,請點擊 main.xml 或底部的 Source

頁籤,就可以看到 XML。main.xml的第一行如下︰

1 http://d.android.com/reference/android/R.html

Page 7: 使用者介面設計 - 碁峰資訊epaper.gotop.com.tw/pdf/ACL029700.pdf使用者介面設計 在第1 章,快速入門中,我們利用Android Eclipse插件,在短短幾 分鐘的時間內兜成一支簡單的"Hello,

Chapter 3 使用者介面設計 37

所有的 Android XML 檔案都是從這一行開始的,它只是告訴編譯器

該檔案為 XML 格式,並且以 UTF-8 編碼。UTF-8 幾乎就像一般的

ASCII 文字,除了它具有可表示非 ASCII 字元的脫逸代碼(escape

code),像是日文字母等。

接下來,我們會看到<LinearLayout>標籤︰

Android為何使用 XML?那不是比較沒效率嗎?

Android 係針對有限記憶體及功率而最佳化的,因此你可能覺得很

奇怪,Android 為什麼會四處使用 XML,畢竟 XML 是可為人類所

讀的冗贅格式,而不是以簡潔或效率著稱,對吧?

雖然你在撰寫程式時會看到 XML,然而 Eclipse 插件會呼叫

Android 的資源編譯器(resource compiler),aapt 將 XML 預

先處理成壓縮過的二進制格式,注意,儲存在行動裝置上的正是

這個格式,而不是原始的 XML文字。

佈置器(Layout)是放置一或多個子物件的容器,並且能夠在父物件矩

形裡的畫面上定位它們。下面是一序列 Android提供的最常見佈置器︰

FrameLayout︰將它的子物件安排成全部從畫面左上角開始。這

被用在頁籤視圖( tabbed view)以及圖像切換器( image

switcher)中。

LinearLayout︰將它的子物件安排在單一欄或列上。這是你最常

使用的佈置器。

RelativeLayout︰將它的子物件以彼此相對或相對於父物件的方

式安排。這經常被用在表單中。

常見問題

Page 8: 使用者介面設計 - 碁峰資訊epaper.gotop.com.tw/pdf/ACL029700.pdf使用者介面設計 在第1 章,快速入門中,我們利用Android Eclipse插件,在短短幾 分鐘的時間內兜成一支簡單的"Hello,

Android手機開發平台速習講座 38

TableLayout︰將它的子物件安排在表格(欄與列)中,類似

HTML表格。

所有佈置器通用的一些參數︰

為 Android 定義 XML 名稱空間(namespace)。你應該要定義名稱

空間一次,就在檔案裡的第一個 XML標籤中。

佔用父物件(此案例為視窗)的整個寬度和高度。可能的值有

fill_parent與 wrap_content。

在<LinearLayout>標籤裡,你可以找到一個子Widget(child widget)︰

這定義了簡單的文字標籤。讓我們用一些不同的文字和按鈕替換它,

下面是我們的第一個嘗試︰

Page 9: 使用者介面設計 - 碁峰資訊epaper.gotop.com.tw/pdf/ACL029700.pdf使用者介面設計 在第1 章,快速入門中,我們利用Android Eclipse插件,在短短幾 分鐘的時間內兜成一支簡單的"Hello,

Chapter 3 使用者介面設計 39

假如你在編輯器裡看見有關遺漏語法限制的警告(DTD 或 XML

schema),請忽視它。代替直接將英文文字寫死在佈置檔裡,我們

使用@string/resid 語法,參照 res/values/strings.xml 檔案裡的字串。

依據不同的 locale(地區與語言選項),可以有不同版本的這個檔案

和其他資源檔,或者像是螢幕解析度與螢幕方向之類的其他參數。現

在,打開該檔案,必要時從底部切換到 strings.xml頁籤,並且輸入︰

儲存 strings.xml,讓 Eclipse 重新建立(rebuild)專案。現在,當你

執行程式時,應該會看見類似圖 3.3 的畫面。畫面雖然清楚明瞭,但

或許可以稍加美化。

Page 10: 使用者介面設計 - 碁峰資訊epaper.gotop.com.tw/pdf/ACL029700.pdf使用者介面設計 在第1 章,快速入門中,我們利用Android Eclipse插件,在短短幾 分鐘的時間內兜成一支簡單的"Hello,

Android手機開發平台速習講座 40

圖 3.3︰第一版起始畫面

讓我們把標題文字加大一些並且將它置中,再讓按鈕變小一點,並且

使用不同的背景顏色。下面是關於顏色的定義,你應該將它們放進

res/values/colors.xml︰

下面是新的佈置:

Page 11: 使用者介面設計 - 碁峰資訊epaper.gotop.com.tw/pdf/ACL029700.pdf使用者介面設計 在第1 章,快速入門中,我們利用Android Eclipse插件,在短短幾 分鐘的時間內兜成一支簡單的"Hello,

Chapter 3 使用者介面設計 41

在這個版本裡,我們引進新語法,@+id/resid。代替參照在其他地方

所定義的資源 ID,這裡指出如何建立可供其他人參照的新資源 ID。

例如,@+id/about_button 定義了 About 按鈕的 ID,我們稍後會用到

它—— 當用戶壓下該按鈕時,讓某事發生。

Page 12: 使用者介面設計 - 碁峰資訊epaper.gotop.com.tw/pdf/ACL029700.pdf使用者介面設計 在第1 章,快速入門中,我們利用Android Eclipse插件,在短短幾 分鐘的時間內兜成一支簡單的"Hello,

Android手機開發平台速習講座 42

圖 3.4︰具有新佈置器的起始畫面

結果被顯示在圖 3.4。這個新畫面在直向模式中看起來很好(當螢幕

高度大於寬度時)。但是在橫向模式(螢幕寬度大於高度)呢?用戶

隨時都可以切換不同模式,例如,透過翻轉鍵盤或者將電話轉向,所

以你必須一併處理這件事。

3.4 使用替換資源

試著將模擬器切換到橫向模式(【 Ctrl+F11】或者袖珍鍵盤

(keypad)上的【7】或【9】鍵),哎呀﹗Exit 按鈕跑到螢幕底端的

外面去了(參見圖 3.5)。該如何修正呢?

你可以試著調整佈置器,讓它能夠運作在每個螢幕方向上。不過那通

常是不太可能達成的,不然就是會導致出現怪異的畫面,當發生這種

情況時,你必須為橫向模式準備不同的佈置器,也就是我們在這裡要

採取的解決方式。

Page 13: 使用者介面設計 - 碁峰資訊epaper.gotop.com.tw/pdf/ACL029700.pdf使用者介面設計 在第1 章,快速入門中,我們利用Android Eclipse插件,在短短幾 分鐘的時間內兜成一支簡單的"Hello,

Chapter 3 使用者介面設計 43

什麼是 Dip,什麼又是 Sp?

從歷史上來看,程式人員總是以圖素的觀點來設計電腦介面,例

如,你可能讓某個文字欄位的寬度為 300 個圖素、讓欄與欄之間

相隔 5 個圖素、以及將小圖示的尺寸定為 16×16個圖素,問題是

如果你在每英寸中具有越來越多點數(dpi,dots per inch)的新

型顯示器上執行該程式,使用者介面會變得越來越小,最後會變

得難以看清楚。

獨立於解析度的做法能夠幫忙解決這個問題,Android 支援下列所

有單位︰

px(圖素)︰畫面上的小點(dot)。

in(英寸)︰由尺規量測的尺寸。

mm(毫米)︰由尺規量測的尺寸。

pt(點)︰1/72英寸。

dp(獨立於密度的圖素)︰奠基於螢幕密度的抽象單位。在

每英寸具有 160個小點的顯示器上,1dp = 1px。

dip︰dp的同義詞,在 Google的範例中較常被使用。

sp(獨立於尺度的圖素)︰類似 dp,但也根據用戶的字體尺

寸偏好而按比例繪製。

為了讓你的介面可針對任何目前與未來的顯示器類型作調整,我

建議你在文字尺寸上用 sp 單位,而其他所有方面用 dip 單位。除

此之外,你也應該考慮使用向量圖(vector graphics)代替位元

圖(bitmap)(參閱第 4章,探索 2D圖形)。

常見問題

Page 14: 使用者介面設計 - 碁峰資訊epaper.gotop.com.tw/pdf/ACL029700.pdf使用者介面設計 在第1 章,快速入門中,我們利用Android Eclipse插件,在短短幾 分鐘的時間內兜成一支簡單的"Hello,

Android手機開發平台速習講座 44

圖 3.5︰在橫向模式中看不到 Exit按鈕

建立名為 res/layout-land/main.xml 的檔案(注意"-land "後置碼),

包含下列佈置器︰

Page 15: 使用者介面設計 - 碁峰資訊epaper.gotop.com.tw/pdf/ACL029700.pdf使用者介面設計 在第1 章,快速入門中,我們利用Android Eclipse插件,在短短幾 分鐘的時間內兜成一支簡單的"Hello,

Chapter 3 使用者介面設計 45

這段程式碼使用 TableLayout 建立兩欄按鈕。現在,再次執行程式

(參見圖 3.6)。即使在橫向模式裡,也可以看見全部的按鈕。

你可以利用資源後置碼(suffix)來指明任何資源的替換版本,而不

只是佈置器,例如你可以利用它們來提供不同語言的本地化文字字

串,每個替換資源檔都必須定義一組完全相同的 ID。

Android 的螢幕密度支援非常倚賴這些後置碼2,例如,高密度圖像被

放在 res/drawable-hdpi 目錄,中等密度的被放在 res/drawable-mdpi

或 res/drawable,低密度的則位在 res/drawable-ldpi 目錄,最後,與

密度無關的(即不該被縮放)就放在 res/drawable-nodpi目錄中。

Android 支援後置碼的使用,指明目前的語言、地區、圖素密度、解

析度、輸入法等等。最新的後置碼清單與繼承規則請參見 Android 資

源的文件說明3。

2 http://developer.android.com/guide/practices/screens_support.html

3 http://d.android.com/guide/topics/resources/resources-i18n.html#AlternateResources