Ludovic ROLAND

Blog technique sur mes expériences de développeur.

Intégrer et utiliser une carte Google dans une application Android (5/7) : Manipulations de base (1/2)

30 juillet 2016

Dans le chapitre précédent, nous avons vu comment afficher une carte Google au sein d’une application Android. Bien que nous ayons vu comment supporter les anciennes version d’Android grâce à l’utilisation de la classe SupportMapFragment. C’est cette version du fragment que nous utiliserons dans le reste de ce tutoriel. Aussi, le layout permettant l’affichage de la carte doit ressembler à ça :

<fragment
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/map"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:name="com.google.android.gms.maps.SupportMapFragment"
/>

Avant d’attaquer la personnalisation et la manipulation de la carte via le langage Java, nous allons nous attarder sur le layout de notre fragment. En effet, nous allons voir qu’il est déjà possible, via le layout XML, de personnaliser certains éléments de la carte Google comme par exemple :

  • le niveau de zoom
  • le type de la carte à afficher
  • la partie de la carte à afficher
  • etc.

Plan

Déclarer un nouvel espace de nom XML

Comme je vous le disais dans l’introduction de ce chapitre, avant de voir comment personnaliser certains éléments de la carte directement via la manipulation du layout XML. Pour cela, nous allons utiliser un nouvel espace de nom XML (ou namespace en anglais) et utiliser des attributs spécifiques.

Pour déclarer un espace de nom, il convient d’ajouter la ligne suivante au niveau de votre layout :

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

Dans le cadre de cet exemple, l’espace de nom s’appelle map, mais ce n’est nullement une obligation. Vous pouvez choisir le nom que vous souhaitez.

Une fois l’espace de nom ajouté au layout, ce dernier devrait ressembler à ça :

<fragment
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:map="http://schemas.android.com/apk/res-auto"
  android:id="@+id/map"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:name="com.google.android.gms.maps.SupportMapFragment"
/>

Choisir le type de la carte

Grâce aux attributs XML de notre layout, nous allons être en mesure de personnaliser le type de carte que nous souhaitons afficher dans notre application. Par défaut, la carte affichée est dite normale, mais nous allons également être en mesure d’afficher d’autres types comme par exemple une carte de type satellite ou terrain.

Pour personnaliser le type de la carte à afficher, il convient d’utiliser l’attribut XML mapType puis de lui attribuer l’une des valeurs suivantes :

  • none pour n’afficher aucune carte (c’est bizarre mais ça peut servir ;))
  • normal pour afficher la carte par défaut.
  • satellite pour afficher une carte de type satellite.
  • terrain pour afficher une carte de type terrain.
  • hybrid pour afficher une carte dite hybride.

Par exemple, si vous choisissez la valeur satellite, votre layout devrait ressembler à ça :

<fragment
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:map="http://schemas.android.com/apk/res-auto"
  android:id="@+id/map"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:name="com.google.android.gms.maps.SupportMapFragment"
  map:mapType="satellite"
/>

Si vous exécutez votre application, vous devriez y découvrir une carte bien différente de la précédente comme en témoigne la capture d’écran suivante :

Je vous laisse le soin de tester les différents types de carte pour découvrir le rendu !

Manipuler la caméra et la position initiale de la carte

Comme vous avez pu le constater via les différentes captures d’écran de ce cours, à chaque fois que l’on lance notre carte, la position initiale est toujours la même. En effet, le niveau de zoom est toujours identique et la carte est toujours centrée au même endroit. Nous allons voir qu’il est possible de personnaliser la position initiale de la carte ainsi que la caméra et ce directement via les attributs XML de notre layout.

Changer la position initiale de la caméra sur la carte

Comme je vous le disais nous allons pouvoir modifier la position initiale de notre carte. Aussi, je vous propose, dans le cadre de ce tutoriel, de centrer la carte sur Paris dont les coordonnées GPS sont d’après internet :

  • Latitude : 48.8534100
  • Longitude : 2.3488000

Via les attributs XML cameraTargetLat et cameraTargetLng, nous allons pouvoir personnaliser la position GPS sur laquelle nous souhaitons centrer la carte. Aussi, si l’on souhaite centrer la carte sur Paris, notre layout doit ressembler à ça :

<fragment
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:map="http://schemas.android.com/apk/res-auto"
  android:id="@+id/map"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:name="com.google.android.gms.maps.SupportMapFragment"
  map:cameraTargetLat="48.8534100"
  map:cameraTargetLng="2.3488000"
/>

Nous pouvons exécuter notre application dès maintenant pour vérifier le bon fonctionnement de notre code :

