Android 13 主題色 Icon 實作與縮小 VectorDrawable 體積的方法

終結圖示強迫症最後一哩路

Ray Yuan Liou
9 min readMar 3, 2023
他在等你更新 App 啦。

Google 在 Android 12 引入了 Material You 設計風格,裏頭有一部分是可以藉由使用者桌布的不同,產生各種不同的個性化系統顏色,這裡頭之中也包含著圖示。
如果你的手機上跑的是 Android 12 以上的版本,在更換桌布時會跳出畫面讓你選擇色盤。而下面有一個選項叫做「圖示套用主題色」,在 Android 12 和 13 兩個版本之後,後面還有一個 Beta 版的標籤。

圖1. 圖示套用主題色的功能,在 12 和 13 後面都有 Beta 版字樣

今天就來簡介如何實作 Android 的主題色 Icon,不過需要提醒,雖然這個功能在 Android 12 就已經出現,無奈的是 12 尚未對外開放官方製作流程,雖然我們可以透過指定顏色到系統的顏色進而實作,不過卻有缺陷 — Icon 不會隨著桌布變化而變化,需要重新安裝才行。(小彩蛋是 Material U 取色並調整 UI 的功能叫做 Monet,Android 12 首發時只有 Pixel 手機支援。其他裝置至少要等到 Android 12L,Google 才將 Monet 放入 AOSP 裡頭。故 Android 12 的模擬器是不支援動態色彩的。Android 12 的主題色 Icon 也是 Pixel Launcher 神奇魔法,直到 13 才算對大眾開放。)
因為以上這點,本篇文章的範例針對 Android 13 以上的版本進行說明。

最近也幫 Android 台灣電子書 App 做了相關的功能,就依照這個為範例來拆解步驟。大家可以自己跳到需要的步驟即可。

取得圖示的 SVG 版本

首先你需要有目前 Icon 的原圖檔,可能很多人跟我一樣原擋是一個 Png 圖檔(或其他的點陣格式),有沒有什麼方法可以將原來的點陣圖抽取出來成為向量圖呢?(最好是免費服務黑黑黑)

Photopea 就是這個服務,而且他不需要安裝!直接跑在瀏覽器上面。
首先我們先把原 Icon 圖示的主體部分套上黑白的濾鏡並且輸出(本例輸出成 PNG)。接著用 Photopea 開啟這個檔案,請點擊圖片本身,接著選擇 Image -> Vectorized Bitmap。

圖2. 將點陣圖變成向量圖

依照需求調整圖示即可。像我發現 EBook 的圖示只需要 8 色顯示效果就很不錯。我這裡照預設透過「Cartoon」模式進行輸出。

圖3. 點陣化圖形

在這邊有幾個的步驟我建議進行,第一個是去除原來 Icon 的背景,將他去背。第二個則是將原圖片大小調成 Android 預設的最大值 108 x 108。
首先是去背,套上黑白濾鏡的圖片,可以點擊最下面的 Path 0 圖層(請自行確認自己圖示的圖層),並按下 Delete 鍵即可。

圖4. 點擊背景圖層,按下 delete

接著是一個可選的流程,非必要進行。我會將圖片調整為 108 x 108 大小的 Icon 方便之後丟進去時調整內容。我用的方法是透過 Image -> Image Size 調整圖片的大小,別忘了目前圖片已經是向量圖,先調整成近似 1:1 的大小。再透過 Image -> Canvas Size 將背景拉成 108 x 108。

圖5. 調整畫布大小

處理好 Vectorized 後,我們透過 File -> Export as -> SVG 得到去除背景的 SVG 圖樣。

圖6. 另存 SVG 圖檔

最佳化 VectorDrawable 的方式

我們會最佳化 png 圖檔來追求更小的安裝擋,那換成 VectorDrawable 後能不能再榨出一點空間呢?答案是可以!在這裏,我們可以藉由最佳化 SVG 圖及 VectorDrawable 本身,來榨出更多空間。

SVGOMG 就是一個專門用來讓 SVG 縮小大小的網站,因為圖示不會放太大,所以我們透過減少 Number precision 的方式來減少空間。

圖7. 透過減少 Number precision 來縮小容量

接著,我們開啟 Android Studio。使用 Vector Asset 來匯入我們剛剛最佳化過的 SVG 檔案

圖8. 匯入 SVG 檔案到 Android 專案

接下來要介紹的工具叫做酪梨 🥑 (avocado),一個命令列工具。他可以幫助我們進一步的減少 VectorDrawable 的大小。
avocado 是一個 node 寫的程式,我們可以透過 npm 來安裝他

$ npm install -g avocado

安裝完 avocado 後,開啟終端機,並開啟專案的 drawable 資料夾(也就存放剛剛處理圖示的那個資料夾)。
開啟 drawable 資料夾後,下指令:

$ avocado <your_image_name>.xml

以這個 Icon 來看,最後的結果是可以透過這些方法省 1kb 左右的空間。

圖9. 圖示省了 1kb

製作主題色 Icon

終於進展到製作主題色 Icon,在這之前你的 App 必須要已經使用 Adaptive Icon 才行,我們的主題色 Icon (Themed icon) 就是建立在其的基礎之上。

請開啟你的 ic_launcher.xmlic_launcher_round.xml 這兩個檔案(應該在 mipmap-anydpi-v26 目錄之下。在原來就有 foreground 和 background 之下,新增一個 monochrome 參數。

<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
<!-- add this -->
<monochrome android:drawable="@drawable/ic_monochrome_icon_opt" />
</adaptive-icon>

到這步,其實已經設定好,接下來開啟 Android 13 以上的模擬器,或是機器將 App build 上去跑跑。記得開啟「圖示套用主題色」,可以將圖示拉到桌面上。但你會注意到,圖示怪怪的⋯⋯

圖10. 圖示顯示怪怪的,一片黑

調整的第一步,先將我們 Icon 圖檔的 VectorDrawable 開啟。我們有兩個需要調整的地方:第一個是 Icon 的大小,第二個則是讓他正常顯示。

首先我們先將 path 先 group 起來,好對他做變形:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">

<group
android:scaleX="0.4"
android:scaleY="0.4"
android:translateX="34"
android:translateY="32">

<!-- your path here -->

</group>
</vector>

我們可以透過 scaleX 和 Y 來調整縮放,透過 translateX 和 Y 來調整 Icon 的位置。從 Icon Preview 之中可以注意到,圖示變小、位置也改變了。
這時先 build 到 Android 上跑跑看。會注意到雖然大小正常了,卻顯示出一坨黑。

圖11. 圖示顯示出來了,但還是一片黑

如果你們的圖示,是簡單的圖形,到這一步應該就完工了。但像電子書圖示,還是希望他有放大鏡等層次,可以讓人一眼看出來。

這時我們可以用 android:fillAlpha 參數,來調整各個圖層的明暗細節。大家可以自行調整看看。而電子書 Icon 調整後,大概會是這個樣子:

圖12. 調整 Alpha 值,將圖示的層次顯示出來

接著再試著放到 Android 上跑跑看,會發現我們的 Icon 完成囉。😎
大家可以盡情地切換顏色,也換到深色模式跑跑看。並且這個改動之後,有圖示潔癖的使用者,也能更安心的安裝囉!

圖13. 最終結果預覽

更多實作上的細節,可以看看台灣電子書原始碼,作為範例參考。

--

--