Chapitre 3
GESTION DES EVENEMENTS
 
 
Précédent Suivant
 

Gestion des événements
Exercice: "Paint"
Disposition des vues
* Préparer deux zones
* Haut: barre d'outils
* Bas: espace où dessiner
* Zone de dessin
* Type: FrameLayout
* Identifiant: "scene"
* Barre d'outils
* Type: LinearLayout (horizontal)
* Ajouter des boutons
* Une classe représentant le dessin sera développée
* Classe "Dessin" qui hérite de "FrameLayout"
* Un objet de cette classe sera ajouté dans la vue "scene"
Dessiner sur une vue (1/2)
* Deux objets sont nécessaires pour tracer sur une vue
* Pinceau: "outil" de dessin (objet de la classe "Paint")
* A créer, possibilité d'en avoir plusieurs
* Paint pinceau = new Paint();
* Style de tracé
* Forme pleine: pinceau.setStyle(Paint.Style.FILL);
* Contour uniquement: pinceau.setStyle(Paint.Style.STROKE);
* Couleur du tracé: pinceau.setColor(0xFF00FF00);
* Code ARGB: Aliasing + Rouge + Vert + Bleu
* Epaisseur du trait: pinceau.setStrokeWidth(4);
* Toile: "réceptable" du dessin (objet de la classe "Canvas")
* Elle est fournie automatiquement par le système
* Utiliser un pinceau pour tracer
* Ligne: toile.drawLine(x1,y1,x2,y2,pinceau);
* Rectangle: toile.drawRect(x1,y1,x2,y2,pinceau);
Dessiner sur une vue (2/2)
* On n'appelle jamais directement le code qui dessine
* Appel automatique du système à la méthode "onDraw" de la vue
* Uniquement quand le rafraîchissement du dessin est nécessaire
* La toile est alors fournie à cette méthode
* Placer le code du dessin dans la méthode "onDraw" de la vue
protected void onDraw(Canvas toile) {
super.onDraw(toile);
// Tracé du dessin
}
* Indiquer au système qu'il doit appeler votre code
* Dans le constructeur: setWillNotDraw(false);
* Possibilité de demander le rafraîchissement de la vue
* A tout moment, en appelant sa méthode "invalidate"
Classe "Dessin" (1/2)
* Héritage d'une classe de vues existante
public class Dessin extends FrameLayout {
private Paint pinceau_; // Attribut
public Dessin(Context contexte) { [...] }
protected void onDraw(Canvas toile) { [...] }
}
* Constructeur
* Une vue est construite à partir d'un contexte
* public Dessin(Context contexte) {
super(contexte);
// Initialisation de la vue
}
Classe "Dessin" (2/2)
* Initialisation de la vue
* Couleur de fond
* setBackgroundColor(0xFFEEEEEE);
* Dimensions (par exemple, adaptation au parent)
* setLayoutParams(new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
* Forcer l'appel à "onDraw"
* setWillNotDraw(false);
* Au démarrage de l'activité
* Récupérer la zone de dessin (identifiant "scene")
* FrameLayout scene = findViewById(R.id.scene);
* Créer un objet dessin
* Dessin dessin = new Dessin(this);
* Ajouter le dessin dans la zone
* scene.addView(dessin);
Mécanisme des écouteurs
* Possibilité de surveiller de nombreux événements sur une vue
* Les événements sont organisés par type
* OnClick: détection "clic" (appui + relâchement) avec le doigt
* OnTouch: détection appui, relâchement, déplacement du doigt
* ...
* Surveillance d'un type d'événement sur une vue ==> écouteur
* Ecouteur = objet alerté quand l'événement se produit sur la vue
* Exemple: vue.setOnTouchListener(ecouteur);
* Au démarrage de l'activité
* Créer un objet écouteur (dont la classe devra être développée)
* Ecouteur ecouteur = new Ecouteur();
* Associer l'écouteur aux événements sur la vue "dessin"
* dessin.setOnTouchListener(ecouteur);
Classe "Ecouteur" (1/2)
* Héritage de l'interface correspondant au type d'événement
* Interface ~ classe sans implémentation
* public class Ecouteur implements OnTouchListener {
public boolean onTouch(View vue,
MotionEvent evnt) { [...] }
}
* Lorsqu'un événement "OnTouch" se produit
==> appel de la méthode "onTouch" de l'écouteur
* C'est de cette manière que l'écouteur est informé
* Il reçoit la vue qui a subi l'événement (ici, notre dessin)
* Au besoin, il faut la convertir
* Dessin dessin = (Dessin)vue;
* Et un objet contenant des renseignements sur l'événement: evnt
Classe "Ecouteur" (2/2)
* Redéfinition de la méthode "onTouch"
public boolean onTouch(View vue,MotionEvent evnt) {
int action = evnt.getAction(); // Type d'action du doigt
int x = (int)evnt.getX(); // Position X du doigt
int y = (int)evnt.getY(); // Position Y du doigt
if (action == MotionEvent.ACTION_DOWN)
System.out.println("Doigt posé au point " + x + ";" + y);
else if (action == MotionEvent.ACTION_UP)
System.out.println("Doigt levé au point " + x + ";" + y);
else if (action == MotionEvent.ACTION_MOVE)
System.out.println("Doigt déplacé au point " + x + ";" + y);
return true; // Indique que l'événement a été traité
}
Classe "Courbe" (1/2)
* Courbe = liste de points
* Classe "Point" existe
* Utilisation du conteneur "ArrayList"
* Equivalent à un tableau dont la taille s'adapte automatiquement
* ArrayList<Point> = liste de points
* Classe "Courbe" agrège une liste de points
public class Courbe {
private ArrayList<Point> points_;
public Courbe() { [...] }
public void ajouter(Point point) { points_.add(point); }
public void dessiner(Paint pinceau,Canvas toile) { [...] }
}
Classe "Courbe" (2/2)
* Dessiner la courbe
public void dessiner(Paint pinceau,Canvas toile) {
// Réglage du pinceau
for (int i = 1; i < points_.size(); ++i) {
int x1 = points_.get(i-1).x; int x2 = points_.get(i).x;
int y1 = points_.get(i-1).y; int y2 = points_.get(i).y;
// Tracé d'une ligne (x1;y1) ? (x2;y2) sur la toile
}
}
* Dans la classe "Dessin"
* Mémoriser la liste des courbes ==> attribut "courbes_"
* Méthode pour ajouter une courbe dans la liste ==> void ajouter(Courbe courbe)
* Méthode "onDraw" à modifier pour qu'elle affiche les courbes mémorisées
* Faire un test en créant des courbes dans le constructeur
Création interactive d'une courbe
* Dans la classe "Ecouteur"
* Doigt posé ==> nouvelle courbe (position = 1er point)
* Doigt en mouvement ==> ajout point dans la courbe
* Doigt levé ==> courbe terminée
* Mémoriser la courbe en cours de tracé
* Attribut "courbe_", initialisé à "null" dans le constructeur
* Modifier la méthode "OnTouch"
if (action == MotionEvent.ACTION_DOWN)
{ /* Nouvelle courbe (ajouter à la liste) */ }
else if (action == MotionEvent.ACTION_UP)
{ /* Courbe terminée */ }
else if (action == MotionEvent.ACTION_MOVE)
{ /* Ajout point dans la courbe */ }
dessin.invalidate(); // Demande rafraîchissement
Classe "Ligne"
public class Ligne {
private Point origine_;
private Point destination_;
public void setOrigine(Point point) { [...] }
public void setDestination(Point point) { [...] }
public Ligne(Point origine,Point destination) { [...] }
public void dessiner(Paint pinceau,Canvas toile) {
// Réglage du pinceau
// Tracé de la ligne
}
}
Affichage des lignes
* Dans la classe "Dessin"...
* Mémoriser la liste des lignes ==> attribut "lignes_"
* Mémoriser la ligne en cours de tracé
* Attribut "ligneCourante_"
* Initialisé à "null" dans le constructeur
* Méthode pour ajouter une ligne dans la liste
* void ajouter(Ligne ligne)
* Méthode pour définir la ligne en cours de tracé
* void setLigneCourante(Ligne ligne)
* Compléter la méthode d'affichage "onDraw"
* Pour les lignes fixées, tracé d'une certaine couleur
* Pour la ligne en cours (si elle existe), tracé d'une autre couleur
Création interactive d'une ligne
* Dans la classe "Ecouteur"
* Doigt posé ==> nouvelle ligne courante (position = origine de la ligne)
* Doigt en mouvement ==> modification destination de la ligne
* Doigt levé ==> ligne fixée
* Mémoriser la ligne en cours de tracé
* Attribut "ligne_", initialisé à "null" dans le constructeur
* Modifier la méthode "OnTouch"
if (action == MotionEvent.ACTION_DOWN)
{ /* Nouvelle ligne courante */ }
else if (action == MotionEvent.ACTION_UP)
{ /* Ligne fixée (ajouter à la liste) */ }
else if (action == MotionEvent.ACTION_MOVE)
{ /* Modification destination de la ligne */ }
dessin.invalidate(); // Demande rafraîchissement
Gestion des outils
* Dans la classe "Ecouteur"
* Mémoriser le choix de l'outil ==> attribut "outil_"
* Exemple: 1 = courbe, 2 = ligne...
* Méthode pour changer d'outil: void setOutil(int outil)
* Modifier la méthode "onTouch"
* Afin d'effectuer le travail correspondant à l'outil sélectionné
* Dans la classe de l'activité
* L'objet écouteur devient un attribut de la classe
* Afin d'être accessible à partir d'autres méthodes
* Créer une méthode (déclenchée par un bouton) pour activer chaque outil
* void selectionnerCourbe(View vue)
* void selectionnerLigne(View vue)
* ...
* Associer chaque méthode au clic du bouton correspondant
* Attribut "onClick"