Comme vous pouvez le constater dans la capture d’écran, à première vue, c’est bien la France qui semble être au centre de la carte. Pour vérifier que c’est bien Paris qui est au centre et non une autre ville, je vous propose de voir immédiatement comment modifier le niveau de de zoom de la carte.

Changer le niveau de zoom

Nous allons donc maintenant voir comment il est possible de modifier le niveau de zoom de la carte. Changer le niveau de zoom va nous permettre d’afficher plus ou moins de détails sur l’endroit qui est centré sur la carte. Aussi, un niveau de zoom de zéro permettra d’afficher l’ensemble de la carte tandis qu’un niveau de zoom plus gros nous permettra de n’afficher, par exemple, qu’une seule rue.

Pour modifier le niveau de zoom de la carte, il convient d’utiliser l’attribut XML cameraZoom. Afin de zoomer suffisament sur Paris, je vous propose de voir le résultat si l’on choisit la valeur 10. Le layout doit alors ressembler à ça :

<fragment
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:map="http://schemas.android.com/apk/res-auto"
  android:id="@+id/map"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:name="com.google.android.gms.maps.SupportMapFragment"
  map:cameraTargetLat="48.8534100"
  map:cameraTargetLng="2.3488000"
  map:cameraZoom="10"
/>

Exécutez l’application pour vérifier que le niveau de zoom a bien changé :

Comme vous pouvez le constater dans la capture d’écran ci-dessus, le niveau de zoom a bien été modifié et Paris semble bien être au centre de la carte.

Changer l’orientation de la carte

Nous n’allons pas nous arrêter là ! Je vous propose maintenant de voir comment il est possible de changer l’orientation de la carte. Pour illustrer l’utilité de cette fonctionnalité, je vous propose de centrer la carte de notre application sur le parc d’attractions La Mer de Sable dont les coordonnées GPS sont les suivantes :

  • Latitude : 49.145135
  • Longitude : 2.675194

Utilisez une carte de type satellite et réglez le zoom sur 16. Après exécution de l’application, voici ce que vous devriez avoir à l’écran :

Jettons maintenant un oeil à la carte officielle du parc disponible sur son site internet :

Que constatez-vous ?

La grande étendue de sable n’est pas du tout au même endroit ! Dans notre application, elle se trouve vers le bas tandis que sur le plan officiel du parc, elle se trouve sur la gauche. Changer l’orientation de la carte de notre application va donc nous permettre de faire pivoter la carte et, dans le cadre de notre exemple, afficher la grande étendue de sable du parc d’attractions au même endroit que dans le plan officiel.

Pour modifier l’orientation de la carte, nous allons utiliser l’attribut XML cameraBearing et lui donner comme valeur un angle en degrés. Afin de placer l’étendue de sable à gauche comme sur le plan officiel du parc, je vous propose de voir le résultat si l’on choisit la valeur 225. Le layout doit alors ressembler à ça :

<fragment
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:map="http://schemas.android.com/apk/res-auto"
  android:id="@+id/map"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:name="com.google.android.gms.maps.SupportMapFragment"
  map:mapType="satellite"
  map:cameraTargetLat="49.145135"
  map:cameraTargetLng="2.675194"
  map:cameraZoom="16"
  map:cameraBearing="225"
/>

Lancez l’application pour vérifier que l’étendue de sable se trouve bien à gauche dorénavant :

Comme vous pouvez le constater, l’étendue de sable se trouve bien à gauche. Vous remarquerez également l’apparition d’une petite boussole en haut à gauche de l’écran permettant d’indiquer à l’utilisateur de votre application que l’orientation de la carte a été changée.

On se rapproche de la carte officielle de La Mer de Sable, mais si l’on y regarde de plus près, on peut encore y voir au moins une différence entre la carte officielle et celle de notre application : l’inclinaison. La carte officielle du parc est vue de côté tandis que celle que nous affichons dans notre application est vue du dessus. Je vous propose donc de voir comment il est possible de changer l’inclinaison de la carte Google affichée au sein de notre application.

Changer l’inclinaison de la carte

Pour modifier l’inclinaison de la carte, il convient d’utiliser l’attribut XML cameraTilt et de lui donner comme valeur un angle en degrés compris entre 0 et 90.

Dans le cadre de notre exemple, je vous propose d’utiliser un angle de 45 degrés. Le layout doit alors ressembler à ça :

<fragment
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:map="http://schemas.android.com/apk/res-auto"
  android:id="@+id/map"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:name="com.google.android.gms.maps.SupportMapFragment"
  map:mapType="satellite"
  map:cameraTargetLat="49.145135"
  map:cameraTargetLng="2.675194"
  map:cameraZoom="16"
  map:cameraBearing="225"
  map:cameraTilt="45"
