Interfaces graphiques Android
Introduction
- Android peut être installé sur une multitude d'appareils
- Les fonctionnalités d'Android disponibles dépendent de la version installée et des composants matériels d'un appareil
- Une application Android doit s'adapter à l'appareil
- En ajustant les interfaces graphiques affichées à l'écran
- Et en dégradant les fonctionnalités liées à des composants manquants
- Les APIs du SDK permettent de détecter l'environnement d'exécution et d'assurer la rétro-compatibilité d'une application
- La conception des interfaces graphiques Android diffèrent de celle des interfaces graphiques traditionnelles
- Android supporte la déclaration d'interfaces graphiques en XML afin de simplifier le code à écrire pour créer des écrans
- Chaque écran d'une application est géré par une activité
Principes
- Une interface graphique est un arbre de composants graphiques décrivant le rendu affiché à l'écran
- Un composant graphique peut contenir d'autres composants
- Un composant est dit "conteneur" s'il peut contenir d'autres composants
- Sinon le composant est dit "non-conteneur"
- Note : les composants graphiques appliquent le design pattern Composite
- Chaque composant graphique correspond à une classe
- Les classes sont rangées selon une arborescence d'héritage
- Arborescence qui n'a rien à voir avec un arbre de composants graphiques
- Les interfaces graphiques Android appliquent le modèle MVC
- Model : données de l'interface
- View : écran affiché (arbre de composants graphiques)
- Controller : gère les actions utilisateurs
- La logique métier est généralement déléguée à un composant
Construction
- Layout : désigne un composant graphique conteneur (classe héritant de ViewGroup)
- Widget : désigne un composant graphique non-conteneur (classe héritant de View) = élément de contrôle
- Un ID peut être attribué à un composant pour l'identifier
- Android supporte deux modes de définition d'interfaces
- Procédural : l'interface graphique est complètement codée en Java (comme avec AWT et SWING)
- Déclaratif : l'interface graphique est décrit dans un fichier XML pouvant être transformé en arbre de composants
- Le mode déclaratif permet d'utiliser des éditeurs graphiques pour générer le code XML par simple glisser/déposer
- Le mode procédural est parfois obligatoire pour pallier à certaines restrictions du mode déclaratif
Exemple du mode procédural
public class BoutonHeureActivite
extends Activity implements View.OnClickListener {
private Button btn;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
btn = new Button(this);
btn.setOnClickListener(this);
updateTime();
setContentView(btn);
}
public void onClick(View view) {
updateTime();
}
private void updateTime() {
btn.setText(new Date().toString());
}
}Classe BoutonHeureActivite.java
Exemple du mode déclaratif
public class BoutonHeure2Activite
extends Activity
implements View.OnClickListener {
private Button btn;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.activity_main);
btn = (Button)
findViewById(R.id.button1);
btn.setOnClickListener(this);
updateTime();
}
public void onClick(View view) {
updateTime();
}
private void updateTime() {
btn.setText(new Date().toString());
}
}<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<Button
android:id="@+id/button1"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:layout_alignParentLeft="true"
android:text="Button" />
</LinearLayout>Classe BoutonHeureActivite.java
Fichier XML res/layout/activity_main.xml
Layout
- Un layout gère la disposition de composants graphiques
- Parallèle avec AWT (et SWING) : un layout Android est comparable à l'association d'un layout et d'un container AWT
- Des layouts génériques ont été implémentés au fil des versions
- FrameLayout : layout le plus simple affichant un seul élément
- GridLayout : organise les éléments dans une grille virtuelle
- LinearLayout : organise les éléments en ligne horizontale ou verticale
- RelativeLayout : organise les éléments les uns par rapport aux autres
- TableLayout : organise les éléments dans un tableau
- Il existe des layouts adaptés à un certain type de contenu
- CardView : affiche une carte d'informations (cf. spécification Material Design)
- ListView : affiche des éléments dans une liste verticale
- WebView : affiche une page web (affichage basé sur un DOM)
- Rappel : tous les layouts héritent de la classe ViewGroup
Layout
FrameLayout
GridLayout
TableLayout
LinearLayout
RelativeLayout
Widget
- Un widget est un composant graphique affiché à l'écran et représentant une interaction avec l'utilisateur
- Le mot widget est la contraction de window object
- En IHM, un widget est un contrôle
- Android supporte de nombreux widgets
- Button : affiche un bouton
- CheckBox : affiche une case à cocher
- EditText : affiche une zone de saisie
- RadioButton : affiche un bouton radio
(groupé dans un RadioGroup) - Spinner : affiche un menu déroulant
- TextView : affiche une zone de texte
- ToogleButton : affiche un bouton on/off
- Rappel : tous les widgets héritent de la classe View

