• Aucun résultat trouvé

La construction par inflation

J'exploite les deux constructeurs destinés à l'inflation pour pouvoir récupérer les attributs que j'ai pu passer en attributs. En effet, il m'est possible de définir mes propres attributs pour ma vue. Pour cela, il me faut créer des ressources de type attr dans un tableau d'attributs. Ce tableau est un nœud de type declare-styleable. J'attribue un nom à chaque élément qui leur servira d'identifiant. Enfin, je peux dire pour chaque attr quel type d'informations il contiendra.

Code : XML <resources>

<declare-styleable name="ChessBoardView">

<!-- L'attribut d'identifiant "colorOne" est de type "color" -->

<attr name="colorTwo" format="color"/> </declare-styleable>

</resources>

Pour utiliser ces attributs dans le layout, il faut tout d'abord déclarer utiliser un namespace, comme on le fait pour pouvoir utiliser les attributs qui appartiennent à Android :

xmlns:android="http://schemas.android.com/apk/res/android" .

Cette déclaration nous permet d'utiliser les attributs qui commencent par android: dans notre layout, elle nous permettra donc d'utiliser nos propres attributs de la même manière.

Pour cela, on va se contenter d'agir d'une manière similaire en remplaçant xmlns:android par le nom voulu de notre

namespace et http://schemas.android.com/apk/res/android par notre package actuel. Dans mon cas, j'obtiens : Code : Console

xmlns:sdzName="http://schemas.android.com/apk/res/sdz.chapitreDeux.chessBoard"

Ce qui me donne ce XML : Code : XML

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

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:sdzName="http://schemas.android.com/apk/res/sdz.chapitreDeux.chessBoard" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <sdz.chapitreDeux.chessBoard.ChessBoardView android:layout_width="fill_parent" android:layout_height="fill_parent" sdzName:colorOne="#FF0000" sdzName:colorTwo="#00FF00" /> </LinearLayout>

Il me suffit maintenant de récupérer les attributs comme nous l'avions fait précédemment : Code : Java

// attrs est le paramètre qui contient les attributs de notre objet en XML

public ChessBoardView(Context context, AttributeSet attrs, int

defStyle) {

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

}

// idem

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

init(attrs); }

R.styleable.ChessBoardView);

// Il s'agit d'un TypedArray qu'on sait déjà utiliser, je récupère la valeur de la couleur 1 ou "-1" si on la trouve pas int tmpOne = attr.getColor(R.styleable.ChessBoardView_colorOne, -1);

// Je récupère la valeur de la couleur 2 ou "-1" si on la trouve pas

int tmpTwo = attr.getColor(R.styleable.ChessBoardView_colorTwo, -1);

init(tmpOne, tmpTwo); }

onMeasure

La taille par défaut de 100 pixels est ridicule et ne conviendra jamais à un échiquier. Je vais faire en sorte que si l'application me l'autorise, je puisse exploiter le carré le plus grand possible, et je vais faire en sorte qu'au pire, notre vue prenne au moins la moitié de l'écran.

Pour cela, j'ai écrit une méthode qui calcule la dimension la plus grande entre la taille que me demande de prendre le layout et la taille qui correspond à la moitié de l'écran. Puis je compare en largeur et en hauteur quelle est la plus petite taille accordée, et mon échiquier s'accorde à cette taille.

Il existe plusieurs méthodes pour calculer la taille de l'écran. De mon côté, j'ai fait en sorte de l'intercepter depuis les ressources avec la méthode DisplayMetrics getDisplayMetrics (). Je récupère ensuite l'attribut heightPixels pour avoir la hauteur de l'écran et widthPixels pour sa largeur.

Code : Java /**

* Calcule la bonne mesure sur un axe uniquement * @param spec - Mesure sur un axe

* @param screenDim - Dimension de l'écran sur cet axe * @return la bonne taille sur cet axe

*/

private int singleMeasure(int spec, int screenDim) { int mode = MeasureSpec.getMode(spec);

int size = MeasureSpec.getSize(spec);

// Si la layout n'a pas précisé de dimensions, la vue prendra la moitié de l'écran

if(mode == MeasureSpec.UNSPECIFIED) return screenDim/2;

else

// Sinon, elle prendra la taille demandée par le layout return size;

}

@Override

protected void onMeasure (int widthMeasureSpec, int

heightMeasureSpec) {

// On récupère les dimensions de l'écran DisplayMetrics metrics =

getContext().getResources().getDisplayMetrics(); // Sa largeur...

int screenWidth = metrics.widthPixels; // ... et sa hauteur

int screenHeight = metrics.heightPixels;

int retourWidth = singleMeasure(widthMeasureSpec, screenWidth); int retourHeight = singleMeasure(heightMeasureSpec,

screenHeight);

// Comme on veut un carré, on aura qu'une taille pour les deux axes, la plus petite possible

int retour = Math.min(retourWidth, retourHeight);

setMeasuredDimension(retour, retour); }

Toujours avoir dans son implémentation de onMeasure un appel à la méthode void setMeasuredDimension

(int measuredWidth, int measuredHeight), sinon votre vue vous enverra une exception.

onDraw

Il ne reste plus qu'à dessiner notre échiquier ! Ce n'est pas grave si vous ne comprenez pas l'algorithme, du moment que vous avez compris toutes les étapes qui me permettent d'afficher cet échiquier tant voulu.

Code : Java

@Override

protected void onDraw(Canvas canvas) { // Largeur de la vue

int width = getWidth(); // Hauteur de la vue int height = getHeight();

int step = 0, min = 0;

// La taille minimale entre la largeur et la hauteur min = Math.min(width, height);

// Comme on ne veut que 8 cases par lignes et 8 lignes, on divise la taille par 8

step = min / 8;

// Détermine quand on doit changer la couleur entre deux cases boolean switchColor = true;

for(int i = 0 ; i < min ; i += step) { for(int j = 0 ; j < min ; j += step) { if(switchColor)

canvas.drawRect(i, j, i + step, j + step, mPaintTwo); else

canvas.drawRect(i, j, i + step, j + step, mPaintOne); // On change de couleur entre chaque ligne... switchColor = !switchColor;

}

// ...et entre chaque case switchColor = !switchColor; }

}

Partie 3 : Annexes

L'architecture d'Android

Après quelques réflexions et quelques recherches, je me suis dit que c'était peut-être une bonne idée de présenter aux plus curieux l'architecture d'Android. Vous pouvez considérer ce chapitre comme facultatif s'il vous ennuie ou vous semble trop compliqué, vous serez tout de même capable de développer correctement sous Android mais un peu de culture technique ne peut pas vous faire de mal .

Concrètement, l'architecture d'Android, c'est ça :

Schéma qui provient de la page suivante, provenant du site d'Android destiné aux développeurs.

En soi, ce schéma est incompréhensible et franchement pas glamour, mais il résume de manière concrète ce que je vais vous raconter. Ce que vous observez est une pile des composants qui constituent le système d'exploitation. Le sens de lecture se fait de bas en haut, puisque le composant de plus bas niveau est le noyau Linux et celui de plus haut niveau sont les applications.

Documents relatifs