Crear un widget de reloj personalizado: Diseño de reloj
Spanish (Español) translation by CYC (you can also view the original English article)
El desarrollo de widgets para la plataforma Android implica un conjunto ligeramente diferente de tareas que el desarrollo de aplicaciones estándar. En esta serie de tutoriales, trabajaremos en el proceso de desarrollo de un widget de reloj analógico personalizable. El reloj se basará en la clase Android AnalogClock y se personalizará con tus propios gráficos.
Resumen de la serie
En esta serie de tutoriales estamos desarrollando un widget de reloj analógico Android personalizable utilizando la clase AnalogClock y gráficos personalizados. En la primera parte de la serie, creamos el proyecto, preparamos el archivo Manifest y otros recursos. En esta parte, trabajaremos en el diseño del widget. Esto implicará la creación de gráficos para la esfera del reloj y las agujas, así como la implementación del diseño en XML. Crearemos gráficos para diferentes densidades de dispositivo. En la parte final de la serie, vamos a implementar un permiso para que el usuario pueda elegir entre una selección de diseños para el reloj, por lo que crearemos tres opciones de diseño aquí.
Esta es la Parte 2 de nuestra serie sobre Cómo construir un widget de reloj analógico Android personalizable en cuatro tutoriales:
- Configuración del proyecto Widget en Android
- Diseñando el reloj
- Recibir actualizaciones y ejecutar
- Implementando la configuración del usuario
El widget Android AnalogClock utiliza tres imágenes: el dial del reloj, el minutero y la manecilla de la hora. Por lo tanto, crearemos tres elementos de diseño para cada versión del widget de reloj de los cuales queremos que los usuarios puedan elegir. También crearemos opciones de diseño alternativas con dial, hora y minutero. Para este proyecto, necesitaremos enfocarnos en las diferentes densidades de pantalla del dispositivo, para lo cual crearemos archivos de imágenes en cuatro escalas diferentes.
Paso 1: Crear imágenes para el reloj
Vamos a crear tres diseños de reloj, cada uno con un dial, minutero y manecilla de horas. Por supuesto que puedes usar tus propios diseños, pero puedes usar los archivos de imagen que estamos usando aquí para comenzar. Los archivos de imagen para cada diseño en cada densidad se incluyen en el enlace de descarga para este tutorial y también se incluirán en la descarga de la Parte 4.
Primero está el dial del reloj. Recuerda que especificamos el widget con dos celdas de ancho y dos celdas de alto, lo que da como resultado un tamaño máximo de 146dp (píxeles independientes de la densidad). Para esta serie de tutoriales crearemos cuatro versiones de cada imagen para adaptarse a las cuatro categorías de densidad.
En lugar de crear imágenes para cada densidad, alternativamente puedes usar gráficos NinePatch, los cuales son mapas de bits que se pueden ampliar y reducir para adaptarse a las densidades de los dispositivos, lo que te permite crear una sola imagen para cada diseño. La posibilidad de utilizar NinePatch depende en parte del contenido de los diseños que estás utilizando, pero hay herramientas para ayudarte a crearlos si lo deseas.
Es más fácil si comienzas con la densidad media, que debe ser un máximo de 146px en ambos ejes. Aquí está el dial de reloj predeterminado que estamos utilizando en densidad media, que puedes utilizar como referencia para tus propios diseños o por si no deseas crear el tuyo:

En este caso, la imagen es 146px en ambos ejes, pero puedes hacerla más pequeña si lo deseas. Especificaremos un margen para los dispositivos con una API de Android menores de 14, pero no proporcionaremos un margen para los dispositivos con más de 14, porque en los niveles API más recientes se coloca un margen automático entre los widgets. Puedes usar casi cualquier diseño que desees: tu reloj ni siquiera tiene que ser circular. Incluir marcas o números que indiquen las horas en la esfera es aconsejable desde una perspectiva de usabilidad, aunque no es esencial.
Aquí están los dos diseños alternativos de reloj dial que utilizaremos, uno estilo piedra y el otro metalizado, que se muestra aquí en densidad media:


