為 Wear OS 建構錶面

1. 事前準備

如要為 Wear OS 建立錶面,開發人員必須使用錶面格式,這是一種以 XML 為基礎的格式,可讓您建立生動且效能出色的錶面。

這個程式碼實驗室適合希望使用 XML 手工製作錶面的使用者,或是希望進一步瞭解格式以便自行建構設計工具的使用者。

如果您想使用圖形工具建立自己的錶面,建議您查看現有的工具,例如 Watch Face Studio

必要條件

  • 具備 XML 相關經驗。

執行步驟

在本程式碼研究室,您將學到:

  • WFF 錶面的封裝方式
  • 如何建立錶面,包括微光模式
  • 新增圖案等元素
  • 將資料來源納入錶面
  • 如何解決錶面相關問題

您將要建構的是可自訂的錶面,可選擇多種色彩主題、內建步數和日期指標。

90468c36ea8b7ca.png 324c4462145dbcc6.png

軟硬體需求

2. 瞭解錶面格式專案結構

下載程式碼實驗室檔案

如要開始使用,請在此下載本程式碼實驗室檔案

$ git clone https://github.com/android/codelab-watch-face-format

或者,您也可以將存放區下載為 ZIP 檔案:

watch-face-format 目錄中有兩個專案:startfinish。我們將使用 start 專案,但您隨時可以查看 finish 專案,其中包含已完成的程式碼實驗室。

讓我們檢查錶面格式專案的基本結構。您可以使用自己選擇的編輯器,也可以在 Android Studio 中依序點選「File」>「Open...」,然後選取 start 目錄,開啟起始專案。

start/watchface/src/main 目錄中,您會看到下列檔案,讓我們來看看每個檔案的功能:

檔案

說明

AndroidManifest.xml

就像一般 Android 應用程式一樣,這個檔案包含錶面相關的必要資訊,以及建構錶面所需的內容。

res/xml/watch_face_info.xml

錶面資訊檔案包含錶面中繼資料,例如如何找到預覽圖片,以及錶面是否可自訂。

res/raw/watchface.xml

這個檔案包含錶面本身的定義。雖然可以有多個定義,但這會是系統使用的預設檔案。

res/drawable/preview.png

每個錶面都需要系統使用的預覽圖片。為了讓這個專案能進行建構,start/ 資料夾含有空白預覽畫面,我們會稍後更新

res/drawable/hour.pngres/drawable/minute.pngres/drawable/second.png

這些是我們會在錶面中使用的指針。

res/values/strings.xml

就像 Android 應用程式一樣,包含可在錶面中使用的字串。

程式碼在哪裡?

請注意,專案中其實無程式碼。除了 AndroidManifest.xml 檔案外,專案的所有檔案都位於 res/ 資源目錄中。這是因為 WFF 錶面不得包含任何程式碼:例如,如果您嘗試加入 Kotlin 或 Java 程式碼,Play 商店將不接受這類內容。

Wear OS 系統會讀取這些資源,並負責為您建構及執行錶面。也就是說,您不需要任何執行階段或其他邏輯,因此可節省開發作業。

3. 建構錶面

我們將更新上述每個檔案,以便建立可運作的錶面。

準備資訊清單

為了將套件識別為 WFF 錶面,資訊清單需要宣告兩件事:

  1. 專案中無程式碼。
  2. 使用的錶面格式版本。

首先,請更新 <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

智慧手錶或模擬器上應該會顯示錶面了!恭喜!

b1ab1ed6a1ce8575.png

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
  • 樞紐:指針會自動旋轉,但 pivotXpivotY 會指定樞紐應出現的位置。以 pivotY 為例,計算方式如下:

f08428ae204605e1.png

c194bd487cebbe26.png

  • 變化版本<SecondHand> 包含 <Variant> 子元素,這會隱藏秒針,因為錶面在微光模式下只會每分鐘更新一次。

現在請執行以下指令,重新建構錶面並部署至裝置或模擬器:

./gradlew installDebug

這次我們有一個可運作的時鐘,但仍有許多改進空間!

52628bf6c0d30d09.png

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> 參照第三個顏色。

如先前所述,重新建構及部署錶面,即可看到彩色錶面!

e382aaf41c7990d9.png

不僅如此,如果長按錶面並輕觸設定按鈕,還有 6 種色彩主題可供選取!

79ffac91f7cabaf5.png

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> 元素:這會在微光模式下移除背景環,盡可能減少亮起的像素數量。

此外,也請注意我們再次使用色彩主題選取環狀區塊的顏色,以便在錶面上的所有元素中維持風格一致。

710c8969df19226b.png

7. 驗證錶面

在進一步改善錶面之前,我們先來瞭解如何使用「錶面格式驗證工具」簡化開發程序。

驗證工具可檢查 XML 是否正確,讓您在建構及部署錶面時,避免浪費時間製作出無法運作的錶面。

  1. 從 GitHub 存放區下載驗證工具 JAR 檔案
  2. 針對 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>

錶面格式支援各種資料來源,步數計數器是任何錶面都適合添加的絕佳選項,可讓使用者追蹤自己的日常活動和運動。

建構及部署錶面,查看這些最新加入的內容:

78cd5888c9e3a9a6.png

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>

8b5959083acc5689.png

每個知名錶廠都會在錶面加入自家標誌,因此我們也來加入自己的標誌吧!當然,我們可以使用 Android 標誌!

不過,由於這是智慧手錶,我們可以做點「特別」的嘗試,加入可根據配戴者手腕角度移動的標誌。

做法是將圖片放入 <Group> 元素中,然後使用 <Transform> 元素,根據手腕角度為 <Group> 元素套用「旋轉」效果。結構如下所示:

e738ca09c695ca93.png

元素的預設樞紐點位於中心,因此我們不需要調整 <Group>pivotXpivotY。將 <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 檔案,系統會使用這個檔案顯示錶面預覽畫面嗎?我們現在來更新這個錶面,讓它更貼近完成的錶面!

如要產生螢幕截圖,最簡單的方法就是使用模擬器。在錶面執行時,按下螢幕截圖按鈕:

6172ea8cc9309516.png

確認擷取畫面已設為「Display Shape」

9d90300c3ce4d8f.png

儲存圖片,然後使用這張新圖片取代 res/drawable/preview.png 檔案。如同之前的做法,重新建構並部署錶面。

10. 恭喜

恭喜!您已瞭解使用錶面格式建立錶面的基礎知識!

本程式碼研究室的解決方案

您可以到 GitHub 取得本程式碼研究室的解決方案程式碼:

$ git clone https://github.com/android/codelab-watch-face-format

或者,您也可以將存放區下載為 ZIP 檔案:

後續步驟

您可以透過錶面格式做更多事。以下提供一些建議,供您參考:

強化錶面

準備發布

  • 請查看記憶體用量工具,這項工具可分析錶面的記憶體用量,也是將錶面上傳至 Google Play 前必用的工具!