1. Antes de comenzar
Para crear caras de reloj para Wear OS, los desarrolladores deben usar el Formato de Caras de Relojes que está basado en XML y te permite crear caras de reloj expresivas y de alto rendimiento.
Este codelab está dirigido para quienes deseen crear caras de reloj de forma manual con XML o quienes quieran comprender mejor el formato para crear sus propias herramientas de diseño.
Si quieres usar herramientas gráficas para crear tu propia cara de reloj, te recomendamos que mires las herramientas existentes, como Watch Face Studio.
Requisitos previos
- Experiencia con XML
Actividades
En este codelab, aprenderás lo siguiente:
- Cómo se empaquetan las caras de reloj de WFF
- Cómo crear una cara de reloj, incluido el modo ambiente
- Cómo agregar elementos, como formas
- Cómo incorporar fuentes de datos en la cara de reloj
- Cómo solucionar problemas con tu cara de reloj
Crearás una cara de reloj personalizable, con una variedad de temas de colores para elegir, un contador de pasos integrado y un indicador de fecha.
Requisitos
- Android Studio Meerkat o una versión posterior (si bien no es necesario usar Android Studio directamente, esta es la forma más fácil de garantizar que tengas instaladas las Herramientas de compilación de Android y las Herramientas de la plataforma que se usarán)
- Un emulador de Wear OS o un reloj Wear OS físico (con las opciones para desarrolladores habilitadas)
2. Información sobre la estructura de proyectos del Formato de Caras de Relojes
Descarga los archivos del codelab
Para comenzar, descarga los archivos del codelab aquí.
$ git clone https://github.com/android/codelab-watch-face-format
También tienes la opción de descargar el repositorio como archivo ZIP:
Hay dos proyectos en el directorio watch-face-format
: start
y finish
. Usaremos el proyecto start
, pero puedes consultar el proyecto finish
en cualquier momento, ya que contiene el codelab terminado.
Inspeccionemos la estructura básica del proyecto de Formato de Caras de Relojes. Puedes usar el editor que elijas o abrir el proyecto de partida en Android Studio seleccionando File > Open… y el directorio start
.
En el directorio start/watchface/src/main
, verás los siguientes archivos. Veamos qué hace cada uno:
Archivo | Descripción |
| Al igual que en una app para Android normal, este archivo contiene información esencial sobre la cara de reloj y lo que se necesita para compilarla. |
| El archivo de información de la cara de reloj contiene metadatos sobre ella, como cómo encontrar la imagen de vista previa y si se puede personalizar. |
| Este archivo contiene la definición de la cara de reloj. Si bien es posible tener más de una definición, este es el archivo predeterminado que se usa. |
| Cada cara de reloj necesita una imagen de vista previa que use el sistema. Para que se compile este proyecto, la carpeta start/ contiene una vista previa en blanco. La actualizaremos más adelante. |
| Estas son las manecillas del reloj que usaremos en nuestra cara de reloj. |
| Al igual que en una app para Android, contiene cadenas que se pueden usar en la cara de reloj. |
¿Dónde está el código?
Observa que, en realidad, no hay código en el proyecto. Además del archivo AndroidManifest.xml
, todos los archivos del proyecto residen en res/
, el directorio de recursos. Esto se debe a que las caras de reloj del Formato de Caras de Relojes no pueden contener código. Por ejemplo, si intentas incluir código Kotlin o Java, Play Store no lo aceptará.
El sistema Wear OS lee estos recursos y se encarga de compilar y ejecutar tu cara de reloj por ti. Esto significa que no se necesita ningún entorno de ejecución ni ninguna otra lógica, lo que te ahorra esfuerzo de desarrollo.
3. Compila una cara de reloj
Actualizaremos cada uno de los archivos anteriores para crear una cara de reloj funcional.
Prepara el manifiesto
Para identificar el paquete como una cara de reloj del Formato de Caras de Relojes, el manifiesto debe declarar dos aspectos:
- Que no hay código en el proyecto
- Es la versión del Formato de Caras de Relojes que se usa
Primero, actualiza el elemento <application>
para agregar el atributo hasCode
:
<application
android:label="@string/watch_face_name"
android:hasCode="false">
En segundo lugar, agrega un <property>
al elemento <application>
que especifique la versión del Formato de Caras de Relojes que se usa en esta cara de reloj:
<property
android:name="com.google.wear.watchface.format.version"
android:value="1" />
Define el archivo watch_face_info
El archivo watch_face_info.xml
tiene un requisito obligatorio: especificar la ubicación de la imagen de vista previa. En este proyecto, proporcionamos una imagen de vista previa en res/drawable/preview.png
. Este es un archivo en blanco, pero lo actualizaremos más adelante con una captura de pantalla real de nuestra cara de reloj terminada.
Como parte del codelab, también haremos que nuestra cara de reloj sea personalizable. También lo declaramos en watch_face_info.xml file
con el elemento <Editable>
.
Actualiza res/xml/watch_face_info.xml
para agregar los siguientes elementos:
<Preview value="@drawable/preview" />
<Editable value="true" />
Escribe XML de Formato de Caras de Relojes
La definición de la cara de reloj real se encuentra en res/raw/watchface.xml
. Inspecciona este archivo en tu editor. Verás que el elemento <WatchFace>
define un ancho y una altura de 450 por 450 para la cara de reloj. Este espacio de coordenadas se usa en todo el resto del archivo, independientemente de las dimensiones de píxeles reales en las que se ejecuta la cara de reloj, y se ajusta según corresponda.
El XML es el siguiente:
<?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>
Por ahora, esta definición solo mostrará "Hello World!" en el reloj. Lamentablemente, aún no es la hora (pero volveremos a arreglar esto). Veamos cómo compilar la cara de reloj y cómo transferirla al dispositivo.
Compila e implementa la cara de reloj
En la línea de comandos, asegúrate de estar en el directorio de inicio y, luego, ingresa el siguiente comando:
./gradlew installDebug
O en Windows:
gradlew.bat installDebug
Se compilará la cara de reloj y se instalará en el dispositivo. Mantén presionada la pantalla de la cara de reloj y busca la cara de reloj Codelab. Como alternativa, para configurar la cara de reloj desde la línea de comandos, usa lo siguiente:
adb shell am broadcast -a com.google.android.wearable.app.DEBUG_SURFACE --es operation set-watchface --es watchFaceId com.example.codelab
Ahora deberías ver la cara de reloj en tu reloj o emulador. ¡Felicitaciones!
4. Agrega la hora
El Formato de Caras de Relojes admite la visualización de relojes analógicos y digitales, incluso puedes tener ambos o varios en una sola cara de reloj.
Veamos cómo agregar un reloj analógico con el elemento <
AnalogClock
>
. Primero, quita todo el elemento <
PartText
>
del archivo watchface.xml
y reemplázalo por lo siguiente:
<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>
El elemento <AnalogClock>
tiene una altura y un ancho de 450, por lo que ocupa toda la pantalla. También tiene tres elementos secundarios: <
HourHand
>
, <
MinuteHand
>
y <
SecondHand
>
. Ten en cuenta lo siguiente sobre cómo se definen:
- Recurso: Cada uno de estos elementos secundarios tiene un atributo de recurso, que corresponde a un recurso de diseño. Por ejemplo, hay un archivo
hour.png
enres/drawable
, que usa el elemento<HourHand>
. Ten en cuenta que no es necesario especificar@drawable
. - Reorientaciones: Las manecillas rotan automáticamente, pero
pivotX
ypivotY
especifican dónde debe ocurrir la reorientación. A modo de ejemplo,pivotY
se calcula de la siguiente manera:
- Variante: El
<SecondHand>
incluye un elemento secundario<
Variant
>
, que oculta el segundero, ya que la cara de reloj solo se actualizará cada minuto cuando esté en modo ambiente.
Ahora, ejecuta el siguiente comando para volver a compilar y, luego, implementar la cara de reloj en tu dispositivo o emulador:
./gradlew installDebug
Esta vez, tenemos un reloj que funciona, aunque aún podemos hacer mucho para mejorarlo.
5. Agrega colores y temas
Parte de lo que hace que las caras de reloj sean divertidas es la capacidad de personalizarlas y hacerlas expresivas.
Nuestra cara de reloj es un poco simple en este momento, ya que es completamente blanca, así que agreguemos un poco de color. Además, hagamos que los temas de colores sean personalizables.
Crea el objeto ColorConfiguration
Primero, definiremos los temas de color que estarán disponibles en la cara de reloj. En watchface.xml
, busca el texto <!-- TODO: Add UserConfigurations here -->
y reemplázalo por lo siguiente:
<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>
Esto define 6 temas de colores, cada uno con 5 colores. Cada tema es una lista de colores separados por espacios, como se muestra en el atributo colors
.
Cada uno de los temas necesitará un nombre fácil de entender, por lo que debes agregar las siguientes definiciones al archivo 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>
Usa ColorConfiguration
Después de definir los temas de color, aplícalos a las manecillas del reloj agregando un atributo tintColor
a cada una de ellas. Modifica watchface.xml
de la siguiente manera:
<HourHand ... tintColor="[CONFIGURATION.themeColor.0]">
...
<MinuteHand ... tintColor="[CONFIGURATION.themeColor.1]">
...
<SecondHand ... tintColor="[CONFIGURATION.themeColor.2]">
<HourHand>
hace referencia al primer color del tema seleccionado, <MinuteHand>
al segundo color y <SecondHand>
al tercero.
Vuelve a compilar y, luego, implementa la cara de reloj, como antes, y verás que ahora tiene color.
Además, si mantienes presionada la cara de reloj y presionas el botón de configuración, puedes elegir entre los 6 temas de colores.
6. Agrega un color de fondo
Hay algunas otras cosas que podemos hacer para que esta cara de reloj se destaque. Agreguemos un diseño de fondo en negrita. Si bien el fondo seguirá siendo predominantemente negro, este toque de color ayudará a mejorar el aspecto.
Usaremos el elemento <
PartDraw
>
del Formato de Caras de Relojes, que te permite crear una capa para dibujar primitivas, como líneas, rectángulos, óvalos y arcos. Reemplaza el texto <!-- TODO: Add the background design here -->
por lo siguiente:
<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>
Observa nuevamente el uso del elemento <Variant>
; esto quitará nuestro anillo de fondo cuando esté en modo ambiente para minimizar la cantidad de píxeles iluminados.
Observa también cómo volvemos a usar el tema de color para seleccionar el color del anillo, de modo que se mantenga el diseño en todos los elementos de la cara de reloj.
7. Valida tu cara de reloj
Antes de continuar con la mejora de la cara de reloj, exploremos cómo optimizar el proceso de desarrollo con el uso del validador de Formato de Caras de Relojes.
El validador es una herramienta que verifica la exactitud de tu XML, lo que te ahorra tiempo en la compilación y la implementación de una cara de reloj solo para descubrir que no funciona.
- Descarga el archivo JAR del validador desde el repositorio de GitHub.
- Ejecuta el validador en tu archivo
watchface.xml
.
java -jar wff-validator.jar 1 watchface/src/main/res/raw/watchface.xml
Si el XML de la cara de reloj es válido, verás un mensaje de confirmación. Sin embargo, si se encuentra un error, se mostrarán los detalles del error y la ubicación, por ejemplo:
SEVERE: [Line 18:Column 49]: cvc-complex-type.2.4.a: Invalid content was found starting with element 'PartDrw'
8. Usa fuentes de datos
El Formato de Caras de Relojes puede usar una variedad de fuentes de datos diferentes para que tu cara de reloj sea más útil.
Agreguemos dos fuentes de datos de uso general que ayudan a que tu cara de reloj sea más útil: la fecha actual (¿quién no se olvidó de la fecha antes?) y el recuento de pasos diario.
Cada uno de estos elementos se coloca en un contenedor <
PartText
>
, que es una capa para realizar operaciones de texto.
Agrega la fecha
Reemplaza el texto <!-- TODO: Add the date/time element here -->
por lo siguiente:
<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>
En el fragmento anterior, usamos <
Template
>
para dar formato a dos fuentes de datos en una cadena. DAY
es un número entero del 1 al 31 y MONTH_S
ya es una cadena, por lo que usamos la expresión de formato %d %s
para colocar el número entero y la cadena juntos.
Es recomendable rodear esto con un elemento CDATA
, ya que evita que se incorporen espacios en blanco de forma accidental en la renderización, lo que puede afectar la posición y la alineación.
Por último, observa nuevamente cómo usamos el tema de color para asegurarnos de que esta última incorporación a la cara de reloj mantenga el tema existente.
Agrega el recuento de pasos
Reemplaza el texto <!-- TODO: Add the step count element here -->
por lo siguiente:
<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>
El Formato de Caras de Relojes admite una amplia variedad de fuentes de datos, y el recuento de pasos es una gran incorporación a cualquier cara de reloj, ya que le permite al usuario hacer un seguimiento de su movimiento y ejercicio diarios.
Compila y, luego, implementa la cara de reloj para verificar estas incorporaciones más recientes:
9. Retoques finales y vista previa
La atención a los detalles es fundamental en las caras de reloj, así que agreguemos algunos detalles finales adicionales.
Agrega sombras a la cara de reloj
Las manecillas de la cara de reloj funcionan bien en sus diferentes colores, pero se ven un poco planas en la cara de reloj. Reemplaza <!-- TODO: Add shadows here later -->
por lo siguiente para agregar sombras detrás de las manecillas del reloj:
<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>
Agrega un logotipo divertido
Todos los fabricantes de relojes conocidos tienen su logotipo en sus caras de reloj, así que agreguemos el nuestro. Por supuesto, usemos el logotipo de Android.
Sin embargo, como se trata de un reloj inteligente, hagamos algo diferente y agreguemos un logotipo que pueda moverse en respuesta al ángulo de la muñeca de quien lo usa.
Para ello, colocaremos nuestra imagen dentro de un elemento <
Group
>
y, luego, usaremos un elemento <
Transform
>
para aplicar una rotación al elemento <Group>
, según el ángulo de la muñeca. Nuestra estructura se verá de la siguiente manera:
El punto de reorientación predeterminado de un elemento está en el centro, por lo que no es necesario ajustar pivotX
y pivotY
de <Group>
. Si aplicas un <Transform>
a <Group>
, se rotará <PartImage>
alrededor de ese punto de pivote central.
En <Transform>
, usamos la fuente de datos [
ACCELEROMETER_ANGLE_XY
]
, que representa la suma de los ángulos en la dirección X e Y.
Reemplaza <!-- TODO: Add the Android logo -->
por el siguiente fragmento:
<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>
Vuelve a implementar la cara de reloj. Si usas un dispositivo físico, póntelo y mueve la muñeca para ver cómo se mueve el logotipo de Android. Si usas un emulador, abre los controles extendidos del emulador y manipula los ángulos X e Y en los sensores virtuales.
Actualiza la vista previa
¿Recuerdas que, al comienzo del codelab, vimos que hay un archivo preview.png
, que el sistema usa para mostrar una vista previa de la cara de reloj? Ahora, actualicemos esto para que refleje mejor nuestra cara de reloj terminada.
La forma más fácil de generar una captura de pantalla es con el emulador. Con la cara de reloj en ejecución, haz clic en el botón de captura de pantalla:
Asegúrate de que la captura esté configurada en Display Shape:
Guarda la imagen y reemplaza el archivo res/drawable/preview.png
por esta imagen nueva. Vuelve a compilar y, luego, implementa la cara de reloj como antes.
10. Felicitaciones
¡Felicitaciones! Aprendiste los conceptos básicos para crear una cara de reloj con el Formato de Caras de Relojes.
Solución del codelab
Puedes obtener el código de la solución de este codelab en GitHub:
$ git clone https://github.com/android/codelab-watch-face-format
También tienes la opción de descargar el repositorio como archivo ZIP:
Próximos pasos
Hay mucho más que puedes hacer con el Formato de Caras de Relojes. Estas son algunas sugerencias sobre qué hacer a continuación:
Mejora tu cara de reloj
- Agrega complicaciones para incluir datos adicionales en tu cara de reloj.
- Considera usar una cara de reloj digital en lugar de una analógica.
- Explora más funciones del formato.
Prepárate para publicar
- Consulta la herramienta de espacio en memoria, que analiza el uso de memoria de tu cara de reloj y es una herramienta esencial para usar antes de subirla a Google Play.