Una vez que hayas diseñado los diales de tu reloj, puedes crear versiones alternativas de cada imagen para las diferentes densidades. Dependiendo de tus diseños, puede que no sea necesario, pero incluiremos versiones personalizadas de cada imagen para los diseños en este tutorial. A continuación, se indica el tamaño máximo que estamos usando para nuestro widget en los ejes X e Y en cada densidad:
- Densidad baja: 110px
- Densidad media: 146px
- Densidad alta: 220px
- Densidad extra alta: 292px
Cuando tengas archivos de imagen para cada diseño de dial del reloj que quieras usar (y versiones para cada densidad, si corresponde), cópialos en las carpetas drawables en tu espacio de trabajo widget del proyecto Android. Eclipse normalmente creará una carpeta para cada categoría de densidad automáticamente, pero, si solo estás usando una imagen para todas las densidades, puedes crear una carpeta simplemente llamada "drawable" y colocar allí la imagen. Las carpetas para cada nivel de densidad son:
- Baja: drawable-lpdi
- Medio: drawable-mpdi
- Alta: drawable-hpdi
- Extra alta: drawable-xhpdi
El administrador Android AVD te permitirá probar tu proyecto de widget terminado en cada una de estas densidades. Después de guardar tus imágenes en las distintas carpetas drawables, asegúrate de haber utilizado los mismos nombres en cada una de ellas. Por ejemplo, uno de los diseños del dial que estamos usando se llama "clock_dial_stone"; este es el nombre de archivo de la imagen para el dial de piedra en cada carpeta de densidad, aunque el contenido de cada versión es diferente, aunque solo sea en tamaño. Si todavía tienes dudas acerca de cómo debería funcionar esto, solo descarga los archivos de imágenes usando el enlace de descarga en la parte superior de este tutorial y explora las carpetas para obtener la idea.
Paso 2: Crea las imágenes de las manecillas del reloj
Ahora crea una imagen para tus manecillas de horas y minutos, incluidas las imágenes para cada diseño y cada densidad a la que te diriges. Aquí están nuestras manecillas para los minutos con una densidad media en cada diseño:



Nuevamente, siéntete libre de usarlos para comenzar o para trabajar en el tuyo. Ten en cuenta que estos archivos de imagen contienen espacio transparente alrededor de la manecilla. Debes diseñar cada una de tus imágenes de manecilla con la altura completa de la esfera del reloj con la que se van a utilizar. Cada manecilla debe estar en la posición exacta en que estaría cuando señale las doce, colocada sobre la imagen del cuadrante del reloj y a la mitad de ella. La manecilla también debe estar en el centro de tu archivo de imagen horizontalmente, ya que se rotará desde su punto central al mostrar la hora. La longitud de las manecillas dentro del archivo de imagen depende de ti, siempre que la altura total de la imagen sea la misma que la altura de la imagen de cuadrante.
El siguiente diagrama muestra la escala completa de las imágenes de las manecillas con la manecilla de los minutos en las doce, en las tres (la manecilla de las horas se ha girado 90 grados en el sentido de las agujas del reloj en su punto central):

Una vez que hayas ordenado tus diseños de minutos, guarda uno para cada densidad nuevamente, escalando hacia arriba y hacia abajo para que coincida con la altura de la marcación del reloj en cada caso. Cópialos nuevamente en tus carpetas drawables, usando el mismo nombre para cada diseño en las carpetas de densidad que las imágenes de marcado.
A continuación, lleva a cabo el mismo proceso para tus manecillas de horas. Aquí están las manecillas de las horas para los tres diseños que estamos usando:



