Construire un widget d'horloge personnalisé Implémentation de la configuration utilisateur

Le développement de widgets pour la plate-forme Android implique un ensemble de tâches légèrement différent de celui du développement d'applications standard. Dans cette série de didacticiels, nous allons suivre le processus de développement d’un widget horloge analogique personnalisable. L'horloge sera basée sur la classe Android AnalogClock et personnalisée avec vos propres graphiques..

Jusqu'à présent, dans cette série, nous avons conçu et mis en œuvre le widget en XML et Java et avons un widget d'horloge qui fonctionne, que l'utilisateur peut ajouter à son écran d'accueil. Dans cette dernière partie de la série, nous allons implémenter la configuration utilisateur de base. Dans la partie 2, nous avons créé plusieurs conceptions d’horloge, nous allons donc permettre à l’utilisateur de choisir entre elles..

Voici la partie 4 de 4 d'une série sur la création d'un widget d'horloge analogique Android personnalisable dans quatre didacticiels:

  • Configuration du projet Widget Android
  • Concevoir l'horloge
  • Réception des mises à jour et lancement
  • Implémentation de la configuration utilisateur

La création de la configuration utilisateur dans notre application de widget impliquera une nouvelle classe d'activité Java, présentant le choix des choix à l'utilisateur. Lorsque l'utilisateur sélectionne une conception, nous mettrons à jour l'apparence du widget et stockerons le choix de l'utilisateur dans les préférences partagées de l'application. Nous allons également étendre la classe de widgets pour gérer les clics de l'utilisateur sur le widget et les lire à partir des préférences partagées pour le choix de l'utilisateur. En plus de travailler avec ces deux fichiers Java, nous allons créer un nouveau fichier de valeurs et un fichier d’agencement XML pour le choix Activité avec quelques images à afficher..


Étape 1: gérer les clics sur le widget

Premièrement, ajoutons du code à la classe de widgets pour détecter les clics d’utilisateur. Dans la classe "ClockWidget", dans l'instruction "if" de la méthode "onReceive", après la ligne dans laquelle nous avons extrait l'objet Remote Views, ajoutez le code suivant pour créer une intention pour le sélecteur Activité que vous allez utiliser:

 Intention choiceIntent = new Intent (context, ClockChoice.class);

Ne vous inquiétez pas des erreurs Eclipse pour l'instant, elles disparaîtront lorsque nous créerons la nouvelle classe d'activité à l'étape suivante.. Après cette ligne, créez une intention en attente comme suit:

 PendingIntent clickPendIntent = PendingIntent.getActivity (context, 0, choiceIntent, PendingIntent.FLAG_UPDATE_CURRENT);

Lancer des activités sur des clics de widget est un peu différent, comme vous pouvez le voir. Notez que nous transmettons l'objet Context et une référence à la nouvelle intention. Ajoutez maintenant le code suivant spécifiant que l’intention en attente doit être lancée lorsque vous cliquez sur le widget:

 views.setOnClickPendingIntent (R.id.custom_clock_widget, clickPendIntent);

Nous spécifions le widget en faisant référence à l'ID de la mise en page parent dans le fichier XML "clock_widget_layout". Nous devons utiliser les vues distantes pour faire référence aux éléments de l'interface utilisateur, car nous sommes dans une classe de widgets plutôt que dans une classe d'activité. Nous ajouterons plus de code à cette classe plus tard.


Étape 2: Créer une activité de sélecteur

Passons maintenant à l’activité dans laquelle nous laissons les utilisateurs choisir un design. Créez une nouvelle classe dans votre projet en cliquant avec le bouton droit de la souris ou en sélectionnant le dossier du paquet source, puis en choisissant "Fichier". Sélectionnez ensuite "Nouveau", "Classe" et entrez "ClockChoice" comme nom de classe. Eclipse ouvrira la nouvelle classe lorsque vous cliquerez sur Terminer. Rappelez-vous que nous avons inclus cette activité dans le fichier Manifest du projet de la partie 1..

Faites de votre nouvelle classe une activité et une qui gérera les clics de l'utilisateur en prolongeant sa ligne d'ouverture comme suit:

 Classe publique ClockChoice Etend Activity implémente OnClickListener 

