El desarrollo de widgets para la plataforma Android implica un conjunto de tareas ligeramente diferente al desarrollo de aplicaciones estándar. En esta serie de tutoriales, trabajaremos en el proceso de desarrollar un widget de reloj analógico personalizable. El reloj se basará en la clase AnalogClock de Android y se personalizará con tus propios gráficos..
Hasta ahora, en esta serie, hemos diseñado e implementado el widget en XML y Java y tenemos un widget de reloj en funcionamiento que el usuario puede agregar a su pantalla de inicio. En esta parte final de la serie, vamos a implementar la configuración básica del usuario. En la Parte 2 creamos varios diseños de reloj, por lo que ahora permitiremos al usuario elegir entre ellos.
Esta es la Parte 4 de 4 en una serie sobre Creación de un widget de reloj analógico de Android personalizable en cuatro tutoriales:
Construir la configuración del usuario en nuestra aplicación de widgets implicará una nueva clase de actividad Java, que presentará la selección de opciones al usuario. Cuando el usuario selecciona un diseño, actualizaremos la apariencia del widget y almacenaremos la elección del usuario según las Preferencias Compartidas de la aplicación. También ampliaremos la clase de widget para manejar los clics del usuario en el widget y leer de las Preferencias Compartidas para la elección del usuario. Además de trabajar con estos dos archivos Java, crearemos un nuevo archivo de valores y un archivo de diseño XML para la Actividad de la elección junto con algunas imágenes para mostrar dentro.
Primero, agreguemos algo de código a la clase de widget para detectar los clics de los usuarios. En la clase "ClockWidget", dentro de la declaración "if" en el método "onReceive", después de la línea en la que recuperamos el objeto de Vistas Remotas, agregue el siguiente código para crear un Intent para la Actividad del selector que vamos a usar:
Intención choiceIntent = new Intent (context, ClockChoice.class);
No te preocupes por los errores de Eclipse por ahora, desaparecerán cuando creemos la nueva clase de actividad en el siguiente paso. Después de esta línea, cree una Intención Pendiente de la siguiente manera:
PendingIntent clickPendIntent = PendingIntent.getActivity (context, 0, choiceIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Iniciar actividades con clics de widgets es un poco diferente, como puede ver. Observe que pasamos el objeto de contexto y una referencia a la nueva intención. Ahora agregue el siguiente código que especifica que la Intención pendiente se debe iniciar cuando se hace clic en el widget:
views.setOnClickPendingIntent (R.id.custom_clock_widget, clickPendIntent);
Especificamos el widget refiriéndonos al ID del diseño principal en el archivo XML "clock_widget_layout". Necesitamos usar las Vistas remotas para referirnos a los elementos de la interfaz de usuario, ya que estamos en una clase de widget en lugar de una clase de actividad. Agregaremos más código a esta clase más adelante..
Ahora para la Actividad en la que permitimos a los usuarios elegir un diseño. Cree una nueva clase en su proyecto haciendo clic derecho o seleccionando la carpeta del paquete de origen y seleccionando "Archivo"; luego seleccione "Nuevo", "Clase" e ingrese "ClockChoice" como el nombre de la clase. Eclipse abrirá la nueva clase cuando haga clic en Finalizar. Recuerde que incluimos esta actividad en el archivo de manifiesto del proyecto en la parte 1.
Haga de su nueva clase una actividad y una que maneje los clics de los usuarios al extender su línea de apertura de la siguiente manera:
La clase pública ClockChoice extiende los implementos de actividades OnClickListener
Una vez más, simplemente ignore los mensajes de error, aparecerán hasta que proporcionemos el método "onClick". Necesitará las siguientes declaraciones de importación:
importar android.app.Activity; importar android.view.View.OnClickListener;
Proporcione el método de actividad "onCreate" dentro de la clase de la siguiente manera:
public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.clock_choice);
Vamos a crear el archivo de diseño en el siguiente paso. Necesitará otra importación:
importar android.os.Bundle;
Agregaremos más código a esta clase más adelante..
Vamos a crear el diseño que especificamos en la clase de actividad anterior. Cree un nuevo archivo de diseño haciendo clic con el botón derecho o seleccionando la carpeta "res / layout" y seleccionando "Archivo", luego haciendo clic en "Nuevo", "Archivo" e ingresando "clock_choice.xml" para que coincida con la referencia en el código anterior.
Cuando Eclipse abre el archivo, seleccione la pestaña "clock_choice.xml" para editar el código. Ingrese el siguiente esquema de diseño en su archivo:
El diseño incluye un diseño lineal dentro de una vista de desplazamiento. Dentro del diseño lineal, primero agregue un texto informativo como sigue:
Agregue el recurso de cadena indicado aquí a su archivo "strings.xml"; asegúrese de incluirlo en las copias del archivo de cadena, en "valores" y "valores-v14":
Elija una opción:
Ahora vamos a mostrar una imagen para representar el diseño de cada reloj. Estas imágenes actuarán como botones para que los usuarios las presionen al seleccionar un diseño. Cree sus imágenes ahora, recuerde incluir diferentes versiones para cada densidad. Si todavía no desea crear su propia imagen, puede usar las imágenes en el enlace de descarga al final del tutorial; aquí están las versiones de densidad media de cada uno:
Guarde cada versión de sus imágenes en las carpetas dibujables para su aplicación, recuerde usar los mismos nombres en cada carpeta de densidad.
Ahora vuelve a tu archivo de diseño XML "clock_choice". Agregue un botón de imagen para cada diseño que esté usando, con lo siguiente para los tres diseños de ejemplo que hemos usado, después de la Vista de texto:
Hay varios puntos a tener en cuenta aquí. Primero, observe que cada botón de imagen tiene una ID con la misma sintaxis pero un entero incremental al final. Lo usaremos para recorrer los diseños en Java, por lo que si está incluyendo más de tres diseños, asegúrese de asignarlos en iteración. números, como "design_3", etc. Aparte de los atributos de diseño, cada elemento también indica el recurso dibujable relevante, así que modifíquelos si los archivos de imagen que acaba de crear tienen nombres diferentes. Finalmente, los atributos de descripción de contenido se refieren a recursos de cadena, así que agréguelos a los archivos "strings.xml" en sus carpetas de "valores" y "valores-v14" de la siguiente manera:
Diseño predeterminado Diseño de piedra Diseño de metal
Modifique estas descripciones si es necesario para adaptarlas a sus propios diseños..
Hagamos uso de los temas de Android para automatizar ciertos aspectos de la apariencia de la actividad del selector. Abra el archivo de manifiesto de su proyecto y extienda el elemento que representa la actividad del selector de reloj de la siguiente manera:
Al agregar el tema del diálogo, la actividad aparece superpuesta en la pantalla de inicio. Esta es su apariencia con los diseños de muestra que hemos utilizado en esta serie de tutoriales:
Esto es lo que aparecerá cuando el usuario haga clic en el widget. Si la pantalla del dispositivo es demasiado pequeña para dar cabida a los tres diseños, se desplazarán ya que el diseño utiliza una Vista de desplazamiento. Cuando el usuario selecciona un diseño, la apariencia del widget se actualizará y esta actividad de la opción desaparecerá.
No hace falta decir que es posible que desee modificar el número de diseños posibles dentro de su aplicación de widget de reloj. Para facilitar este proceso, vamos a hacer que nuestro código Java lea la cantidad de diseños de forma dinámica. Para este propósito, vamos a utilizar un valor numérico para realizar un seguimiento de la cantidad de diseños que estamos utilizando. Cree un nuevo archivo en cada una de sus dos carpetas de valores, haga clic con el botón derecho o seleccione cada carpeta por turno y seleccione "Archivo" y luego "Nuevo", "Archivo" y escriba "numbers.xml" como nombre de archivo.
Seleccione la pestaña "numbers.xml" e ingrese el siguiente código en su nuevo archivo:
3
Modifique el número si usó un número diferente de diseños, asegurándose de que el valor coincida con el número de Botones de imagen que incluyó en el diseño y el número de elementos de Reloj analógico que tiene en el diseño de su widget. Recuerde que necesita una copia del archivo "numbers.xml" en ambas carpetas de valores, así que cópielo y péguelo si es necesario.
Si modifica el número de diseños que está utilizando en cualquier momento, debe modificar el valor en el (los) archivo (s) "numbers.xml", agregar cada diseño como un elemento de Reloj analógico en el archivo "clock_widget_layout" de la aplicación y un Botón de imagen para cada diseño en el archivo de diseño de la actividad del selector.
Vamos a manejar la interacción del usuario con la selección de diseños de reloj. Abra su archivo de actividad "ClockChoice". Dentro de la clase, antes del método "onCreate", agregue las siguientes variables de instancia:
// cuenta de diseños private int numDesigns; // botones de imagen para cada diseño privado ImageButton [] designBtns; // identificadores para cada elemento de reloj privado int [] diseños;
Usaremos estas variables para recorrer los distintos diseños. Añadir otra importación:
importar android.widget.ImageButton;
Dentro del método "onCreate", después del código existente, cree una instancia de la variable para realizar un seguimiento del número de diseños de reloj, de la siguiente manera:
numDesigns = this.getResources (). getInteger (R.integer.num_clocks);
Aquí recuperamos el valor en el archivo XML de números que creamos anteriormente. Podremos usar este valor como referencia al iterar a través de los diseños. A continuación, cree una instancia de las matrices para los botones de diseño y los elementos del reloj:
designBtns = new ImageButton [numDesigns]; designs = new int [numDesigns];
La primera matriz se referirá a los botones de imagen que estamos usando dentro de esta actividad de selección para detectar la elección del usuario. La segunda matriz almacenará referencias a los elementos del reloj analógico para cada diseño en el archivo de diseño del widget..
Ahora agregue un bucle para iterar a través de los diseños:
para (int d = 0; dDentro del bucle, recupere una referencia a cada elemento del reloj analógico en el diseño del widget:
designs [d] = this.getResources (). getIdentifier ("AnalogClock" + d, "id", getPackageName ());Si vuelve a mirar el archivo "clock_widget_layout", verá que cada elemento del reloj analógico tiene una ID que comprende "AnalogClock" seguido de un entero incremental. Lo usamos aquí para recuperar una referencia de cada uno usando el contador de bucle. A continuación, aún dentro del bucle, recupere los valores de ID para los Botones de imagen en el diseño de Actividad del selector:
designBtns [d] = (ImageButton) findViewById (this.getResources (). getIdentifier ("design _" + d, "id", getPackageName ()));Aquí estamos usando "findViewById" para obtener una referencia al elemento relevante del Botón de imagen, pasando la ID, que comprende "diseño_" seguido del entero de incremento. Ahora configure el detector de clics para cada uno de estos botones para que podamos manejar los clics en esta clase de actividad. Mientras aún está dentro del bucle:
designBtns [d] .setOnClickListener (this);Ahora podemos seguir adelante con el método de clic para los botones de diseño. Después del método "onCreate" en la clase "ClockChoice", agregue un método "onClick" de la siguiente manera:
vacío público onClick (ver v)Agregue la siguiente importación:
importar android.view.View;En el método "onClick", primero debemos determinar qué botón ha presionado el usuario. Agregue el siguiente bucle dentro del método para este propósito:
int elegido = -1; para (int c = 0; cAquí verificamos la ID de la vista en la que se hizo clic contra las ID que hemos almacenado en la matriz del Botón de imagen. Cuando el bucle sale, tenemos el índice elegido almacenado en una variable local. Después de que el bucle almacene una referencia a la ID para el elemento de reloj analógico elegido:
int pickClock = diseños [picked];Ahora necesitamos obtener una referencia a los elementos de diseño del widget, para lo que necesitamos las Vistas remotas, pasando el diseño del widget como referencia:
RemoteViews remoteViews = nuevas RemoteViews (this.getApplicationContext (). GetPackageName (), R.layout.clock_widget_layout);Para esto necesitas otra declaración de importación:
importar android.widget.RemoteViews;Recuerde que incluimos cada diseño de Reloj analógico en el archivo de diseño del widget; esto se debe a que no podemos alterar dinámicamente los atributos de un Reloj analógico, como los elementos extraíbles para el dial y las manos, por lo que incluimos todos los diseños y configuramos todos pero uno para ser invisible. Antes de configurar el diseño del reloj elegido para que sea visible, configuraremos los demás para que sean invisibles, lo que podemos hacer en un bucle de la siguiente manera:
para (int d = 0; dUsamos la matriz en la que almacenamos los valores de ID del elemento del reloj analógico para establecer cada uno invisible siempre que no sea el elegido. Ahora podemos configurar el diseño elegido para que sea visible, después de este bucle:
remoteViews.setViewVisibility (pickedClock, View.VISIBLE);Ahora, debido a que esta es una aplicación de widget, necesitamos actualizar la apariencia del widget de la siguiente manera:
// obtener el nombre del componente para la clase del widget ComponentName comp = new ComponentName (este, ClockWidget.class); // obtener AppWidgetManager AppWidgetManager appWidgetManager = AppWidgetManager.getInstance (this.getApplicationContext ()); // actualizar appWidgetManager.updateAppWidget (comp, remoteViews);Esto es similar a la forma en que actualizamos el widget en la clase de proveedor de widgets, pero con un par de pasos de procesamiento adicionales porque estamos en una clase de actividad aquí. Deberá agregar estas importaciones:
importar android.appwidget.AppWidgetManager; importar android.content.ComponentName;Ahora la apariencia del widget se actualizará de acuerdo con la elección del usuario..
Paso 5: Actualizar las preferencias compartidas
A continuación, vamos a utilizar la aplicación Preferencias compartidas para almacenar la opción de diseño del usuario. Realice una copia de seguridad en la parte superior de la clase de actividad de elección de reloj, agregue otra variable de instancia:
PrivatePreferences clockPrefs privadas;Ahora, al final del método "onCreate", después del código existente, agregue lo siguiente para crear una instancia de la variable de Preferencias Compartidas:
clockPrefs = getSharedPreferences ("CustomClockPrefs", 0);Usaremos el mismo nombre de preferencias cada vez que accedamos a los datos con respecto a la elección del usuario. Ahora muévase hacia el final del método "onClick", después del código en el que actualizamos el widget. Obtenga el editor de preferencias de la siguiente manera:
SharedPreferences.Editor custClockEdit = clockPrefs.edit ();Ahora pase los datos relacionados con la elección del usuario al editor y confírmelos:
custClockEdit.putInt ("clockdesign", seleccionado); custClockEdit.commit ();Especificamos un nombre para el valor de los datos y la ID del diseño elegido. Finalmente, aún dentro de "onClick", agregue lo siguiente mientras se realiza el trabajo de la Actividad:
terminar();
Paso 6: Verifique las preferencias compartidas
Ahora podemos hacer uso de los datos de Preferencias Compartidas desde la clase de widget. Abra su clase "ClockWidget", que extiende AppWidgetProvider. Los algoritmos que usamos aquí serán similares a los que usamos anteriormente para administrar los diseños de reloj. Agregue las siguientes variables de instancia adicionales en la parte superior:
// preferencias privadas SharedPreferences custClockPrefs; // número de diseños posibles private int numClocks; // ID de los elementos del reloj analógico int [] clockDesigns;Necesitarás la siguiente importación:
importar android.content.SharedPreferences;En el método "onReceive", antes de el código existente, recupere el número de diseños de nuestro recurso de valor:
numClocks = context.getResources (). getInteger (R.integer.num_clocks);A continuación, cree una instancia de la matriz de ID de reloj de la siguiente manera:
clockDesigns = new int [numClocks];Ahora recorra esta matriz, configurando cada elemento como el ID del elemento analógico relevante en el diseño del widget:
para (int d = 0; dAhora pase al contenido de la declaración "if" en el método "onReceive", después de la línea en la que recuperamos las Vistas remotas y antes de la línea en la que creamos la intención para la clase de elección de reloj, obtenga las Preferencias compartidas y verifique para el valor de los datos que configuramos para la elección del usuario:
custClockPrefs = context.getSharedPreferences ("CustomClockPrefs", 0); int chosenDesign = custClockPrefs.getInt ("clockdesign", -1);El nombre de las Preferencias Compartidas y el valor del valor de los datos deben coincidir con lo que incluyó cuando configuró la opción del usuario en la Actividad del selector de arriba. Es posible que el usuario aún no haya elegido un diseño, así que incluya una declaración "if" para verificar:
if (chosenDesign> = 0)Dentro de la declaración "if", primero haga un bucle a través de los diseños, configurando cada uno invisible si no es el elegido:
para (int d = 0; dNecesitará otra importación:
importar android.view.View;Ahora establece el diseño elegido visible:
views.setViewVisibility (clockDesigns [chosenDesign], View.VISIBLE);Ahora, cuando se actualiza el widget, si el usuario ha elegido un diseño, se mostrará ese diseño.
Conclusión
Ese es el widget de reloj completado! Puede ejecutarlo en un emulador o dispositivo para probarlo. Debe ejecutarse continuamente, actualizando el tiempo y reflejando la elección de diseño del usuario..
Tómese un tiempo para mirar hacia atrás sobre los diversos elementos de la aplicación y asegúrese de comprender cómo funcionan en conjunto unos con otros. El proceso de desarrollar cualquier otra aplicación de widget implicará muchos de los mismos pasos. Los elementos vitales en una aplicación de widget son: el elemento XML "appwidget-provider", el archivo Manifest, la clase que extiende AppWidgetProvider y, por supuesto, los elementos visuales que incluyen diseños y recursos.
Si está buscando desarrollar más las habilidades que ha aprendido en esta serie, hay una variedad de opciones. Si desea proporcionar una configuración de usuario avanzada para sus widgets, puede usar una Actividad de preferencias junto con la acción APPWIDGET_CONFIGURE. Si desea incluir pantallas de reloj digital junto con sus opciones analógicas, el proceso es un poco más complejo. Puede incluir la clase predeterminada de Reloj Digital en una aplicación estándar, pero no en una aplicación de widget, por lo que debe implementar la visualización de la hora digital y actualizarse usted mismo, utilizando componentes adicionales como Servicios y Gestores de alarmas..
Siéntase libre de usar el código fuente completo y las imágenes para este tutorial proporcionado en el enlace de descarga.