El principio aquí es el mismo que para los minuteros, excepto que las manecillas de las horas normalmente deberían ser más cortas. Diseña las manecillas de las horas que apuntan a las 12 en punto y prepara versiones para cada densidad, copiándolas en tus carpetas drawables como lo hiciste con los minuteros.
Paso 3: Definir los márgenes de los widgets
El diseño del widget va a usar algunos datos que incluiremos en las carpetas "values" de nuestro proyecto. En Android API 14 en adelante, el sistema incluye automáticamente márgenes entre widgets tal como aparecen en la pantalla de inicio del usuario. Sin embargo, en versiones anteriores de API este no era el caso. Por este motivo, queremos especificar un margen para incluir el widget alrededor del reloj en dispositivos con niveles de Android inferiores a 14. Este es un caso en el que podemos aprovechar el hecho de que tenemos carpetas de valores que se dirigen a estas dos categorías de niveles de API de usuario.
Definiremos los márgenes en nuestro archivo de diseño XML al referirnos a un recurso de dimensión. En el directorio "values", crea un nuevo archivo llamado "dimensions.xml" - Selecciona la carpeta "values" en Eclipse y haz clic con el botón derecho o elige "Archivo", luego "Nuevo", "Archivo" e ingresa el nombre del archivo.



Cuando hagas clic en el botón "Finalizar", Eclipse creará y abrirá el archivo. Selecciona la pestaña "dimensions.xml" para editar el código. Introduce lo siguiente:
1 |
|
2 |
<resources>
|
3 |
<dimen name="clock_margin">8dp</dimen> |
4 |
</resources>
|
Este código simplemente enumera un valor de dimensión utilizando píxeles independientes de la densidad junto con un nombre para que podamos referirnos a él en otro lugar.
Guarda el archivo. Ahora cópialo haciendo clic con el botón derecho en la carpeta "values" o seleccionándolo y seleccionando "Editar" - luego selecciona "Copiar". Pégalo en la carpeta "values-v14" que creamos la última vez: haz clic con el botón derecho o selecciona la carpeta y selecciona "Editar", luego selecciona "Pegar". El archivo aparecerá en la carpeta "values-v14", que se dirige a niveles de API desde 14 en adelante. Abre esta nueva copia del archivo y edita el valor de la dimensión para indicar un margen de cero de la siguiente manera:
1 |
|
2 |
<resources>
|
3 |
<dimen name="clock_margin">0dp</dimen> |
4 |
</resources>
|
Ahora, cuando el diseño XML se refiere a este valor de dimensión con su nombre, se usará un valor de cero en dispositivos que ejecuten API 14 plus y un valor de 8dp se utilizará en caso contrario.
Paso 4: Implementar el diseño de widgets
Ahora definamos nuestro widget en XML. Recuerda que especificamos un diseño inicial para el widget en el archivo XML en el que definimos sus propiedades básicas. El diseño al que nos referimos allí era "clock_widget_layout" así que crea este archivo ahora. Haz clic derecho o selecciona tu carpeta de "layout" y elige "Archivo", luego "Nuevo", "Archivo". Ingresa "clock_widget_layout.xml" como el nombre del archivo y haz clic en "Finalizar".



