Nella scorsa lezione, abbiamo visto come integrare la localizzazione dell’utente attraverso la libreria geolocator.
In questa, vedremo come utilizzare le mappe di Google per rendere l’esperienza utente ancora più immersiva.
Esempio pratico
Come sempre, creiamo un nuovo progetto come descritto nella lezione 6 e procediamo con una semplice applicazione per vedere come:
- integrare le mappe di Google nella nostra app;
- aggiungere un marker;
- mostrare la posizione corrente dell’utente.
La struttura del nostro progetto sarà quindi la seguente
lib/
│── screens/
│ │── screen1
│ │ │── screen1.dart
│── theme/
│ │── style.dart
│── routes.dart
Diversamente dalle ultime lezioni, in questo esempio ci basterà lavorare all’interno di una singola schermata per estrapolare l’informazione di interesse. La definizione dello style e delle routes è disponibile sul repository GitHub menzionato nella lezione precedente.
Installazione del plugin google_maps_flutter
Apriamo il file pubspec.yaml e inseriamo sotto la voce dependencies il nome del plugin di interesse come segue
dependencies:
# . . .
google_maps_flutter: ^0.5.27+1
Eseguiamo dal nostro terminale il comando:
flutter pub get
per installare il plugin.
Definizione dei permessi e della API Key
Per permettere alla nostra applicazione di utilizzare le mappe è necessario:
- essere in possesso di un API Key per l’utilizzo delle mappe su Android e su iOS;
- impostare i permessi per iOS e Android.
Per ottenere la API Key e abilitare il servizio di Google Maps è necessario:
- andare sulla Google Developers Console;
- creare o scegliere il progetto su cui si desidera abilitare Google Maps;
- selezionare il menu di navigazione e quindi selezionare la voce Google Maps nella sezione Altre Soluzioni Google;
- nel menù a tendina che compare selezionare la voce API;
- per abilitare Google Maps per Android, selezionare Maps SDK per Android nella sezione API aggiuntive, quindi selezionare ENABLE;
- per abilitare Google Maps per iOS, selezionare Maps SDK per iOS nella sezione API aggiuntive, quindi selezionare ENABLE.
A questo punto se abbiamo seguito correttamente tutti i passi, troveremo le nostre API nella nella sezione API abilitate e non ci resta che abilitare le credenziali.
Spostiamoci nella sezione Api e servizi e clicchiamo sulla voce Credenziali.
Nella nuova sezione, clicchiamo sulla voce CREA CREDENZIALI per ottenere in pochi istanti una nuova chiave da utilizzare nella nostra app.
Ai fini di questa lezione non è necessario applicare alcun tipo di restrizione per impedirne l’uso, ma è caldamente consigliato farlo per i rilasci delle applicazioni in produzione.
Integriamo la nostra API Key nel progetto.
Per iOS è necessario aggiungere nel file ios/Runner/AppDelegate.swift l’import a GoogleMaps e nel corpo di Bool le nostre API key come segue.
import GoogleMaps
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GMSServices.provideAPIKey("YOUR KEY HERE")
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
Successivamente, aggiungiamo nel file ios/Runner/Info.plist quanto segue.
<key>io.flutter.embedded_views_preview</key>
<string>YES</string>
Per Android, apriamo il file android/app/src/main/AndroidManifest.xml e aggiungiamo all’interno del tag <application>
<meta-data android:name="com.google.android.geo.API_KEY"
android:value="YOUR API KEY"/>
Sia per Android che per iOS, andiamo a sostituire la stringa YOUR API KEY con la chiave ottenuta dalla Google Developer Console.
Oltre a questi permessi, aggiungiamo anche quelli inerenti alla localizzazione, come indicato nella lezione precedente, per mostrare la posizione corrente dell’utente sulla mappa.
Aggiungere la mappa
Partiamo con il primo aspetto: integrare le mappe nella nostra app.
Apriamo il file screen1.dart e creiamo la classe Stateful Screen1 come segue.
class Screen1 extends StatefulWidget {
@override
State<Screen1> createState() => Screen1State();
}
class Screen1State extends State<Screen1> {
@override
Widget build(BuildContext context) {
return //...
}
}
Ora che abbiamo definito lo stato del nostro widget possiamo definire:
- un oggetto
Completerdi tipoGoogleMapControllerche permette di definire un controller per ogni istanza diGoogleMapin esecuzione sul dispositivo; - un oggetto
LatLngrappresentate il Colosseo; - la posizione iniziale della mappa da mostrare all’utente sfruttando la classe
CameraPositionche permette di definire un punto geografico (LatLng) e un livello di zoom; - la mappa utilizzando il widget
GoogleMap.
Per farlo, ci basteranno poche e semplici righe di codice. Vediamo un esempio di implementazione del nostro Screen1State.
class Screen1State extends State<Screen1> {
Completer<GoogleMapController> _controller = Completer();
static final LatLng colosseoLatLng = LatLng(41.890251, 12.492373);
static final CameraPosition colosseo = CameraPosition(
target: LatLng(41.890251, 12.492373),
zoom: 16.5,
);
@override
Widget build(BuildContext context) {
return new Scaffold(
body: GoogleMap(
mapType: MapType.normal,
initialCameraPosition: colosseo,
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);
},
),
);
}
}
Possiamo vedere che per il widget GoogleMap abbiamo impostato:
- il tipo di mappa da utilizzare tramite la proprietà
mapType; - la proprietà
initialCameraPositiona cui abbiamo impostato l’oggettocolosseoche rappresenta la posizione desiderata per la camera; - la
onMapCreatedin cui abbiamo associato all’oggetto_controllerla nuova istanza diGoogleMapControllerottenuta con l’inizializzazione del widgetGoogleMap.
Eseguiamo l’applicazione per ottenere il seguente risultato.
Aggiungiamo adesso:
- un marker per indicare il punto esatto in cui si trova il Colosseo, fornendo per quel marker un titolo e uno snippet;
- un percorso breve identificato da un linea verde che rappresenta i fori imperiali.
Per farlo, basterà utilizzare le classi Marker e Polyline, rispettivamente.
Vediamo come con un semplice esempio.
static final Marker colosseoMarker = Marker(
markerId: MarkerId(colosseoLatLng.toString()),
position: colosseoLatLng,
infoWindow: InfoWindow(
title: 'Colosseo',
snippet: 'Roma, Italy',
),
icon: BitmapDescriptor.defaultMarker,
);
static final Polyline foriImperiali = Polyline(
polylineId: PolylineId(colosseoLatLng.toString()),
visible: true,
width: 7,
color: Colors.green,
points: [
LatLng(41.891456, 12.490189),
LatLng(41.891436, 12.490261),
LatLng(41.891348, 12.490476),
LatLng(41.891300, 12.490733),
LatLng(41.891260, 12.490911)
],
);
A questo punto, modifichiamo il widget GoogleMap per aggiungere le proprietà polylines e markers che ci permetteranno di impostare la Polyline e il Marker definiti.
Widget build(BuildContext context) {
return new Scaffold(
body: GoogleMap(
// . . .
polylines: <Polyline>{foriImperiali},
markers: <Marker>{colosseoMarker},
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);
},
),
);
}
In questo caso, avendo una sola Polyline e un solo Marker creati in modo statico e sempre fruibili non abbiamo gestito il relativo stato tramite il metodo setState(). In un'applicazione reale è importante non dimenticarsene.
Eseguiamo quindi la nostra applicazione ottenendo il risultato seguente.

Infine, non resta che la parte più facile. Mostrare la posizione dell’utente sulla mappa. Il metodo più semplice che non coinvolge l’utilizzo del plugin geolocator è quello di impostare a true le proprietà myLocationButtonEnabled e myLocationEnabled del widget GoogleMap.
Il widget GoogleMap sarà quindi il seguente.
Widget build(BuildContext context) {
return new Scaffold(
body: GoogleMap(
// . . .
myLocationButtonEnabled: true,
myLocationEnabled: true,
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);
},
),
);
}
Eseguiamo l’applicazione per vedere i risultati delle nostre modifiche.

Come possiamo vedere dalle immagini, la posizione dell’utente sarà rappresentata dal pallino blu.
Se vuoi aggiornamenti su Mobile inserisci la tua email nel box qui sotto:
