1. 事前準備
如要為 Wear OS 建立錶面,開發人員必須使用錶面格式,這是一種以 XML 為基礎的格式,可讓您建立生動且效能出色的錶面。
這個程式碼實驗室適合希望使用 XML 手工製作錶面的使用者,或是希望進一步瞭解格式以便自行建構設計工具的使用者。
如果您想使用圖形工具建立自己的錶面,建議您查看現有的工具,例如 Watch Face Studio。
必要條件
- 具備 XML 相關經驗。
執行步驟
在本程式碼研究室,您將學到:
- WFF 錶面的封裝方式
- 如何建立錶面,包括微光模式
- 新增圖案等元素
- 將資料來源納入錶面
- 如何解決錶面相關問題
您將要建構的是可自訂的錶面,可選擇多種色彩主題、內建步數和日期指標。
軟硬體需求
- Android Studio Meerkat 以上版本 - 雖然不一定要直接使用 Android Studio,但這是確保您已安裝所需的 Android 建構工具和 平台工具最簡單的方法。
- Wear OS 模擬器或實體 Wear OS 手錶,而且已啟用開發人員選項。
2. 瞭解錶面格式專案結構
下載程式碼實驗室檔案
如要開始使用,請在此下載本程式碼實驗室檔案
$ git clone https://github.com/android/codelab-watch-face-format
或者,您也可以將存放區下載為 ZIP 檔案:
watch-face-format
目錄中有兩個專案:start
和 finish
。我們將使用 start
專案,但您隨時可以查看 finish
專案,其中包含已完成的程式碼實驗室。
讓我們檢查錶面格式專案的基本結構。您可以使用自己選擇的編輯器,也可以在 Android Studio 中依序點選「File」>「Open...」,然後選取 start
目錄,開啟起始專案。
在 start/watchface/src/main
目錄中,您會看到下列檔案,讓我們來看看每個檔案的功能:
檔案 | 說明 |
| 就像一般 Android 應用程式一樣,這個檔案包含錶面相關的必要資訊,以及建構錶面所需的內容。 |
| 錶面資訊檔案包含錶面中繼資料,例如如何找到預覽圖片,以及錶面是否可自訂。 |
| 這個檔案包含錶面本身的定義。雖然可以有多個定義,但這會是系統使用的預設檔案。 |
| 每個錶面都需要系統使用的預覽圖片。為了讓這個專案能進行建構,start/ 資料夾含有空白預覽畫面,我們會稍後更新 |
| 這些是我們會在錶面中使用的指針。 |
| 就像 Android 應用程式一樣,包含可在錶面中使用的字串。 |
程式碼在哪裡?
請注意,專案中其實無程式碼。除了 AndroidManifest.xml
檔案外,專案的所有檔案都位於 res/
資源目錄中。這是因為 WFF 錶面不得包含任何程式碼:例如,如果您嘗試加入 Kotlin 或 Java 程式碼,Play 商店將不接受這類內容。
Wear OS 系統會讀取這些資源,並負責為您建構及執行錶面。也就是說,您不需要任何執行階段或其他邏輯,因此可節省開發作業。
3. 建構錶面
我們將更新上述每個檔案,以便建立可運作的錶面。
準備資訊清單
為了將套件識別為 WFF 錶面,資訊清單需要宣告兩件事:
- 專案中無程式碼。
- 使用的錶面格式版本。
首先,請更新 <application>
元素,新增 hasCode
屬性:
<application
android:label="@string/watch_face_name"
android:hasCode="false">
其次,請在 <application>
元素中加入 <property>
,指定這個錶面使用的錶面格式版本:
<property
android:name="com.google.wear.watchface.format.version"
android:value="1" />
定義 watch_face_info
檔案
watch_face_info.xml
檔案有一個必要規定:指定預覽圖片的位置。在這個專案中,我們已在 res/drawable/preview.png
提供預覽圖片。這是空白檔案,但我們稍後會更新為已完成的錶面實際螢幕截圖。
在程式碼實驗室中,我們也會讓錶面可自訂。此外,我們會使用 <Editable>
元素,在 watch_face_info.xml file
中宣告這項資訊。
更新 res/xml/watch_face_info.xml
以新增下列元素:
<Preview value="@drawable/preview" />
<Editable value="true" />
編寫錶面格式 XML
實際錶面的定義包含在 res/raw/watchface.xml
中。請在編輯器中檢查這個檔案。您會發現 <WatchFace>
元素為錶面定義了 450 x 450 的寬度和高度。這個座標空間會用於檔案的其餘所有部分,且無論錶面運作的實際像素尺寸為何都會採用,並根據實際情況向上或向下調整。
XML 如下所示:
<?xml version="1.0"?>
<WatchFace width="450" height="450">
<Scene>
<PartText x="0" y="0" width="450" height="450">
<Text>
<Font family="SYNC_TO_DEVICE" size="48">Hello, World!</Font>
</Text>
</PartText>
</Scene>
</WatchFace>
目前這個定義只會在手錶上顯示「Hello, World!」,很抱歉,還沒有時間!- 但我們會回來修正這個問題。接下來,我們將瞭解如何建構錶面並將其安裝到裝置上。
建構及部署錶面
在指令列上,確認您位於啟動目錄,然後發出指令:
./gradlew installDebug
或在 Windows 執行下列指令:
gradlew.bat installDebug
這樣做會建構錶面並安裝在裝置上。長按錶面畫面,找出「Codelab」錶面。或者,如要透過指令列設定錶面,請使用下列指令:
adb shell am broadcast -a com.google.android.wearable.app.DEBUG_SURFACE --es operation set-watchface --es watchFaceId com.example.codelab
智慧手錶或模擬器上應該會顯示錶面了!恭喜!
4. 新增時間
錶面格式支援同時顯示類比和數位時鐘,甚至可以在單一錶面上同時顯示多個時鐘。
讓我們來看看如何使用 <
AnalogClock
>
元素新增類比時鐘。首先,請從 watchface.xml
檔案中移除整個 <
PartText
>
元素,並替換為以下元素:
<AnalogClock x="0" y="0" width="450" height="450">
<!-- TODO: Add shadows here later -->
<HourHand resource="hour"
x="215" y="50" width="20" height="190"
pivotX="0.5" pivotY="0.921" >
</HourHand>
<MinuteHand resource="minute"
x="217" y="25" width="16" height="220"
pivotX="0.5" pivotY="0.9">
</MinuteHand>
<SecondHand resource="second"
x="221" y="15" width="8" height="245"
pivotX="0.5" pivotY="0.857">
<Variant mode="AMBIENT" target="alpha" value="0" />
<Sweep frequency="15" />
</SecondHand>
</AnalogClock>
<AnalogClock>
元素的高度和寬度為 450,因此會占滿整個螢幕。此外,還有三個子元素:<
HourHand
>
、<
MinuteHand
>
和 <
SecondHand
>
。請注意以下定義方式:
- 資源:每個子元素都有資源屬性,對應到可繪項目素材資源。舉例來說,
res/drawable
中有hour.png
檔案,而<HourHand>
元素會使用該檔案。請注意,您不需要指定@drawable
。 - 樞紐:指針會自動旋轉,但
pivotX
和pivotY
會指定樞紐應出現的位置。以pivotY
為例,計算方式如下:
- 變化版本:
<SecondHand>
包含<
Variant
>
子元素,這會隱藏秒針,因為錶面在微光模式下只會每分鐘更新一次。
現在請執行以下指令,重新建構錶面並部署至裝置或模擬器:
./gradlew installDebug
這次我們有一個可運作的時鐘,但仍有許多改進空間!
5. 新增顏色和主題
錶面之所以有趣,部分原因在於可以自訂錶面,並讓錶面展現個人風格。
我們的錶面目前有點單調,都是白色,所以我們要加入一些色彩!不僅如此,我們還要讓色彩主題「可以自訂」。
建立 ColorConfiguration
首先,我們要定義錶面可用的色彩主題。在 watchface.xml
中找出文字 <!-- TODO: Add UserConfigurations here -->
,並替換為:
<UserConfigurations>
<ColorConfiguration id="themeColor" displayName="color_label" defaultValue="0">
<ColorOption id="0" displayName="color_theme_0" colors="#ffbe0b #fb5607 #ff006e #8338ec #883c3c3c" />
<ColorOption id="1" displayName="color_theme_1" colors="#8ecae6 #219ebc #ffb703 #fb8500 #883c3c3c" />
<ColorOption id="2" displayName="color_theme_2" colors="#ff595e #ffca3a #8ac926 #1982c4 #883c3c3c" />
<ColorOption id="3" displayName="color_theme_3" colors="#ff0000 #00ff00 #ff00ff #00ffff #883c3c3c" />
<ColorOption id="4" displayName="color_theme_4" colors="#ff99c8 #fcf6bd #d0f4de #a9def9 #883c3c3c" />
<ColorOption id="5" displayName="color_theme_5" colors="#1be7ff #6eeb83 #e4ff1a #ffb800 #883c3c3c" />
</ColorConfiguration>
</UserConfigurations>
這會定義 6 種色彩主題,每個主題包含 5 種顏色。每個主題都是以空格分隔的顏色清單,如 colors
屬性所示。
每個主題都需要一個易讀的名稱,因此請在 res/values/strings.xml
檔案中加入下列定義:
<string name="color_label">Color Theme</string>
<string name="color_theme_0">Bold</string>
<string name="color_theme_1">Magic</string>
<string name="color_theme_2">Breeze</string>
<string name="color_theme_3">Daytime</string>
<string name="color_theme_4">Relaxed</string>
<string name="color_theme_5">Smart</string>
使用 ColorConfiguration
定義色彩主題後,請為每個主題新增 tintColor
屬性,將其套用至錶面指針。請修改 watchface.xml
,如下所示:
<HourHand ... tintColor="[CONFIGURATION.themeColor.0]">
...
<MinuteHand ... tintColor="[CONFIGURATION.themeColor.1]">
...
<SecondHand ... tintColor="[CONFIGURATION.themeColor.2]">
<HourHand>
參照所選主題的第一個顏色,<MinuteHand>
參照第二個顏色,<SecondHand>
參照第三個顏色。
如先前所述,重新建構及部署錶面,即可看到彩色錶面!
不僅如此,如果長按錶面並輕觸設定按鈕,還有 6 種色彩主題可供選取!
6. 新增背景顏色
我們可以再做幾件事,讓這個錶面更出色。我們來加入大膽的背景設計。雖然背景仍以黑色為主,但這點點星光般的色彩能提升整體外觀。
我們會使用錶面格式 <
PartDraw
>
元素,讓您建立圖層來繪製線條、矩形、橢圓和弧線等基本圖形。將文字 <!-- TODO: Add the background design here -->
替換為下列內容:
<Group x="100" y="100" width="250" height="250" name="background" alpha="127">
<Variant mode="AMBIENT" target="alpha" value="0" />
<PartDraw x="0" y="0" width="250" height="250">
<Ellipse x="0" y="0" width="250" height="250">
<Fill color="[CONFIGURATION.themeColor.3]" />
</Ellipse>
<Ellipse x="50" y="50" width="150" height="150">
<Fill color="#000000" />
</Ellipse>
</PartDraw>
</Group>
留意我們再次使用到 <Variant>
元素:這會在微光模式下移除背景環,盡可能減少亮起的像素數量。
此外,也請注意我們再次使用色彩主題選取環狀區塊的顏色,以便在錶面上的所有元素中維持風格一致。
7. 驗證錶面
在進一步改善錶面之前,我們先來瞭解如何使用「錶面格式驗證工具」簡化開發程序。
驗證工具可檢查 XML 是否正確,讓您在建構及部署錶面時,避免浪費時間製作出無法運作的錶面。
- 從 GitHub 存放區下載驗證工具 JAR 檔案。
- 針對
watchface.xml
檔案執行驗證工具
java -jar wff-validator.jar 1 watchface/src/main/res/raw/watchface.xml
如果錶面 XML 有效,系統會顯示確認訊息,但如果發現錯誤,系統會顯示錯誤詳細資料和位置,例如:
SEVERE: [Line 18:Column 49]: cvc-complex-type.2.4.a: Invalid content was found starting with element 'PartDrw'
8. 使用資料來源
錶面格式可利用各種不同的資料來源,讓錶面更實用。
讓我們新增兩個常用的資料來源,讓錶面更實用:目前日期 (誰沒忘記過日期?) 和每日步數。
其中每個元素都會放置在 <
PartText
>
容器中,這是用於執行文字作業的圖層。
新增日期
將 <!-- TODO: Add the date/time element here -->
文字替換為以下內容:
<PartText x="225" y="225" width="225" height="225">
<Variant mode="AMBIENT" target="alpha" value="0" />
<TextCircular centerX="0" centerY="0" width="415" height="415" startAngle="180" endAngle="90" align="CENTER" direction="COUNTER_CLOCKWISE">
<Font family="SYNC_TO_DEVICE" size="28" color="[CONFIGURATION.themeColor.0]">
<Template>
<![CDATA[%d %s]]>
<Parameter expression="[DAY]"/>
<Parameter expression="[MONTH_S]"/>
</Template>
</Font>
</TextCircular>
</PartText>
在上方程式碼片段中,我們使用 <
Template
>
將兩個資料來源格式化為字串。DAY
是 1 到 31 之間的整數,而 MONTH_S
已是字串,因此我們使用格式化運算式 %d %s
將整數和字串放在一起。
建議您將此元素包圍在 CDATA
元素中,以免轉譯時不小心加入空白,進而影響位置和對齊方式。
最後,請再次注意我們如何再次使用色彩主題,確保錶面最新加入的內容會維持現有主題。
新增步數
將 <!-- TODO: Add the step count element here -->
文字替換為以下內容:
<PartText x="0" y="0" width="225" height="225">
<Variant mode="AMBIENT" target="alpha" value="0" />
<TextCircular centerX="225" centerY="225" width="415" height="415" startAngle="270" endAngle="360" align="CENTER" direction="CLOCKWISE">
<Font family="SYNC_TO_DEVICE" size="28" color="[CONFIGURATION.themeColor.2]">
<Template>
<![CDATA[%05d]]>
<Parameter expression="[STEP_COUNT]"/>
</Template>
</Font>
</TextCircular>
</PartText>
錶面格式支援各種資料來源,步數計數器是任何錶面都適合添加的絕佳選項,可讓使用者追蹤自己的日常活動和運動。
建構及部署錶面,查看這些最新加入的內容:
9. 最後修飾和預覽
錶面設計重視細節,因此我們來加入幾個最終的點綴。
為錶面新增陰影
錶面指針的顏色搭配得宜,但在錶面上看起來有點平面。將 <!-- TODO: Add shadows here later -->
替換為以下內容,即可在指針後方加入陰影:
<HourHand resource="hour" x="220" y="55" width="20" height="190"
pivotX="0.5" pivotY="0.921" tintColor="[CONFIGURATION.themeColor.4]">
<Variant mode="AMBIENT" target="alpha" value="0" />
</HourHand>
<MinuteHand resource="minute" x="222" y="30" width="16" height="220"
pivotX="0.5" pivotY="0.9" tintColor="[CONFIGURATION.themeColor.4]">
<Variant mode="AMBIENT" target="alpha" value="0" />
</MinuteHand>
<SecondHand resource="second" x="226" y="20" width="8" height="245"
pivotX="0.5" pivotY="0.857" tintColor="[CONFIGURATION.themeColor.4]">
<Variant mode="AMBIENT" target="alpha" value="0" />
<Sweep frequency="15" />
</SecondHand>
新增活潑的標誌
每個知名錶廠都會在錶面加入自家標誌,因此我們也來加入自己的標誌吧!當然,我們可以使用 Android 標誌!
不過,由於這是智慧手錶,我們可以做點「特別」的嘗試,加入可根據配戴者手腕角度移動的標誌。
做法是將圖片放入 <
Group
>
元素中,然後使用 <
Transform
>
元素,根據手腕角度為 <Group>
元素套用「旋轉」效果。結構如下所示:
元素的預設樞紐點位於中心,因此我們不需要調整 <Group>
的 pivotX
和 pivotY
。將 <Transform>
套用至 <Group>
會讓 <PartImage>
圍繞該中心樞紐點旋轉。
在 <Transform>
中,我們使用 [
ACCELEROMETER_ANGLE_XY
]
資料來源,代表 X 和 Y 方向的角度總和。
使用下列程式碼片段取代 <!-- TODO: Add the Android logo -->
:
<Group x="92" y="92" width="266" height="266" name="logo_container">
<Variant mode="AMBIENT" target="alpha" value="0" />
<Transform target="angle" mode="BY" value="0.1 * [ACCELEROMETER_ANGLE_XY]" />
<PartImage x="97" y="0" width="72" height="72"
tintColor="[CONFIGURATION.themeColor.2]">
<Image resource="android"/>
</PartImage>
</Group>
重新部署錶面。如果您使用的是實體裝置,請戴上手錶並轉動手腕,看看 Android 標誌會如何移動!如果您使用的是模擬器,請開啟擴充模擬器控制項,然後在「虛擬感應器」中操控 X 和 Y 角度。
更新預覽畫面
還記得程式碼實驗室一開始時,我們看到有 preview.png
檔案,系統會使用這個檔案顯示錶面預覽畫面嗎?我們現在來更新這個錶面,讓它更貼近完成的錶面!
如要產生螢幕截圖,最簡單的方法就是使用模擬器。在錶面執行時,按下螢幕截圖按鈕:
確認擷取畫面已設為「Display Shape」:
儲存圖片,然後使用這張新圖片取代 res/drawable/preview.png
檔案。如同之前的做法,重新建構並部署錶面。
10. 恭喜
恭喜!您已瞭解使用錶面格式建立錶面的基礎知識!
本程式碼研究室的解決方案
您可以到 GitHub 取得本程式碼研究室的解決方案程式碼:
$ git clone https://github.com/android/codelab-watch-face-format
或者,您也可以將存放區下載為 ZIP 檔案:
後續步驟
您可以透過錶面格式做更多事。以下提供一些建議,供您參考:
強化錶面
準備發布
- 請查看記憶體用量工具,這項工具可分析錶面的記憶體用量,也是將錶面上傳至 Google Play 前必用的工具!