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
  • 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
    • Une intention est une instance de la classe Intent
    • Son constructeur prend en paramètre un contexte et la classe de l'activité gérant l'écran à afficher
  • 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
  • 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
  • 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
  • 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