Développement Android : Layouts prédéfinis et structure d'une interface
Layouts prédéfinis
Les layouts prédéfinis dans Android permettent de structurer une interface en utilisant différentes organisations des vues. Voici les principaux types :
- Positions relatives
- Lignes ou colonnes
- Tableaux et « Grid »
- Autres layouts plus ou moins utilisés
Structure d'une interface Android de type formulaire
Un écran Android de type formulaire est généralement composé de plusieurs vues, notamment :
- TextView, ImageView (pour afficher un titre ou une image)
- EditText (pour saisir du texte)
- Button, CheckBox (pour des boutons cliquables ou des cases à cocher)
Ces vues sont alignées à l'aide de groupes sous-classes de type ViewGroup, éventuellement imbriqués :
- LinearLayout : positionne ses vues en ligne ou en colonne
- RelativeLayout : positionne ses vues les unes par rapport aux autres
- TableLayout : positionne ses vues sous forme d'un tableau
Composants UI (Interface Utilisateur)
Les éléments d'interface (UI) sont construits à partir d'objets View et ViewGroup.
- View : un élément visuel (zone de texte, bouton, etc.)
- ViewGroup : un conteneur qui organise d'autres vues
La hiérarchie des composants UI se présente sous forme d'un arbre, où un ViewGroup peut contenir d'autres ViewGroup ou des View.
Représentation en XML
La structure d'un layout est décrite en XML. Voici un exemple de base :
<?xml version="1.0" encoding="utf-8"?>
<android.widget.LinearLayout
android:id="@+id/groupe1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/titre" />
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/Name" />
<LinearLayout
android:id="@+id/groupe2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="40dp"
android:orientation="horizontal">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/valider" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/RAZ" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/annuler" />
</LinearLayout>
</android.widget.LinearLayout>
Paramètres généraux des vues
Toutes les vues doivent spécifier deux attributs essentiels :
- android:layout_width : définit la largeur de la vue
- android:layout_height : définit la hauteur de la vue
Ces attributs peuvent prendre les valeurs suivantes :
- "wrap_content" : la vue s'adapte à son contenu
- "match_parent" : la vue prend toute la place disponible (à partir d'Android 2.2 et API ≥ 8)
- "valeur" : une taille fixe en dp, px, mm, in, etc.
Note : Dans les versions antérieures à Android 2.2 (API < 8), utilisez fill_parent au lieu de match_parent.
Unités de mesure recommandées
Google recommande l'utilisation des unités suivantes :
- dp (density-independent pixel) : pour les dimensions des vues
- sp (scale-independent pixel) : pour les tailles de police
D'autres unités existent :
- px : pixel
- in : pouce
- mm : millimètre
Le dp est une unité de taille indépendante de la densité de l'écran. Par exemple, 100 dp correspondent à 100 pixels sur un écran de 100 dpi et à 200 pixels sur un écran de 200 dpi, mais apparaissent de la même taille.
Bonnes pratiques pour les layouts
Voici quelques recommandations pour optimiser vos interfaces :
- Séparer l'UI (XML) et la logique (Java)
- Utiliser des unités dp ou sp plutôt que des pixels pour une meilleure adaptabilité
- Privilégier une hiérarchie peu profonde pour améliorer les performances
- Éviter les arbres de layouts trop profonds, car cela augmente le temps de calcul pour le rendu
Propriétés des layouts
Les layouts disposent de plusieurs propriétés pour personnaliser l'affichage des widgets :
- Orientation : définie l'organisation des widgets en ligne ou en colonne
- Modèle de remplissage : permet de gérer comment l'espace est réparti entre les widgets
- Poids (layout_weight) : indique la proportion d'espace allouée à chaque widget
- Gravité (layout_gravity) : contrôle l'alignement des widgets dans le layout
- Remplissage (padding) : ajoute de l'espace autour des widgets pour améliorer leur lisibilité
Exemples d'utilisation des layouts
FrameLayout
FrameLayout est le plus simple des conteneurs. Tous les éléments sont placés les uns au-dessus des autres à partir du coin haut-gauche. Le dernier élément ajouté vient recouvrir les autres.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<RadioButton
android:id="@+id/radioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|center_vertical"
android:text="RadioButton" />
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left|center"
android:text="Button4" />
<Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Button5" />
</FrameLayout>
LinearLayout
LinearLayout organise ses composants en ligne ou en colonne selon l'attribut android:orientation.
Exemple en orientation verticale :
<LinearLayout
android:id="@+id/groupe1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="48dp"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:text="@string/titre" />
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:text="@string/Name" />
</LinearLayout>
Exemple en orientation horizontale :
<LinearLayout
android:id="@+id/groupe2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="40dp"
android:orientation="horizontal">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/valider" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/RAZ" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/annuler" />
</LinearLayout>
RelativeLayout
RelativeLayout permet de positionner chaque vue par rapport à une autre vue ou au layout parent. Voici quelques attributs courants :
- layout_alignParentTop : aligne le haut du widget avec celui du parent
- layout_alignCenterVertical : centre verticalement le widget par rapport au parent
- layout_toRightOf : place le widget à droite d'une autre vue
- layout_below : place le widget sous une autre vue
- layout_alignLeft : aligne le bord gauche du widget avec celui d'une autre vue
- layout_alignTop : aligne le bord supérieur du widget avec celui d'une autre vue
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="16dp"
android:paddingRight="16dp">
<EditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/reminder" />
<Spinner
android:id="@+id/dates"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/name"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="@+id/times" />
<Spinner
android:id="@+id/times"
android:layout_width="96dp"
android:layout_height="wrap_content"
android:layout_below="@+id/name"
android:layout_alignParentRight="true" />
<Button
android:layout_width="96dp"
android:layout_height="wrap_content"
android:layout_below="@+id/times"
android:layout_alignParentRight="true"
android:text="@string/done" />
</RelativeLayout>
TableLayout
TableLayout est dérivé de LinearLayout et permet d'organiser les vues sous forme de tableau. Il utilise les éléments TableLayout et TableRow.
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent" />
</TableLayout>
GridLayout
GridLayout est similaire à TableLayout mais plus simple, car il n'est pas nécessaire de spécifier toutes les cellules. Il est plus performant.
L'attribut columnCount permet de définir le nombre de colonnes. Pour spécifier une cellule, utilisez :
- layout_column
- layout_row
- layout_rowSpan
- layout_columnSpan
Note : layout_weight n'est pas utilisé par GridLayout.
TextView : composant de base pour afficher du texte
TextView est le composant le plus simple pour afficher un texte statique, comme un titre.
- Son contenu est défini par l'attribut android:text.
- Il est possible de modifier dynamiquement son texte via le code Java.
<TextView
android:id="@+id/tvtitre"
android:text="@string/titre" />
TextView tvTitre = (TextView) findViewById(R.id.tvtitre);
tvTitre.setText("blablabla");
Principales propriétés de TextView :
- autoLink : convertit les liens HTTP et adresses e-mail en liens cliquables
- ellipsize : règle l'affichage du texte si celui-ci dépasse la zone de visualisation
- height, width, maxHeight, maxWidth : dimensions du composant
- lines, minLines, maxLines : nombre de lignes affichées
- text : texte à afficher
- textColor, textSize, textStyle : caractéristiques du texte
- gravity : positionne le texte dans le conteneur si la zone d'affichage est plus petite
- drawableTop, drawableBottom, drawableLeft, drawableRight : permet d'ajouter des images autour du texte
FAQ : Questions fréquentes sur les layouts Android
1. Pourquoi utiliser des unités dp plutôt que px pour les layouts ?
Les unités dp (density-independent pixel) permettent d'adapter les dimensions des vues à différentes densités d'écran, garantissant ainsi une apparence cohérente sur tous les appareils Android. Contrairement aux pixels (px), qui sont fixes et peuvent rendre une interface illisible ou disproportionnée sur certains écrans.
2. Quels sont les avantages et inconvénients de RelativeLayout ?
Avantages :
- Permet un positionnement précis des vues par rapport à d'autres vues ou au layout parent.
- Réduit le besoin de ViewGroup imbriqués.
- Améliore les performances en évitant des hiérarchies trop profondes.
Inconvénients :
- Plus complexe à utiliser et à maintenir.
- Peut devenir difficile à lire avec un grand nombre de vues.
- Nécessite une bonne compréhension des attributs de positionnement.
3. Comment optimiser la performance d'un layout complexe ?
Pour optimiser un layout complexe, privilégiez :
- Un arbre de hiérarchie peu profond : utilisez des layouts comme RelativeLayout ou LinearLayout avec des attributs de positionnement plutôt que des imbrications multiples.
- Les unités dp et sp pour éviter les recalculs inutiles liés aux pixels.
- Le GridLayout pour les grilles, car il est plus performant que TableLayout.
- La suppression des vues inutiles ou redondantes.