• Aucun résultat trouvé

à partir d'une vue préexistante

Obsolescence régionale

Méthode 1 à partir d'une vue préexistante

Le principe ici sera de dériver d'un widget ou d'un layout qui est fourni par le SDK d'Android. Nous l'avons déjà fait par le passé, mais nous n'avions manipulé que le comportement logique de la vue, pas le comportement visuel.

De manière générale, quand on développe une vue, on fait en sorte d'implémenter les trois constructeurs standards. Petit rappel à ce sujet :

Il y a un constructeur qui est utilisé pour instancier la vue depuis le code : Code : Java

View(Context context)

Un pour l'inflation depuis le XML : Code : Java

View(Context context, AttributeSet attrs)

Le paramètre attrs contenant les attributs définis en XML.

Et un dernier pour l'inflation en XML et qu'un style est associé à la vue : Code : Java

View(Context context, AttributeSet attrs, int defStyle)

Le paramètre defStyle contenant une référence à une ressource, ou 0 si aucun style n'a été défini.

De plus, on développe aussi les méthodes qui commencent par on.... Ces méthodes sont des fonctions de callback et elles sont appelées dès qu'une méthode au nom identique (mais sans on...) est utilisée. Je vous ai par exemple parlé de void measure

bonjour.

Vous trouverez une liste intégrale des méthodes que vous pouvez implémenter à cette adresse.

Par exemple, j'ai créé un bouton qui permet de visualiser plusieurs couleurs. Tout d'abord j'ai déclaré une ressource qui contient une liste de couleurs :

Code : XML

<?xml version="1.0" encoding="utf-8"?> <resources>

<array name="colors"> <item>#FF0000</item> <item>#0FF000</item> <item>#000FF0</item> <item>#FFFFFF</item> </array> </resources>

Ce type de ressources s'appelle un TypedArray, c'est-à-dire un tableau qui peut contenir n'importe quelles autres ressources. Une fois ce tableau désérialisé, je peux récupérer les éléments qui le composent avec la méthode appropriée, dans notre cas comme nous manipulons des couleurs, int getColor (int position, int defaultValue) (position étant la position de l'élément voulu et defaultValue la valeur renvoyée si l'élément n'est pas trouvé).

Code : Java import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.Button;

public class ColorButton extends Button { /** Liste des couleurs disponibles **/ private TypedArray mCouleurs = null;

/** Position dans la liste des couleurs **/ private int position = 0;

/**

* Constructeur utilisé pour inflater avec un style */

public ColorButton(Context context, AttributeSet attrs, int

defStyle) {

super(context, attrs, defStyle); init();

} /**

* Constructeur utilisé pour inflater sans un style */

public ColorButton(Context context, AttributeSet attrs) { super(context, attrs);

init(); }

/**

* Constructeur utilisé pour construire dans le code */

public ColorButton(Context context) { super(context);

init(); }

private void init() { // Je récupère mes ressources Resources res = getResources();

// Et dans ces ressources je récupères mon tableau de couleurs mCouleurs = res.obtainTypedArray(R.array.colors);

setText("Changer de couleur"); }

/* ... */ }

Je redéfinis void onLayout (boolean changed, int left, int top, int right, int bottom) pour qu'à chaque fois que la vue est redimensionnée, je puisse changer la taille du carré qui affiche les couleurs de manière à ce qu'il soit toujours conforme au reste du bouton.

Code : Java

/** Rectangle qui délimite le dessin */ private Rect mRect = null;

@Override

protected void onLayout (boolean changed, int left, int top, int

right, int bottom) {

//Si le layout a changé if(changed)

//On redessine un nouveau carré en fonction des nouvelles dimensions

mRect = new Rect(Math.round(0.5f * getWidth() - 50), Math.round(0.75f * getHeight() - 50),

Math.round(0.5f * getWidth() + 50), Math.round(0.75f * getHeight() + 50)); //Ne pas oublier

super.onLayout(changed, left, top, right, bottom); }

J'implémente boolean onTouchEvent (MotionEvent event) pour qu'à chaque fois que l'utilisateur appuie sur le bouton, la couleur qu'affiche le carré change. Le problème est que cet évènement se lance à chaque toucher, et qu'un toucher ne correspond pas forcément à un clic mais aussi à n'importe quelle fois où je bouge mon doigt sur le bouton, ne serait-ce que d'un pixel. Ainsi, la couleur change constamment si vous avez le malheur de bouger le doigt quand vous restez appuyé sur le bouton. C'est pourquoi j'ai rajouté une condition pour que le dessin ne réagisse que quand on appuie sur le bouton, pas quand on bouge ou qu'on lève le doigt. Pour cela, j'ai utilisé la méthode int getAction () de MotionEvent. Si la valeur retournée est MotionEvent.ACTION_DOWN, c'est que l'évènement qui a déclenché le lancement de la méthode est un clic.

Code : Java

/** Outil pour peindre */

// Uniquement si on appuie sur le bouton

if(event.getAction() == MotionEvent.ACTION_DOWN) { // On passe à la couleur suivante

position ++;

// Évite de dépasser la taille du tableau

// (dès qu'on arrive à la longueur du tableau, on repasse à 0)

position %= mCouleurs.length();

// Change la couleur du pinceau

mPainter.setColor(mCouleurs.getColor(position, -1)); // Redessine la vue invalidate(); } // Ne pas oublier return super.onTouchEvent(event); }

Enfin, j'écris ma propre version de void onDraw(Canvas canvas) pour dessiner le carré dans sa couleur actuelle. L'objet Canvas correspond à la fois à la toile sur laquelle dessiner et à l'outil qui permet de dessiner, alors qu'un objet Paint indique juste au Canvas comment il faut dessiner, mais pas ce qu'il faut dessiner.

Code : Java

@Override

protected void onDraw(Canvas canvas) {

// Dessine le rectangle à l'endroit voulu avec la couleur voulue

canvas.drawRect(mRect, mPainter); // Ne pas oublier

super.onDraw(canvas); }

Vous remarquerez qu'à la fin de chaque méthode de type on..., je fais appel à l'équivalent de la super classe de cette méthode. C'est tout simplement parce que les supers classes effectuent des actions pour la classe Button qui doivent être faites sous peine que le bouton ne se comporte pas correctement.

On a un petit carré en bas de notre bouton, puis dès qu'on appuie sur le bouton, le carré change de couleur :

Documents relatifs