Android 點陣圖形資源的進階運用

設計師與工程師都該知道的事 ⑵

Dcard Tech
Dcard Tech Blog
7 min readJan 9, 2017

--

前言

本篇接續《為 Android app 準備圖形資源》,做一些更進階的探討。

“Drawable” 在 Android 官方文件裡被翻譯為「可繪」,意即「可繪製到畫面上」的廣義內容;包含點陣圖、向量圖、形狀定義、多層繪製、動畫等等。設計師和工程師若能一起了解這些規格,可以減少許多溝通時間並讓專案開發更有效率。

9-patch drawable

9-patch drawable 的使用情境,在於一個按鈕、卡片背景的尺寸不固定的時候,將製作的圖形分割定義為 9 個區塊,保留四個角落不變形,並延伸其餘部分填滿整個視圖。

一個範例 9-patch drawable(已放大)

如圖所示,你可以看到 9-patch drawable 的邊緣有許多黑色與紅色的像素,這些寬度或高度為 1px 的像素,定義了以下幾項資料:

  1. 可延伸區域 (Stretch regions):在上方與左方的黑色像素條,定義了 9-patch drawable 延伸時,x 方向與 y 方向可被扭曲的區域。範例圖的可延伸區域避開了圓角、線框以及陰影的部分,被延展的時候也會看起來比較自然。
  2. 內容區域 (Content padding):在下方與右方的黑色像素條(範例圖裡只有各一個像素)定義了延展後內容可以填滿的部分。除此之外你也可以在套用的 View 直接設 padding,因此你可以自行安排要定義在何處;或是你可以把內容區域定義在圖形線框的內緣,在 View 上再額外指定 padding。
  3. 視覺邊緣 (Optical bounds):在 Android 4.3 含以上,你可以用右方與下方的紅色像素定義圖形的視覺邊緣,後面會有較詳細的介紹。

以上定義可以直接編輯點陣圖像素、使用 SDK 內建的 Draw 9-patch 工具,或是使用一些第三方工具

定義好的 9-patch drawable,可以得到以下結果:

包含文字內容的 9-patch drawable 示例

9-patch drawable 是一個點陣圖資源,因此你可能會需要為不同像素密度的裝置提供不同的版本。提供的方式請請參照前一篇文章,唯一差別是不同縮放級別的 9-patch drawable,邊緣定義的空間仍然為 1 個像素的寬或高。

讓專案辨別圖形為 9-patch drawable 的方式,是在主檔名結尾加上 “.9”(不含引號),例如 “card.9.png”。請用 png 儲存,因為你不會希望 jpeg 壓縮的時候讓邊緣定義失效。

Dcard app 的 Facebook 登入按鈕 9-patch 資源 (mdpi,已放大)
Dcard app 的 Facebook 登入按鈕顯示效果(xxhdpi)

視覺邊緣

視覺邊緣的目的是讓不同的物件之間,能夠以視覺的邊緣,而非圖形的邊緣對齊。在 9-patch drawable 在圖形右方與下方視覺邊緣以外的部分,以紅色像素標註

視覺邊緣對齊的案例:左圖為圖形邊緣對齊,右圖為視覺邊緣對齊

定義好視覺邊緣後,在 view parent 設定android:layoutMode"opticalBounds" 以對齊內容,如以下所示:

<LinearLayout android:layoutMode="opticalBounds" ... >

Mipmap Drawable

在了解 mipmap drawable 之前,先看一下維基百科對 mipmap 的解釋:

在三維電腦圖形的貼圖彩現中有一個常用的技術被稱為 Mipmapping。為了加快彩現速度和減少圖像鋸齒,貼圖被處理成由一系列被預先計算和最佳化過的圖片組成的檔案,這樣的貼圖被稱為 MIP map 或者 mipmap。這個技術在三維遊戲中被非常廣泛的使用。「MIP」來自於拉丁語 multum in parvo 的首字母,意思是「放置很多東西的小空間」。

在 Android 系統裡,一臺螢幕設定為 mdpi 的裝置,使用 app 的 drawable 資源時總是採用 drawable-mdpi 資料夾裡的內容。這時候如果對包含 drawable 的 ImageView 進行縮放,並不會影響採用的圖形解析度;也就是當你放大時,並不會因此而拿 drawable-hdpi 等更高解析度的圖形,只會得到被放大的模糊點陣圖。

在視圖可能被縮放的情況下,若是採用 mipmap drawable,則系統會自動從各密度的資料夾中,取得適合解析度的點陣圖使用。

註: 這裡的「解析度」指的是「影像解析度」,也就是圖形每一個方向上的像素數量,並非影像檔的像素密度定義值。

舉例來說,官方建議啟動器圖示 (launcher icons) 使用 mipmap drawable,原因在於啟動器在設計上可能會需要縮放啟動器圖示;在 Android 4.4 KitKat 發表時,內建的啟動器圖示也比起前一代增加了 25% 的尺寸。

Dcard app 的啟動器圖示 mipmap 資源

像素對齊

在電腦字體點陣化時,有一項技術叫做 “Font hinting”,目的是讓反鋸齒的文字在螢幕上看起來邊緣更銳利清晰,其實就是讓文字的筆畫邊緣與像素格點對齊。

維基百科的字體微調範例圖。由於 Medium 會把圖片縮放與版面同寬,上方的小字預覽可能沒有點對點顯示。

為各像素密度級別(mdpi、hdpi……等)都提供一份點陣圖資源的好處,除了程式執行時節省縮放運算以外,你可以為每一個密度都提供 pixel-perfect 的圖形,也就是個別將線條邊緣對齊像素格點,比起直接將大圖運算縮小可以更加銳利清晰。

Adobe Illustrator 裡對像素格點對齊的動畫說明

對齊像素格點的效果在中低像素密度的裝置更為明顯。

對齊像素前(左)以及對齊像素後(右)的 Dcard 啟動器圖示(mdpi,48*48 px)

以上是由 Dcard Android Team 帶來,關於 Android 圖形資源介紹的第二部分。還有一些向量圖的運用,例如 AnimatedVectorDrawable 以及 VectorDrawable 的 path data 說明等,這部分留到之後的第三部分再介紹。

如果你覺得這篇文章有為你帶來幫助,歡迎分享給其他人。

--

--