Android : Créer un composant personnalisé

Bloc-notes de développeurs - Android

Bloc-notes de développeurs - Android

Voilà un moment que je n’ai pas publié d’article. J’étais en période d’auto-formation sur le framework Android. Je fais mes tests sur une application que je publie de temps en temps sur l’Android Market, il s’agit de l’application de ce blog. Et oui, elle existe et elle est disponible à tout le monde ^^.

J’ai fait d’une pierre deux coups : je montais en compétence sur Android et je créais cette application. Maintenant je vais pouvoir vous faire partager ces quelques semaines de labeur. Vous pouvez dès à présent trouver l’application en recherchant « Olivier PEREZ » sur l’Android market.

Description du composant

Composant presonnalisé : NumberPicker

Composant presonnalisé : NumberPicker

Le composant (ou la vue) que je vous propose de créer aujourd’hui permettra à l’utilisateur de choisir un nombre entier en cliquant sur des boutons « plus » et « moins » (comme pour choisir une heure ou une date).

J’ai commencé par chercher ce composant dans les composants natifs d’Android et en effet j’ai trouvé, dans différents articles sur internet, une solution pour l’utiliser. Cette unique solution apparaissait dans tous les sites, mais elle était assez moche et plus que douteuse. Après avoir fini de l’installer j’ai testé sur le simulateur et tout allait bien…

Seulement voilà, une fois déployé sur mon téléphone, tout marchait SAUF ce composant. J’ai donc décidé de me renseigner pour coder moi même ce tout petit composant.

Ce petit tutoriel se découpe en 3 petites étapes : le layout (la mise en forme), le java (le fonctionnement) et nous finirons en installant notre magnifique composant dans une application.

Layout

NumberPicker - Layout

NumberPicker - Layout

Nous allons créer notre composant comme le montre la hiérarchie ci-contre. Commençons par créer un fichier nommé number_picker.xml dans le dossier layout.

Tout d’abord, le layout principal : RelativeLayout.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
 
<!-- Le contenu -->
 
</RelativeLayout>

Nous allons ensuite utiliser la puissance du RelativeLayout qui permet de positionner les éléments les uns par rapport aux autres ou tout simplement par rapport à leur parent.

Le bouton + sera naturellement positionné en haut du layout, nous collerons ensuite le bouton – en bas du layout puis nous insérerons le champs texte entre les deux boutons.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content">
 
	<Button android:id="@+id/edal_plus_button"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:text="+"
		style="@style/EDAL.NumberPickerText"/>
 
	<Button android:id="@+id/edal_minus_button"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:text="-"
		android:layout_alignParentBottom="true"
		style="@style/EDAL.NumberPickerText"/>
 
	<EditText android:id="@+id/edal_int_field"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:text="0"
		android:layout_above="@id/edal_minus_button"
		android:layout_below="@id/edal_plus_button"
		android:gravity="center"
		android:inputType="number"
		style="@style/EDAL.NumberPickerText"/>
 
</RelativeLayout>

Une bonne habitude à prendre avec les ID est de les préfixer. Dans ce cas j’ai mis edal_, c’est le nom de la librairie personnelle que je développe en même temps. Ça permet d’éviter de mélanger les ID quand une utilise une librairie.

Java

Notre composant est visuellement prêt. Il ne nous reste qu’à coder pour le faire fonctionner et le rendre utilisable.

Créons une classe qui portera le nom de notre composant. Je vous propose donc NumberPicker, rien de révolutionnaire. Elle aura besoin de 5 attributs :

  • private final static String TAG = NumberPicker.class.getName(); // Pour le log
  • private Button plusButton; // Bouton plus
  • private Button minusButton; // Bouton moins
  • private EditText editValue; // Champs texte
  • private int value = 0; // Valeur courante du composant

Deux méthodes publiques seront aussi nécessaires à l’utilisation :

  • public void setValue(int value)
  • public int getValue()

Pas besoin de les présenter, elles parlent d’elles-mêmes.

Ensuite, toute l’initialisation se fait dans le constructeur. C’est à dire la définition des actions que le composant effectuera à la suite d’un clic sur un des deux boutons.

