Les conteneurs
Pour afficher des éléments à l'écran et les organiser entre eux, il est impératif d'utiliser un conteneur.
Dans le fichier XML de mon layout fragment_welcome, le premier élément que nous voyons est du type FrameLayout
. Cet élément est un conteneur. Android suffixe toujours le nom des conteneurs par Layout.
Parmi les conteneurs proposés par Android, nous pouvons noter par exemple :
FrameLayout
: permet de positionner les éléments les uns au-dessus des autres ;LinearLayout
: permet de positionner les éléments les uns à la suite des autres, dans le sens horizontal ou vertical ;ConstraintLayout
: permet de positionner les éléments les uns par rapport aux autres en utilisant des règles de positionnement ;RelativeLayout
: c’est l’ancêtre de ConstraintLayout, il permet également de positionner les éléments les uns par rapport aux autres.
Pour concevoir l’écran d’accueil de notre application tel que sur la maquette suivante, remplacez la balise XML FrameLayout
par LinearLayout
. Pour que l’agencement des éléments se fasse de manière verticale, il faut ajouter l’attribut android:orientation="vertical"
. Vous devez obtenir le résultat suivant :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".WelcomeFragment">
<TextView
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_blank_fragment" />
</LinearLayout>
Les attributs
Occupation de l'espace
Les deux attributs d’une balise XML fondamentaux sont layout_width
et layout_height
. Ils définissent comment afficher un élément au sein de son conteneur. Les quatres valeurs possibles sont :
match_parent
: l'élément doit occuper tout l’espace disponible offert par son parent (vous pourriez voir apparaître de temps en tempsfill_parent
au détour d'un tutoriel ou d'un site web : c'est un attribut obsolète, ancêtre dematch_parent
) ;wrap_content
: l'élément doit n'occuper que la place nécessaire à l'affichage de son contenu ;0dp
: la taille de l’élément est définie par ses contraintes avec un conteneur de typeConstraintLayout
;la valeur brute en dp, même s’il est plutôt recommandé d’utiliser les trois options précédentes pour un rendu plus “responsive”.
Gravitation
La notion de gravitation peut s'appliquer à un élément ou à son contenu. Elle permet de déterminer comment positionner un élément par rapport à son conteneur, ou comment positionner les enfants d'un élément.
Pour définir unitairement le positionnement d'un élément au sein de son layout parent, c'est l'attributandroid:layout_gravity
qu'il faut utiliser. Les valeurs possibles sont nombreuses : start
, end
, center
, center_vertical
, center_horizontal
, etc.
Pour définir globalement le positionnement des éléments enfants d’un conteneur, c'est l'attributandroid:gravity
qu'il faut utiliser. Les valeurs possibles sont identiques à l'attribut layout_gravity
.
Texte
Pour définir du texte, nous allons utiliser l’attribut android:text
. Nous pouvons y saisir des textes bruts directement, comme par exemple android:text=”Hello”
, ou utiliser des chaînes de caractères internationalisées. Celles-ci doivent être spécifiées dans un fichier strings.xml
présent dans le répertoire res/values/
. Pour le moment, notre projet ne comporte qu’une seule langue, et donc il y a un seul fichier strings.xml
. Voici le contenu de ce fichier dans mon projet :
<resources>
<string name="app_name">SuperQuiz</string>
<string name="hello_blank_fragment">Hello blank fragment</string>
</resources>
Ainsi, dans le code du layout XML, au sein du composant TextView
, pour utiliser la chaîne de caractères nomméehello_blank_fragment
, il suffit d’écrire android:text="@string/hello_blank_fragment"
.
L'élément TextView
possède également d’autres propriétés. Nous utiliserons les propriétés suivantes dans ce cours :
android:textSize
: pour changer la taille du texte. L’unité attendue est de typesp
, qui signifie scale-independant pixels. Cette unité se base sur la densité de pixels de l’appareil, mais prend aussi en compte la taille de la police définie dans les réglages de l’appareil. Cela permet à l’interface d’afficher le texte en plus en moins gros selon ce réglage, et donc de rendre votre application plus accessible ;android:textStyle
: pour mettre le texte en gras ou en italique (soit respectivement la valeurbold
ouitalic
) ;android:background
: pour changer sa couleur de fond.
Marge
Pour décoller un élément légèrement du bord, nous pouvons utiliser l'attribut android:layout_margin
, permettant de préciser une grandeur de marge.
Si vous ne souhaitez modifier qu'une seule marge, vous pouvez utiliser les attributs suivants : layout_marginTop
, layout_marginBottom
, layout_marginStart
ou layout_marginEnd
.
Padding
Le padding consiste à ajouter de l'espace entre le contenu d'un élément et les bords de cet élément.
Amusez-vous à ajouter une marge et un padding à l'élément TextView
de votre projet, et à modifier le texte, afin d’obtenir le résultat illustré ci-dessous.
Voici le code de l’élément TextView
que vous avez dû écrire :
<TextView
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Codez comme vous êtes !"
android:layout_margin="60dp"
android:padding="30dp"
android:background="#d2c2fd"/>```
Voilà, vous en savez suffisamment sur la mise en page des éléments et sur l'élément TextView
, pour pouvoir (enfin !) dessiner la partie supérieure du premier écran de notre application SuperQuiz.
À vous de jouer
Vous allez maintenant développer la partie supérieure du layout correspondant au fragment WelcomeFragment
. Concrètement, vous allez ajouter les deux premiers textes de cet écran et les agencer correctement au sein d’un LinearLayout
.
Essayez de reproduire seul la maquette ci-dessous au sein du fichier fragment_welcome.xml
. Concernant la taille des textes et l’espacement entre les éléments, vous pouvez utiliser les valeurs qui vous semblent les plus homogènes.
Alors, vous avez réussi ? Si vous avez besoin d’un peu d’aide, voici les attributs clés à utiliser pour obtenir un affichage équivalent à notre maquette :
Allez, c’est parti pour la correction. Au final, le code de votre layout fragment_welcome.xml
devrait correspondre à ça :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.main.WelcomeFragment"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Welcome to SuperQuiz"
android:textSize="24sp"
android:layout_margin="24dp"/>
<TextView
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="What's your name"
android:textSize="20sp"
android:layout_margin="24dp"/>
</LinearLayout>
Ajoutez les éléments de contrôle
Nous allons maintenant ajouter les deux derniers éléments présents sur l’écran d’accueil de notre application, soit un champ de saisie et un bouton.
Champ de saisie
Pour que l'utilisateur puisse taper son nom, il faut lui présenter un élément lui permettant de saisir du texte. Sous Android, c'est l'élément EditText
qui porte ce rôle. Pour ce faire, toujours dans le fichier fragment_welcome.xml
, ajoutez un élément EditText
.
Dès que vous commencez à saisir le chevron et les premières lettres, Android Studio vous propose automatiquement tous les choix possibles. Dès que vous voyez apparaître EditText
, sélectionnez-le et appuyez sur la touche Entrée ou la touche de tabulation.
Android Studio vous ajoute ensuite automatiquement les attributs layout_width
et layout_height
. Il vous positionne également le curseur sur la première valeur.
Commencez à saisir les premières lettres de match_parent
et complétez automatiquement en appuyant sur Entrée ou Tabulation. Passez à la ligne layout_height
automatiquement avec Tabulation ou Entrée , et mettez cette fois wrap_content
comme valeur. Enfin, appuyez sur Entrée ou Tabulation pour “sortir” des guillemets, et fermez l’élément XML avec la touche / . Android Studio s’occupe de rajouter le chevron manquant, c'est magique !
Tout comme pour le champ texte, nous pouvons ajouter une marge afin d'éviter que la zone de saisie ne soit trop proche des bords, par exemple à gauche et à droite. Par exemple, une marge de 16 dp.
Il est également possible d'ajouter un indice à l'aide de l'attribut android:hint
. Cet indice apparaît dans le champ texte pour apporter une information à l'utilisateur, puis disparaît dès qu'il commence à saisir du texte.
Vous devez obtenir le résultat suivant (seul l'élément EditText
est présenté dans cet extrait de code) :
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:minHeight="48dp"
android:hint="Please type your name"/>
Bouton
Maintenant que l'utilisateur s'est présenté, il n'a plus qu'à appuyer sur un bouton pour commencer à jouer. L'élément XML à utiliser est Button
.
Comme pour l'élément TextView
, l'attribut à utiliser pour spécifier le titre est android:text
. Nous décidons de nommer le bouton "Let's play" . Vous pouvez modifier la marge ou le padding pour positionner le bouton comme bon vous semble. Pour ma part, j'ai décidé de lui affecter un padding horizontal de 24 dp, pour que le bouton soit plus large, et de l’espacer de ses voisins avec une marge de 16 dp. Voici le résultat :
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:paddingHorizontal="24dp"
android:textSize="14sp"
android:text="Let's play" />
Récapitulons en vidéo
Retrouvez ces différentes étapes dans la vidéo ci-dessous :
En résumé
Une activité ou un fragment utilise un fichier layout pour pouvoir positionner ses éléments graphiques à l’écran.
Il y a plusieurs types de layouts permettant d’agencer différemment les éléments graphiques d’un écran : de manière relative aux autres éléments, de manière horizontale, de manière verticale ou en superposition.
Pour bien affiner la position et l’espace occupé par des éléments à l’écran, il faut utiliser les différents attributs disponibles, par exemple
margin
,padding
,layout_gravity
, etc.
Voilà, l'interface graphique est prête. Rendez-vous dans le prochain chapitre pour référencer les éléments graphiques dans le code Java de votre fragment, qui vous permettra ensuite de dynamiser l’application.