Gestion des évènements graphiques
- Un widget produit différents événements
- Des événements communs à tous les widgets
- Des événements spécifiques à certains types de widgets
- Un callback est une méthode appelée automatiquement pour traiter un événement lorsqu'il se produit
- Différentes possibilités existent pour associer un callback à un évènement
- Créer un auditeur d'événements (adapté au type d'événement) et l'associer au widget
- Déclarer la méthode de callback utilisée pour traiter un événement directement dans le fichier XML de l'activité
- Une méthode de callback doit impérativement être publique, accepter un unique paramètre View et ne rien retourner (void)
Déclaration d'un callback
public class MyActivity
extends Activity
implements View.OnClickListener {
private Button btn;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.activity_main);
// Récupération du Button à partir
// de l'IHM en XML
btn = (Button)
findViewById(R.id.button1);
// Enregistrer l'auditeur auprès
// du bouton
btn.setOnClickListener(this);
}
public void onClick(View view) {
// code lancé lorsque le bouton
// est cliqué
}
}<LinearLayout ...>
...
<Button
android:id="@+id/button1"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:text="@strings/button1Label"
android:onClick="doSomething" />
</LinearLayout>Utilisation d'un auditeur d'évènements
Association d'un callback dans le fichier XML
public class MyActivity
extends Activity {
...
public void doSomething(View view) {
// code lancé lorsque le bouton
// est cliqué
}
}Déclaration du callback dans l'activité
Liaison d'écrans
- Une application est une successions d'écrans gérés par une activité implémentant une fonctionnalité
- L'activité principale est le premier écran affiché
- Une activité doit être déclarée dans le manifeste pour pouvoir être affichée à l'écran
- L'utilisation d'une intention permet de changer d'écran
- Les méthodes d'une intention permettent d'échanger des données entre les activités
- La méthode startActivity() exécute une intention pour changer d'écran (elle reçoit l'intention en paramètre)
- Note : la méthode getApplicationContext() permet de récupérer le contexte de l'application
Exemple de changement d'écran
Intent i = new Intent(getApplicationContext(), MapStationActivity.class);
i.putExtra("latitude", latitudeDuPointCourant);
i.putExtra("longitude", longitudeDuPointCourant);
startActivity(i);Message d'avertissement Toast
- Le widget Toast est un widget particulier (n'hérite pas de View)
- Un Toast affiche un message à l'utilisateur durant une certaine durée (il disparaît automatiquement)
- La méthode statique makeText() permet de créer un Toast
- Le contexte doit être passé en premier paramètre
- Le message à afficher en second paramètre
-
La durée d'affichage du Toast en dernier paramètre
- Toast.LENGTH_SHORT = 2 secondes
- Toast.LENGTH_LONG = 5 secondes
- Il faut utiliser la méthode show() d'un Toast pour l'afficher
- Exemple
Toast toast = Toast.makeText(getApplicationContext(), "Hi!", Toast.LENGTH_LONG);
toast.show();
Exercice 1
Interface login
Résultat
MainActivity

HelloActivity

Consignes
- L'objectif est de réaliser une interface de connexion
- L'application est décomposée en deux écrans
-
Ecran 1
- Affiche un message "Saisir votre identifiant login/password"
- Affiche deux champs pour la saisie de l'identifiant
- Affiche un bouton pour valider l'identifiant
- Lorsque l'utilisateur clique sur le bouton, l'écran 2 est affiché si l'identifiant est admin/admin sinon un Toast affiche un avertissement et les champs sont vidés
-
Ecran 2
- Affiche un message personnalisé avec le login saisi dans l'écran 1
-
Ecran 1
- Utiliser des fichiers XML pour déclarer les interfaces des écrans
- Déclarer les chaînes de caractères (message, hint du champ login, label du bouton) dans le fichier strings.xml
Exercice 2
Morpion
Consignes
- L'objectif est de réaliser un jeu de Morpion
- L'application est décomposée en deux écrans
-
Ecran 1
- Ecran d'accueil affichant un bouton pour démarrer une partie
- Lorsque l'utilisateur clique sur le bouton l'écran 2 s'ouvre
-
Ecran 2
- Affiche une grille 3x3 avec un bouton dans chaque case
- Le texte du bouton est rempli avec un O ou un X lorsqu'un joueur appuie dessus
- Un message Toast indique le joueur qui doit jouer et le gagnant de la partie
-
Ecran 1
- A la fin d'une partie, l'utilisateur est renvoyer à l'écran principal
Interfaces graphiques Android
By Steven Enten
Interfaces graphiques Android
Présentation des interfaces graphiques Android
- 1,570