Dans le chapitre précédent, nous avons vu la théorie. Maintenant, nous allons passer à la pratique en rentrant dans le vif du sujet : nous allons créer notre première application optimisée pour les différentes tailles d'écrans !
Nous allons, à partir d'une application fraîchement créée, aborder point par point les notions essentielles pour créer un design homogène et propre sur l'ensemble des terminaux Android.
L'application de départ est disponible à ce lien. (C'est une simple application vide, même pas de "Hello World").
Création d'une interface basique
Dans cette partie, nous allons créer une interface graphique très simple, contenant une image et un texte, sur un seul écran.
Téléchargez et ouvrez l'application Android disponible à ce lien (si vous ne l'avez pas déjà fait) avec Android Studio puis lancez-la sur un émulateur avec une résolution en xxhdpi (par exemple le Nexus 5).
Mais mais ! Je ne sais pas créer un émulateur sur Android Studio !
Rien de compliqué ! Quand vous exécutez votre application, vous devriez voir cette fenêtre :
Cliquez sur le bouton "Create New Virtual Device" afin de créer un émulateur. Choisissez :
Ecran 1 : Le Nexus 5 (dont la densité est égale à xxhdpi)
Ecran 2 : L'image système, celle que vous souhaitez (je prends généralement les plus basses)
Ecran 3 : Nommez-la comme bon vous semble (pour moi ce sera Nexus_5_API_24_xxhdpi, joli nom non ?)
Votre application devrait maintenant être lancée : Super ! Maintenant, nous allons créer notre interface graphique afin qu'elle ressemble à cela :
Pour cela, nous allons tout d'abord :
1 - Importer une image à notre projet dans le dossier drawable/ que l'on appellera ic_openclassrooms.png (vous pouvez trouver l'image brute ici).
2 - Modifier notre layout activity_main.xml afin de lui ajouter une image ainsi qu'un texte :
<?xml version="1.0" encoding="utf-8"?>
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="com.openclassrooms.toolmybar.MainActivity"
<!-- Block 1 prenant la première moitié de l'écran (propriété layout_weight) -->
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#BED4D6"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OpenClassrooms, c'est vraiment le top du top !"
android:textSize="35sp"
android:padding="40dip"
android:textAlignment="center"
android:textColor="#FFFFFF"
<!-- Block 2 prenant la deuxième moitié de l'écran -->
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:id="@+id/imageView"
android:layout_width="200dip"
android:layout_height="200dip"
android:src="@drawable/ic_openclassrooms"
Lancez maintenant l'application sur l'émulateur Nexus 5 précédemment créé. Sympa le résultat non ?
Et si l'on testait notre application sur un terminal plus petit, le Nexus One par exemple ?
Bonne question Brian ! Je vous laisse donc créer, comme tout à l'heure, un émulateur en choisissant un smartphone Nexus One, et soyons fous, une tablette Nexus 9.
Voyons comme notre application s'affiche !
Oula ! Effectivement c'est pas très joli, surtout sur petit écran. Vous me direz, en mode tablette c'est pas le top non plus...
Et si on s'occupait de rendre notre interface graphique plus sympa et surtout lisser le rendu sur tous ces écrans, en utilisant nos amis les quantificateurs ? Ready ? Let's go !
Adaptation et amélioration de notre interface
Création du fichier dimen.xml
Nous allons tout d'abord créer notre fichier dimen.xml dans notre répertoire values/. Nous allons ensuite y ajouter les précédentes valeurs de taille utilisées dans notre layout activity_main.xml qui serviront de base par défaut.
Ensuite, nous allons remplacer les valeurs de notre layout activity_main.xml (35 sp, 40 dip, 200 dip) par les identifiants de nos tailles nouvellement créées dans dimen.xml. Voici les fichiers à modifier :
Fichier res/values/dimen.xml
<!-- TextViews -->
name="size_title"35sp
name="padding_title"40dip
<!-- Images -->
name="size_image_height"200dip
name="size_image_width"@dimen/size_image_height
Extrait de res/layout/activity_main.xml
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OpenClassrooms, c'est vraiment le top du top !"
android:textSize="@dimen/size_title"
android:padding="@dimen/padding_title"
android:textAlignment="center"
android:textColor="#FFFFFF"
android:id="@+id/imageView"
android:layout_width="@dimen/size_image_width"
android:layout_height="@dimen/size_image_height"
android:src="@drawable/ic_openclassrooms"
Création des dossiers avec quantificateurs
Cette étape ne s'effectue qu'une seule fois, et va nous permettre de gérer les différents petits ajustements visuels au niveau de notre interface graphique. Dans notre cas, nous souhaitons mieux gérer les différentes densités (-mdpi, -hdpi, etc...), l'affichage sur un écran plus large comme une tablette (-large) mais également obtenir un meilleur rendu en orientation paysage (-land). Pfiou !
Pour cela, vous allez créer les dossiers suivants dans votre application Android, et y copier/coller les fichiers correspondants autant de fois que nécessaire, à savoir :
Le fichier dimen.xml dans les dossiers values-XXX/
Le fichier activity_main.xml dans layout-land/
Les images dans drawable-XXX/ (préalablement passées à la moulinette grâce à ce logiciel, pour adapter la densité de votre image)
Edition des fichiers et optimisation
Une bonne chose de faite ! Maintenant, si vous exécutez votre application et testez sur les différents terminaux... rien n'a changé visuellement parlant !
C'est bien normal ! Car vous avez simplement copié/collé le fichier dimen.xml dans les différents dossiers values-XXX/ (ainsi que activity_main.xml dans le dossier layout-land/) sans les modifier. Android reprend donc les mêmes valeurs !
Il faut maintenant affiner nos différentes tailles, dans nos différents fichiers dimen.xml, en fonction du rendu de nos différents émulateurs. Hé bé !
Affiner la densité
Pour affiner notre densité sur l'ensemble des écrans (Nexus One, Nexus 5 & Nexus 9) et adapter ainsi correctement la taille de notre texte et de notre image, nous allons modifier l'ensemble des fichiers dimen.xml avec les valeurs qui nous semblent correctes.
Pas de règles ou de formules mathématiques compliquées pour choisir les tailles que vous allez renseigner dans ces fichiers : testez une valeur, puis lancez votre application sur un terminal correspondant à la densité à tester, et vérifiez que cela s'affiche correctement.
Voici ci-dessus, les ajustements que j'ai effectué à titre personnel dans les différents fichiers dimen.xml, afin de rendre l'interface utilisateur plus agréable à mes yeux. Comme vous pouvez le constater, les valeurs ont tendance à devenir plus importantes en fonction de la densité !
N'hésitez pas à tester d'autres valeurs sur d'autres émulateurs, afin de varier les plaisirs !
Optimiser l'orientation
Ce point étant réglé, nous aimerions maintenant afficher correctement notre application en mode Paysage, pour obtenir le résultat suivant :
Pour cela, nous allons simplement modifier notre fichier res/layout-land/activity_main.xml afin de créer ce design, plutôt sympathique avouons-le !
Ainsi, nous avons simplement besoin de passer la valeur vertical à horizontal pour la propriété "orientation" de notre layout principal :
Puis, nous allons réduire le padding de notre TextView afin qu'il soit plus adapté à un affichage de ce type. A cet effet, nous allons créer une nouvelle valeur dans notre fichier dimen.xml (padding_title_land) :
<!-- TextViews -->
name="size_title"35sp
name="padding_title"40dip
name="padding_title_land"10dip
<!-- Images -->
name="size_image_height"200dip
name="size_image_width"@dimen/size_image_height
Cette nouvelle taille sera paramétrée sur notre TextView dans notre fichier res/layout-land/activity_main.xml dont voici le résultat final :
<?xml version="1.0" encoding="utf-8"?>
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="horizontal"
tools:context="com.openclassrooms.toolmybar.MainActivity"
<!-- Block 1 prenant la première moitié de l'écran (propriété layout_weight) -->
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#BED4D6"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OpenClassrooms, c'est vraiment le top du top !"
android:textSize="@dimen/size_title"
android:padding="@dimen/padding_title_land"
android:textAlignment="center"
android:textColor="#FFFFFF"
<!-- Block 2 prenant la deuxième moitié de l'écran -->
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:id="@+id/imageView"
android:layout_width="@dimen/size_image_width"
android:layout_height="@dimen/size_image_height"
android:src="@drawable/ic_openclassrooms"
Et voilà ! N'hésitez pas à tester l'application en mode Paysage sur les autres terminaux (Nexus One et Nexus 9) afin de vérifier que la nouvelle valeur "padding_title_land " n'a pas besoin d'être redéfinie pour plus de granularité dans les autres fichiers dimen.xml.
Résultat
Plutôt réussi non ? Le rendu de notre affichage est maintenant à la fois agréable sur smartphone ET tablette, ainsi qu'en mode Paysage ET Portrait. N'hésitez à pas vous amuser avec ce projet et gérer encore plus de type de terminaux !
Vous trouverez le code source de l'application à cette adresse.
Conclusion
Maintenant que nous savons gérer l'affichage de notre application sur différents écrans et orientations, nous n'avons plus aucune excuse pour ne plus créer d'interfaces utilisateurs fantastiques !
Dans le prochain chapitre, nous introduirons la barre d'outils ainsi que son implémentation, afin de donner encore plus de possibilités à notre navigation.