/>

Exécutez encore une fois l’application pour vérifier que l’inclinaison de la carte a bien été modifiée et que la carte affichée par notre application se rapproche bien du plan officiel du parc :

Personnaliser l’affichage des contrôles

Comme vous avez pu le constater dans les dernières captures, une petite boussole est apparue au niveau de nos cartes. L’affichage de cette petite bousssole ainsi que d’autres contrôles est personnalisable via les attributs XML de notre layout.

Affichage de la boussole

Dans les exemples précédents, la boussole s’est affichée d’elle-même lorsque nous avions modifié l’orientation de la carte. Sachez qu’il s’agit du comportement par défaut. En effet, la boussole s’affiche automatiquement lorsque l’inclinaison ou l’orientation de la carte change. Il est possible de surcharger ce comportement par défaut via l’attribut XML uiCompass. Cet attribut est de type booléen, aussi, il convient de renseigner la valeur true pour conserver le comportement par défaut et false si l’on souhaite cacher la boussole même si l’inclinaison ou l’orientation de la carte sont changées.

Dans le cadre de notre exemple, je vous propose de cacher la boussole malgré la modification de l’orientation de la carte :

Affichage des contrôles de zoom

Actuellement, si les utilisateurs veulent zoomer ou dézoomer sur un point de la carte, la seule possibilité qu’ils ont c’est de connaître et utiliser la gesture dîte de pinch to zoom ou encore en tapant deux fois sur l’écran. Grâce à l’attribut XML uiZoomControls, il est possible d’afficher des contrôles de zoom sur la carte. Ces contrôles se traduisent par :

  • un bouton “+” permettant de zoomer.
  • un bouton “-“ permettant de dézoomer.

Tout comme l’attribut permettant d’afficher la boussole, l’attribut uiZoomControls est de type booléen. Il convient donc de renseigner la valeur true pour afficher les contrôles de zoom et false pour les cacher (il s’agit de la valeur par défaut).

Dans le cadre de notre exemple, nous allons donc forcer l’affichage des contrôles de zoom :

<fragment
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:map="http://schemas.android.com/apk/res-auto"
  android:id="@+id/map"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:name="com.google.android.gms.maps.SupportMapFragment"
  map:uiZoomControls="true"
/>

Comme vous pouvez le constater dans la capture d’écran ci-dessous, deux boutons, permettant de zoomer et dézoomer, sont apparus en bas à droite de l’écran.

Affichage d’une MapToolbar

Depuis peu de temps, à la sélection d’un **marker **, c’est-à-dire une punaise, sur la carte, une MapToolbar s’affiche par défaut proposant deux actions supplémentaires à l’utilisateur :

  • ouvrir la carte dans l’application native Google Maps
  • trouver un itinéraire vers le marker dans l’application native Google Maps

Cette toolbar est désactivable grâce à l’attribut XML uiMapToolbar. Comme pour les précédents attributs XML que nous avons vu dernièrement, il est de type booléen. Il convient donc de renseigner la valeur true pour autoriser l’affichage de la toolbar (il s’agit du comportement par défaut) et false pour ne pas autoriser son affichage.

Dans le cadre de notre exemple, nous allons autoriser son affichage :

<fragment
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:map="http://schemas.android.com/apk/res-auto"
  android:id="@+id/map"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:name="com.google.android.gms.maps.SupportMapFragment"
  map:uiMapToolbar="true"
/>

Dans la capture d’écran ci-dessous, j’ai volontairement affiché un marker sur la carte afin d’afficher la fameuse toolbar pour que vous puissiez voir ce à quoi elle ressemble graphiquement. Vous la trouverez en bas à droite dans la capture d’écran ci-dessous :

Personnaliser les gestures autorisées

Avant de terminer ce chapitre et nous attaquer à la manipulation de la carte via du code Java, il nous reste encore un point à traiter via les attributs XML du layout : les gestures. Les gestures sont l’ensemble des gestes qui permettent via un positionnement précis des doigts sur l’écran du terminal d’effectuer un certain nombre d’actions comme par exemple :

  • zoomer sur la carte
  • dézoomer sur la carte
  • tourner la carte
  • etc.

Nous allons donc voir qu’il est possible de personnaliser l’expérience utilisateur sur un carte en choisissant d’activer ou désactiver certaines de ces gestures.

Les gestures de zoom et dézoom