Encore une fois, ignorez tout message d'erreur, ils apparaîtront jusqu'à ce que nous fournissions la méthode "onClick". Vous aurez besoin des déclarations d'importation suivantes:

 importer android.app.Activity; importer android.view.View.OnClickListener;

Indiquez la méthode "onCreate" d'activité dans la classe, comme suit:

 public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.clock_choice); 

Nous allons créer le fichier de mise en page à l'étape suivante. Vous aurez besoin d'une autre importation:

 importer android.os.Bundle;

Nous ajouterons plus de code à cette classe plus tard.


Étape 3: Conception de l'activité du sélecteur

Créons la mise en page spécifiée dans la classe d'activité ci-dessus. Créez un nouveau fichier de présentation en cliquant avec le bouton droit de la souris ou en sélectionnant le dossier "res / layout" et en choisissant "Fichier", puis en cliquant sur "Nouveau", "Fichier" et en entrant "clock_choice.xml" pour correspondre à la référence dans le code ci-dessus.

Lorsque Eclipse ouvre le fichier, sélectionnez l'onglet "clock_choice.xml" pour modifier le code. Entrez le schéma de mise en page suivant dans votre fichier:

    

La conception comprend une disposition linéaire dans une vue de défilement. Dans la mise en page linéaire, ajoutez d'abord un texte informatif comme suit:

 

Ajoutez la ressource String indiquée ici dans votre fichier "strings.xml" - en vous assurant de l'inclure dans les deux copies du fichier strings, dans "values" et "values-v14":

 Choisis une option:

Nous allons maintenant afficher une image pour représenter chaque conception d'horloge. Ces images vont servir de boutons sur lesquels les utilisateurs peuvent appuyer pour sélectionner un dessin. Créez vos images maintenant, en vous rappelant d'inclure différentes versions pour chaque densité. Si vous ne voulez pas créer les vôtres, vous pouvez utiliser les images dans le lien de téléchargement au bas du didacticiel. Voici les versions de densité moyenne de chacune:

Enregistrez chaque version de vos images dans les dossiers pouvant être dessinés pour votre application, en utilisant les mêmes noms dans chaque dossier de densité..

Revenez maintenant à votre fichier XML de présentation "clock_choice". Ajoutez un bouton d'image pour chaque motif que vous utilisez, avec les éléments suivants pour les trois exemples de motifs que nous avons utilisés, après la vue de texte:

   

Il y a plusieurs points à noter ici. Notez tout d'abord que chaque bouton d'image a un identifiant avec la même syntaxe, mais un entier incrémentant à la fin. Nous l'utilisons pour parcourir les conceptions en Java. Par conséquent, si vous incluez plus de trois conceptions, assurez-vous de les affecter à une itération. des nombres, tels que "design_3", etc. Outre les attributs de conception, chaque élément indique également la ressource pouvant être appelée, puis modifiez-les si les fichiers image que vous venez de créer portent des noms différents. Enfin, les attributs de description de contenu font référence à des ressources de chaîne. Ajoutez-les donc aux fichiers "strings.xml" de vos dossiers "values" et "values-v14" comme suit:

 Conception par défaut Conception de pierre Conception en métal

Modifiez ces descriptions si nécessaire en fonction de vos propres conceptions..

Utilisons des thèmes Android pour automatiser certains aspects de l’apparence de l'activité du sélecteur. Ouvrez le fichier manifeste du projet et développez l’élément représentant le sélecteur d’horloge Activity comme suit:

  

En ajoutant le thème de la boîte de dialogue, l’activité apparaît superposée sur l’écran d’accueil. C’est son apparence avec les exemples de conceptions que nous avons utilisés dans cette série de didacticiels:


C'est ce qui apparaîtra lorsque l'utilisateur cliquera sur le widget. Si l'écran de l'appareil est trop petit pour accueillir les trois modèles, ils défileront au fur et à mesure que la présentation utilise une vue défilement. Lorsque l'utilisateur sélectionne un dessin, l'apparence du widget sera mise à jour et ce choix Activité disparaîtra.