Selecciona la pestaña "clock_widget_layout.xml" cuando Eclipse abra el archivo para que puedas editar el XML. Estamos usando un Diseño Relativo para nuestro widget: si deseas utilizar un diseño diferente, puedes usar alternativamente un Diseño Lineal o de Frame Layout, ya que estos son los únicos compatibles con los widgets. Para usar el diseño relativo, agrega el siguiente esquema a tu archivo de diseño XML:
1 |
|
2 |
<RelativeLayout
|
3 |
xmlns:android="http://schemas.android.com/apk/res/android" |
4 |
android:id="@+id/custom_clock_widget" |
5 |
android:layout_width="fill_parent" |
6 |
android:layout_height="fill_parent" |
7 |
android:padding="@dimen/clock_margin" |
8 |
android:gravity="center"> |
9 |
|
10 |
</RelativeLayout>
|
Aquí especificamos un ID para el widget, que usaremos para implementar clics en nuestro código Java en la Parte 4. Observa que el código también se refiere al valor de dimensión que creamos, utilizando la sintaxis estándar: el nombre de "dimensions.xml " el archivo en realidad no importa, solo necesitas listar un elemento "dimen" en un archivo de valores para referirte a él de esta manera.
Dentro del Diseño Relativo o Relative Layout, agrega tu widget de reloj analógico de la siguiente manera:
1 |
|
2 |
<AnalogClock
|
3 |
android:id="@+id/AnalogClock0" |
4 |
android:layout_width="wrap_content" |
5 |
android:layout_height="wrap_content" |
6 |
android:dial="@drawable/clock_dial" |
7 |
android:hand_hour="@drawable/clock_hour_hand" |
8 |
android:hand_minute="@drawable/clock_minute_hand" |
9 |
/>
|
Este es el elemento estándar del reloj analógico de Android, que nos permite personalizar la pantalla. Usamos un atributo ID para que podamos referirnos al widget en Java. Los últimos tres atributos especifican los recursos drawables que creamos para las manecillas del dial, minuto y hora. Si guardaste el tuyo con diferentes nombres de archivo, modifica este código para reflejarlos. Android seleccionará el archivo drawable de la carpeta de densidad relevante en cada dispositivo de usuario.
Dado que les permitimos a los usuarios elegir un diseño, de hecho vamos a incluir los tres diseños en nuestro XML, configurando todos, excepto uno, para que sean inicialmente invisibles. Asegúrate de que el primer diseño que incluyas sea el que deseas mostrar de forma predeterminada, luego agrega los otros de la siguiente manera:
1 |
|
2 |
<AnalogClock
|
3 |
android:id="@+id/AnalogClock1" |
4 |
android:layout_width="wrap_content" |
5 |
android:layout_height="wrap_content" |
6 |
android:dial="@drawable/clock_dial_stone" |
7 |
android:hand_hour="@drawable/clock_hour_hand_stone" |
8 |
android:hand_minute="@drawable/clock_minute_hand_stone" |
9 |
android:visibility="invisible" |
10 |
/>
|
11 |
<AnalogClock
|
12 |
android:id="@+id/AnalogClock2" |
13 |
android:layout_width="wrap_content" |
14 |
android:layout_height="wrap_content" |
15 |
android:dial="@drawable/clock_dial_metal" |
16 |
android:hand_hour="@drawable/clock_hour_hand_metal" |
17 |
android:hand_minute="@drawable/clock_minute_hand_metal" |
18 |
android:visibility="invisible" |
19 |
/>
|
Nuevamente, modifica los nombres drawables para reflejar los nombres de las imágenes de los diales, minutos y horas para cada uno de tus diseños. Puedes incluir más de tres diseños si lo deseas: asegúrate de que todos, excepto uno de ellos, tengan la visibilidad configurada como invisible, de modo que solo aparezca un diseño (la opción predeterminada) inicialmente. Podremos implementar la elección del usuario entre estos diseños en Java utilizando los atributos de ID del elemento del reloj analógico, que finalizan con números enteros que comienzan en cero y se incrementan con cada diseño. Guarda tu archivo de diseño.
Aquí hay unas capturas de pantalla de cómo se verán cada uno de nuestros diseños cuando se complete el widget:









Lo que vendrá
Ese es el proceso completo de diseño de nuestro widget de reloj. Si no deseas crear tus propias imágenes de diseño en esta etapa, simplemente usa las imágenes en la carpeta de descargas al principio. En el siguiente tutorial usaremos la clase AppWidgetProvider para implementar nuestro widget en Java. En la parte final de la serie implementaremos los clics del usuario en el widget, presentando una opción entre los diseños y actualizando las preferencias del usuario para mostrar continuamente su opción elegida.