Comme je vous le disais un peu plus haut, un utilisateur peut utiliser des gestures pour zoomer ou dézoomer sur un endroit précis de la carte. En effet, les utilisateurs ont la possibilité de zoomer en tapant deux fois sur l’écran ou encore via la gesture de pinch to zoom (qui leur permet aussi de dézoomer). Pour rappel, cette gesture consiste à pincer l’écran avec deux doigts. En rapprochant ses doigts l’utilisateur pourra zoomer, tandis qu’en les écartant, l’utilisateur pourra dézoomer.

Il est possible d’activer ou désactiver ces gestures grâce à l’attribut XML uiZoomGestures. Une nouvelle fois, il s’agit d’un attribut qui attend une valeur booléenne. Aussi, la valeur true permet d’activer les gestures de zoom et dézoom (il s’agit du comportement par défaut), tandis que la valeur false permet de les désactiver.

Dans le cadre de notre exemple, nous allons les désactiver :

<fragment
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:map="http://schemas.android.com/apk/res-auto"
  android:id="@+id/map"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:name="com.google.android.gms.maps.SupportMapFragment"
  map:uiZoomGestures="false"
/>

La gesture de déplacement

Je ne l’avais pas précisé, mais je suis sûr que vous l’aviez remarqué : à l’aide d’un doigt il est possible de se déplacer sur la carte. Cette gesture, aussi simple et naturelle qu’elle soit porte un nom. Il s’agit de la gesture de scroll. Comme toutes les gestures que nous allons voir dans ce chapitre, il est possible de l’activer ou la désactiver.

Pour permettre ou non vos utilisateur de se déplacer sur la carte à l’aide d’un doigt, il convient d’utiliser l’attribut XML uiScrollGestures. Une nouvelle fois, cet attribut est de type booléen. La valeur true permet d’activer la gesture (il s’agit de la valeur par défaut) et la valeur false permet de la désactiver.

Dans le cadre de ce tutoriel, je vous propose de désactiver la gesture de scroll :

<fragment
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:map="http://schemas.android.com/apk/res-auto"
  android:id="@+id/map"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:name="com.google.android.gms.maps.SupportMapFragment"
  map:uiScrollGestures="false"
/>

La gesture de rotation

Un peu plus haut dans ce chapitre, nous avions vu qu’il était possible, grâce aux attributs XML, de changer l’orientation de la carte. Sachez que l’utilisateur peut à tout moment lui même changer cette orientation à l’aide d’une gesture particulière. La gesture qui permet une rotation de la carte consiste à poser un doigt sur l’écran, puis à faire tourner un second doigt autour comme un compas.

Une nouvelle fois, il existe un attribut XML permettant d’activer ou non cette gesture. Il s’agit de l’attribut uiRotateGestures. Il s’agit de nouveau d’un attribut de type booléen. Aussi, la valeur true permet d’activer la possibilité de changer l’orientation de la carte (il s’agit de la valeur par défaut) tandis que la valeur false permet de bloquer la carte sur une orientation déterminée.

Voici ce à quoi ressemble le layout dans le cas où la gesture est désactivée :

<fragment
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:map="http://schemas.android.com/apk/res-auto"
  android:id="@+id/map"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:name="com.google.android.gms.maps.SupportMapFragment"
  map:uiRotateGestures="false"
/>

La gesture d’inclinaison

Avant de conclure ce chapitre, il nous reste une dernière gesture à voir : celle permettant de changer l’inclinaison de la carte. Pour pouvoir changer l’inclinaison d’un carte à l’aide de vos doigts, il convient d’en placer deux sur l’écran puis de les déplacer de manière parallèle soit vers le haut de l’écran, soit vers le bas.

Grâce à l’attribut XML uiTiltGestures vous allez être en mesure d’activer ou désactiver cette gesture, vous permettant alors de conserver l’inclinaison de votre carte sur une valeur bien précis. Cet attribut, de type booléen, accepte la valeur true afin de permettre l’activation de la gesture (il s’agit de la valeur par défaut) et la valeur false afin de la désactiver.

Dans le cadre de ce tutoriel, je vous propose de la désactiver :

<fragment
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:map="http://schemas.android.com/apk/res-auto"
  android:id="@+id/map"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:name="com.google.android.gms.maps.SupportMapFragment"
  map:uiTiltGestures="false"
/>

En résumé :

Lorsque l’on déclare une instance de la classe MapFragment au sein d’un layout, les attributs XML associés nous permettent déjà une grande personnalisation de la carte et notamment :

  • le type de la carte
  • la position et le niveau de zoom initial de la carte
  • l’affichage des contrôles
  • l’activation et la désactivation des gestures

Commentaires