Il va sans dire que vous voudrez peut-être modifier le nombre de conceptions possibles dans votre application de widget horloge. Pour faciliter ce processus, nous allons faire en sorte que notre code Java lise le nombre de conceptions de manière dynamique. Pour ce faire, nous allons utiliser une valeur numérique pour suivre le nombre de conceptions que nous utilisons. Créez un nouveau fichier dans chacun de vos deux dossiers de valeurs, en cliquant avec le bouton droit de la souris ou en sélectionnant chaque dossier et en choisissant "Fichier", puis "Nouveau", "Fichier" et en entrant "numbers.xml" comme nom de fichier.


Sélectionnez l'onglet "numbers.xml" et entrez le code suivant dans votre nouveau fichier:

  3 

Modifiez le nombre si vous avez utilisé un nombre différent de motifs, en vous assurant que la valeur correspond au nombre de boutons d'image que vous avez inclus dans la présentation et au nombre d'éléments d'horloge analogique que vous avez dans votre présentation de widget. N'oubliez pas que vous avez besoin d'une copie du fichier "numbers.xml" dans les deux dossiers de valeurs, donc copiez-le et collez-le si nécessaire..

Si vous modifiez le nombre de conceptions que vous utilisez à un moment donné, vous devez modifier la valeur dans le (s) fichier (s) "numbers.xml", ajouter chaque conception en tant qu'élément Analog Clock dans le fichier "clock_widget_layout" de l'application, ainsi qu'un fichier. Bouton Image pour chaque motif du sélecteur Fichier de présentation d'activité.


Étape 4: Gérer le choix de l'utilisateur

Gérons les interactions de l'utilisateur avec la sélection de modèles d'horloge. Ouvrez votre fichier d'activité "ClockChoice". Dans la classe, avant la méthode "onCreate", ajoutez les variables d'instance suivantes:

 // nombre de designs private int numDesigns; // boutons d'image pour chaque conception privée ImageButton [] designBtns; // identifiants pour chaque élément d'horloge private int [] designs;

Nous utiliserons ces variables pour parcourir les différentes conceptions. Ajouter une autre importation:

 importer android.widget.ImageButton;

Dans la méthode "onCreate", après le code existant, instanciez la variable pour garder une trace du nombre de modèles d'horloge, comme suit:

 numDesigns = this.getResources (). getInteger (R.integer.num_clocks);

Ici, nous récupérons la valeur dans le fichier de nombres XML que nous avons créé précédemment - nous pourrons utiliser cette valeur comme référence lors d'une itération dans les conceptions. Procédez ensuite à l'instanciation des tableaux pour les boutons de conception et les éléments d'horloge:

 designBtns = new ImageButton [numDesigns]; designs = new int [numDesigns];

Le premier tableau se référera aux boutons d'image que nous utilisons dans ce sélecteur d'activité pour détecter le choix de l'utilisateur. Le second tableau va stocker des références aux éléments d'horloge analogique pour chaque conception dans le fichier de présentation de widget lui-même..