J’utilise ci-dessous le terme inflate. Il est souvent utilisé lorsqu’on parle d’interfaces graphiques sous Android, il décrit l’action de créer visuellement le composant.

Le constructeur se chargera aussi de faire l’inflate du composant.

LayoutInflater.from(context).inflate(R.layout.number_picker, this, true);

Ensuite on affecte les composants à nos attributs.

plusButton = (Button)findViewById(R.id.edal_plus_button);
minusButton = (Button)findViewById(R.id.edal_minus_button);
editValue = (EditText)findViewById(R.id.edal_int_field);

Et pour finir on défini quelles sont les actions sur les deux boutons.

plusButton.setOnClickListener(new OnClickListener() {
	@Override
	public void onClick(View v) {
		value++;
		editValue.setText(value + "");
	}
});
 
minusButton.setOnClickListener(new OnClickListener() {
	@Override
	public void onClick(View v) {
		value--;
		editValue.setText(value + "");
	}
});

Utilisation du composant

Notre composant est maintenant prêt, il ne nous reste qu’à l’utiliser dans notre application. Pour cela nous allons l’insérer avec quelques lignes de code.

Dans un futur article je vous présenterai comme utiliser ce composant dans vos fichiers XML.

J’utilise ci-dessous le terme « activity » il s’agit de la classe contrôleur d’un écran.

Commencez par vérifier que vous aillez donné un ID au layout principal de votre activity.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent"
	android:id="@+id/main_frame">
 
<!-- ... -->
 
</RelativeLayout>

Allons ensuite dans notre activity et ajoutons deux petites lignes dans la méthode onCreate(Bundle savedInstanceState).

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.main);
 
	RelativeLayout rl = (RelativeLayout)findViewById(R.id.main_frame);
	rl.addView(new NumberPicker(this, 0));
 
	/*...*/
}

Et voilà, le tour est joué.

Et l’avenir ?

J’ai déjà en tête deux idées d’articles, assez proches de celui-ci, qui pourraient vous intéresser.

Il s’agit de :

  • l’utilisation de notre composant directement dans les fichiers XML
  • la création d’un composant perso en le dessinant (cercles, carrés, trais, images, etc.)

Si vous avez une préférence pour un des deux dites-le moi, je commencerai par celui de votre choix.

Tagués avec : , , , , , ,
Publié dans Android
7 commentaires pour “Android : Créer un composant personnalisé
  1. Kévin dit :

    Moi j’aurais une petite préférence pour le composant perso en le dessinant!!
    Sinon merci pour le tuto très bien réalisé.

  2. Olivier PEREZ dit :

    Bonjour Kévin,
    En effet la création de composants en les dessinant est une autre possibilité. J’espère pouvoir trouver un peu de temps dans les semaines à venir pour rédiger un petit article la dessus.

  3. cyril dit :

    Bonjour,

    je serais également intéressé par la création de composant en les dessinant.

    Merci pour ce partage de connaissance.

  4. mav3656 dit :

    Merci pour ce tuto. Dommage qu’il n’y ait pas l’instanciation via XML. Bonne continuation

  5. Olivier PEREZ dit :

    Merci bien, j’aimerai bien trouver un peu de temps pour rédiger un article là dessus mais je doit vous avouer que je n’ai pas beaucoup de temps pour le moment. Mais promis vous y aurez droit un jour ou l’autre.

  6. SOL4RIS dit :

    Merci pour ce tuto. Mais j’ai une question : La classe que tu crées (NumberPicker) doit obligatoirement hériter de la classe View, non?
    Car la fonction statique findViewById() n’est definie que pour une classe héritant de View…

  7. Olivier PEREZ dit :

    En effet, si tu veux créer un composant graphique tu doit hériter de View, mais tu n’est pas obligé d’hériter directement de cette classe. Tu peux également hériter d’une de ses sous-classes, RelativeLayout dans notre exemple.

    Sur cette page tu peux trouver toutes les classes qui héritent (directement ou indirectement) de View ici : http://developer.android.com/reference/android/view/View.html

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*