1. 准备工作
如需为 Wear OS 创建表盘,开发者必须使用表盘格式 (WFF),这是一种基于 XML 的格式,可让您创建富有表现力且性能出众的表盘。
本 Codelab 面向希望使用 XML 手工制作表盘的用户,或希望更好地了解该格式以帮助他们构建自己的设计工具的用户。
如果您想使用图形工具创建自己的表盘,我们建议您查看 Watch Face Studio 等现有工具。
前提条件
- 有 XML 方面的经验。
实践内容
在此 Codelab 中,您将学习:
- WFF 表盘的打包方法
- 如何创建包含微光模式的表盘
- 添加形状等元素
- 在表盘中整合数据源
- 如何排查表盘问题
您将构建一个可自定义的表盘,其中包含可供选择的各种颜色主题、内置步数和日期指示器。
所需条件
- Android Studio Meerkat 或更高版本 - 尽管并非必须直接使用 Android Studio,但这是确保您已安装 Android Build Tools 和 Platform Tools(这些工具后续会用到)的最简单方法。
- 一台 Wear OS 模拟器,或者一部已启用开发者选项的实体 Wear OS 手表。
2. 了解表盘格式项目结构
下载 Codelab 文件
首先,请在此处下载 Codelab 文件
$ git clone https://github.com/android/codelab-watch-face-format
或者,您可以下载代码库 Zip 文件:
在 watch-face-format
目录中有两个项目:start
和 finish
。我们将使用 start
项目,但您随时可以查看 finish
项目,其中包含完成的 Codelab。
我们来检查一下表盘格式项目的基本结构。您可以使用自己选择的编辑器,也可以在 Android Studio 中依次选择 File > Open… 并选择 start
目录,以打开 start 项目本身。
在 start/watchface/src/main
目录中,您将看到以下文件,我们来看看每个文件的作用:
文件 | 说明 |
| 与常规 Android 应用一样,此文件包含有关表盘以及构建表盘所需内容的必要信息。 |
| 表盘信息文件包含有关表盘的元数据,例如如何查找预览图片以及表盘是否可自定义。 |
| 此文件包含表盘本身的定义。虽然可以有多个定义,但这是使用的默认文件。 |
| 每个表盘都需要一个供系统使用的预览图片。为了构建此项目,start/ 文件夹中包含一个空白预览,我们稍后会对其进行更新 |
| 这些是将在表盘中使用的时针。 |
| 与 Android 应用一样,包含可在表盘中使用的字符串。 |
代码在哪里?
请注意,该项目中实际上并不包含任何代码。除了 AndroidManifest.xml
文件外,项目的所有文件都存放在 res/
目录下,即资源目录。这是因为表盘格式的表盘不能包含任何代码。例如,如果您尝试添加 Kotlin 或 Java 代码,Play 商店将不会接受这样的表盘。
Wear OS 系统会读取这些资源,并负责为您构建和运行表盘。这意味着您无需编写任何运行时或其他逻辑代码,从而节省了开发工作量。
3. 为 Wear OS 构建表盘
我们将更新上述每个文件,以创建一个实用的表盘。
准备清单文件
为了将软件包标识为表盘格式的表盘,清单文件需要声明以下两点:
- 项目中不包含任何代码。
- 所使用的表盘格式版本。
首先,更新 <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
下提供了预览图片。目前该文件为空,但后续我们会将其替换为已完成表盘的实际屏幕截图。
在本 Codelab 中,我们还将使表盘具备可自定义特性。我们还在 watch_face_info.xml file
中使用 <Editable>
元素声明来声明这一特性。
请更新 res/xml/watch_face_info.xml
文件,添加以下元素:
<Preview value="@drawable/preview" />
<Editable value="true" />
编写表盘格式的 XML 文件
实际表盘的定义包含在 res/raw/watchface.xml
文件中。请在编辑器中打开此文件查看。您会看到 <WatchFace>
元素为表盘定义了 450x450 的宽度和高度。在文件的其余部分都会使用这个坐标空间,并且无论表盘的实际像素尺寸是多少,都可以相应地进行缩放。
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!”,暂时还未实现时间显示功能!不过,我们稍后会回来解决这个问题。接下来,我们将构建表盘并将其部署到设备上。
构建和部署表盘
在命令行界面中,请确保您当前位于 start 目录,然后执行以下命令:
./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 角度。
更新预览
还记得在本 Codelab 的开头,我们提到的 preview.png
文件吗?系统会使用该文件来显示表盘预览。现在,让我们更新此文件,以更好地展示我们完成的表盘!
生成屏幕截图最简单的方法是使用模拟器。在表盘运行时,点击屏幕截图按钮:
确保截图设置为显示形状:
保存图片,并用此新图片替换 res/drawable/preview.png
文件。然后,像之前一样重新构建和部署表盘。
10. 恭喜
恭喜!您已经学习了使用表盘格式创建表盘的基础知识!
此 Codelab 的解决方案
您可以从 GitHub 获取本 Codelab 的解决方案代码:
$ git clone https://github.com/android/codelab-watch-face-format
或者,您可以下载代码库 Zip 文件:
后续操作
表盘格式的功能远不止于此。以下是一些建议,供您进一步探索:
增强表盘功能
准备发布
- 请查看内存占用工具,该工具可分析表盘的内存使用情况,是您在将表盘上传到 Google Play 之前不可或缺的辅助工具!