Ajoutez maintenant une boucle pour parcourir les dessins:

 pour (int d = 0; d 

Dans la boucle, récupérez une référence à chaque élément Analog Clock de la présentation du widget:

 designs [d] = this.getResources (). getIdentifier ("AnalogClock" + d, "id", getPackageName ());

Si vous regardez le fichier "clock_widget_layout", vous verrez que chaque élément Analog Clock a un ID comprenant "AnalogClock" suivi d'un entier incrémentant - nous l'utilisons ici pour récupérer une référence à chacun en utilisant le compteur de boucles. Ensuite, toujours dans la boucle, récupérez les valeurs d’ID pour les boutons d’image dans la structure d’activité du sélecteur:

 designBtns [d] = (ImageButton) findViewById (this.getResources (). getIdentifier ("design _" + d, "id", getPackageName ());

Ici, nous utilisons "findViewById" pour obtenir une référence à l'élément Image Button pertinent, en passant l'ID, qui comprend "design_" suivi de l'entier incrémentant. Définissez maintenant l'écouteur de clic pour chacun de ces boutons afin que nous puissions gérer les clics dans cette classe d'activité. Bien que toujours dans la boucle:

 designBtns [d] .setOnClickListener (this);

Nous pouvons maintenant utiliser la méthode du clic pour les boutons de conception. Après la méthode "onCreate" de la classe "ClockChoice", ajoutez une méthode "onClick" comme suit:

 vide publique onClick (View v) 

Ajoutez l'importation suivante:

 importer android.view.View;

Dans la méthode "onClick", nous devons d’abord déterminer le bouton sur lequel l’utilisateur a appuyé. Ajoutez la boucle suivante dans la méthode à cette fin:

 int choisi = -1; pour (int c = 0; c 

Ici, nous comparons l’ID de vue cliqué par rapport aux ID que nous avons stockés dans le tableau Bouton Image. Lorsque la boucle se termine, l'index choisi est stocké dans une variable locale. Après la boucle, enregistrez une référence à l’ID de l’élément Analog Clock choisi:

 int pickClock = dessins [choisis];

Nous devons maintenant obtenir une référence aux éléments de présentation du widget, pour lesquels nous avons besoin des vues distantes, en passant la présentation du widget comme référence:

 RemoteViews remoteViews = new RemoteViews (this.getApplicationContext (). GetPackageName (), R.layout.clock_widget_layout);

Pour cela, vous avez besoin d'une autre déclaration d'importation:

 importer android.widget.RemoteViews;

N'oubliez pas que nous avons inclus chaque conception d'horloge analogique dans le fichier de présentation du widget. En effet, nous ne pouvons pas modifier de manière dynamique les attributs d'une horloge analogique, tels que les éléments dessinables pour le cadran et les aiguilles. mais un pour être invisible. Avant de définir la conception d'horloge choisie pour être visible, nous allons définir les autres comme invisibles, ce que nous pouvons faire en boucle comme suit:

 pour (int d = 0; d 

Nous utilisons le tableau dans lequel nous avons stocké les valeurs d’identification d’élément Analog Clock pour les définir toutes invisibles tant que ce n’est pas celui qui a été choisi. Maintenant, nous pouvons définir le design choisi pour être visible, après cette boucle:

 remoteViews.setViewVisibility (pickClock, View.VISIBLE);

Comme il s'agit d'une application de widget, nous devons mettre à jour l'apparence du widget comme suit:

 // récupère le nom du composant pour la classe de widget NomComposant comp = new NomComposant (this, ClockWidget.class); // get AppWidgetManager AppWidgetManager appWidgetManager = AppWidgetManager.getInstance (this.getApplicationContext ()); // met à jour appWidgetManager.updateAppWidget (comp, remoteViews);

Ceci est similaire à la façon dont nous avons mis à jour le widget dans la classe de fournisseur de widget, mais avec quelques étapes de traitement supplémentaires car nous sommes dans une classe d'activité ici. Vous devrez ajouter ces importations:

 importer android.appwidget.AppWidgetManager; importer android.content.ComponentName;

Maintenant, l'apparence du widget sera mise à jour en fonction du choix de l'utilisateur.


Étape 5: Mettre à jour les préférences partagées

Ensuite, nous allons utiliser l’application Préférences partagés pour stocker le choix de conception de l’utilisateur. Sauvegardez la classe d'activité en haut du choix d'horloge, ajoutez une autre variable d'instance:

 PrivatePreferences privées clockPrefs;

Maintenant, à la fin de la méthode "onCreate", après le code existant, ajoutez ce qui suit pour instancier la variable Shared Preferences:

 clockPrefs = getSharedPreferences ("CustomClockPrefs", 0);

Nous utiliserons le même nom de préférences chaque fois que nous accéderons aux données relatives au choix de l'utilisateur. Passez maintenant à la fin de la méthode "onClick", après le code dans lequel nous avons mis à jour le widget. Obtenez l'éditeur de préférences comme suit:

 SharedPreferences.Editor custClockEdit = clockPrefs.edit ();

Maintenant, passez les données concernant le choix de l'utilisateur à l'éditeur et validez-le:

 custClockEdit.putInt ("clockdesign", sélectionné); custClockEdit.commit ();

Nous spécifions un nom pour la valeur de données et l'ID de la conception choisie. Enfin, toujours dans "onClick", ajoutez ce qui suit lorsque le travail de l'activité est terminé:

 terminer();

Étape 6: Vérifier les préférences partagées

Nous pouvons maintenant utiliser les données des préférences partagées de la classe de widgets. Ouvrez votre classe "ClockWidget", qui étend AppWidgetProvider. Les algorithmes que nous utilisons ici seront similaires à ceux que nous avons utilisés ci-dessus pour gérer les conceptions d'horloge. Ajoutez les variables d'instance supplémentaires suivantes en haut:

 // préférences private SharedPreferences custClockPrefs; // nombre de conceptions possibles private int numClocks; // ID des éléments d'horloge analogique int [] clockDesigns;

Vous aurez besoin de l'importation suivante:

 importer android.content.SharedPreferences;

Dans la méthode "onReceive", avant le code existant, récupérez le nombre de conceptions de notre ressource de valeur:

 numClocks = context.getResources (). getInteger (R.integer.num_clocks);

Ensuite, instanciez le tableau d'ID d'horloge comme suit:

 clockDesigns = new int [numClocks];

Parcourez maintenant ce tableau en définissant chaque élément comme ID de l'élément Analog Clock correspondant dans la présentation du widget:

 pour (int d = 0; d 

Passez maintenant au contenu de l'instruction "if" dans la méthode "onReceive", après la ligne dans laquelle nous avons extrait les vues distantes et avant la ligne dans laquelle nous avons créé l'intention de la classe de choix d'horloge, obtenez les préférences partagées et vérifiez pour la valeur de données définie pour le choix de l'utilisateur:

 custClockPrefs = context.getSharedPreferences ("CustomClockPrefs", 0); int selectedDesign = custClockPrefs.getInt ("clockdesign", -1);

Le nom des préférences partagées et le nom de la valeur de données doivent correspondre à ce que vous avez inclus lors de la définition du choix de l'utilisateur dans l'activité de sélection ci-dessus. L'utilisateur n'a peut-être pas encore choisi de modèle. Vous devez donc inclure une instruction "if" à vérifier:

 si (conception choisie> = 0) 

Dans la déclaration "if", commencez par parcourir les dessins, en définissant chaque invisible si ce n'est pas celui qui a été choisi:

 pour (int d = 0; d 

Vous aurez besoin d'une autre importation:

 importer android.view.View;

Maintenant, affichez le design choisi:

 views.setViewVisibility (clockDesigns [selectedDesign], View.VISIBLE);

Maintenant, lorsque le widget est mis à jour, si l'utilisateur a choisi un design, ce design sera affiché.


Conclusion

C'est le widget d'horloge terminé! Vous pouvez l'exécuter sur un émulateur ou un périphérique pour le tester. Il devrait fonctionner en permanence, mettre à jour l'heure et refléter le choix de conception de l'utilisateur.


Prenez le temps de passer en revue les différents éléments de l’application et d’en comprendre le fonctionnement. Le processus de développement de toute autre application de widget impliquera de nombreuses étapes identiques. Les éléments essentiels d'une application de widget sont: l'élément XML "appwidget-provider", le fichier Manifest, la classe d'extension de AppWidgetProvider et bien sûr les éléments visuels, notamment les dispositions et les ressources..

Si vous souhaitez développer davantage les compétences que vous avez acquises dans cette série, vous avez le choix entre plusieurs options. Si vous souhaitez fournir une configuration utilisateur avancée pour vos widgets, vous pouvez utiliser une activité de préférence avec l'action APPWIDGET_CONFIGURE. Si vous souhaitez inclure des affichages d'horloge numérique avec vos options analogiques, le processus est un peu plus complexe. Vous pouvez inclure la classe d'horloge numérique par défaut dans une application standard, mais pas dans une application de widget. Vous devez donc implémenter l'affichage de l'heure numérique et les mettre à jour vous-même, à l'aide de composants supplémentaires tels que des services et des gestionnaires d'alarmes..

N'hésitez pas à utiliser le code source complet et les images de ce didacticiel fourni dans le lien de téléchargement..