Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 37 di 37
  • livello intermedio
Indice lezioni

Gestione delle mappe

Usando la libreria geolocator su un'app mobile realizzata con Flutter, vediamo come migliorare la UX integrando le mappe di Google.
Usando la libreria geolocator su un'app mobile realizzata con Flutter, vediamo come migliorare la UX integrando le mappe di Google.
Link copiato negli appunti

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 Completer di tipo GoogleMapController che permette di definire un controller per ogni istanza di GoogleMap in esecuzione sul dispositivo;
  • un oggetto LatLng rappresentate il Colosseo;
  • la posizione iniziale della mappa da mostrare all’utente sfruttando la classe CameraPosition che 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à initialCameraPosition a cui abbiamo impostato l’oggetto colosseo che rappresenta la posizione desiderata per la camera;
  • la onMapCreated in cui abbiamo associato all’oggetto _controller la nuova istanza di GoogleMapController ottenuta con l’inizializzazione del widget GoogleMap.

Eseguiamo l’applicazione per ottenere il seguente risultato.

Figura 180. Visualizzazione delle mappe di Google su a) Android b) iOS (click per ingrandire)Visualizzazione delle mappe di Google su a) Android b) iOS

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.

Figura 181. Esempio di creazione di una Polyline e di un Marker su a) Android b) iOS (click per ingrandire)Esempio di creazione di una Polyline e di un Marker su a) Android b) iOS

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.

Figura 182. Visualizzazione della posizione corrente dell’utente su a) Android b) iOS (click per ingrandire)Visualizzazione della posizione corrente dell’utente su a) Android b) iOS

Come possiamo vedere dalle immagini, la posizione dell’utente sarà rappresentata dal pallino blu.

Ti consigliamo anche