Cómo agregar Google Maps a Flutter

La semana pasada, en Flutter Live, mostramos por primera vez la integración de Google Maps en Flutter. El paquete se encuentra disponible como google_maps_flutter en pub.dartlang.org. La API está cambiando para que pueda comunicarse mejor con Flutter, y tendrás más novedades cuando eso esté listo. Mientras tanto, si quieres jugar con Google Maps en Flutter usando la API actual basada en el controlador, aquí tienes un instructivo.
Este artículo muestra paso a paso cómo agregar un widget de Google Maps a tu aplicación de Flutter. Esto es lo que harás hoy:


Configuración

El primer paso es agregar el complemento de Flutter de Google Maps como una dependencia en el archivo pubspec.yaml.

Una vez que hagas eso, deberás ejecutar los paquetes de Flutter.
El siguiente paso es obtener una clave de API. Para ello, ve al sitio web de Google Maps Platform y haz clic en "EMPEZAR". Marca la casilla de verificación de Maps y, luego, haz clic en "Continuar".


Elige un proyecto existente o crea uno nuevo, y completa los pasos restantes en este diálogo para obtener la clave de la API.
A continuación, agrega la clave a tu app de Flutter. Para Android, deberás especificar la clave de la API en el manifiesto de la aplicación (android/app/src/main/AndroidManifest.xml) de la siguiente manera:

En el caso de iOS, especifica la clave de la API en el archivo delegado de la aplicación (ios/Runner/AppDelegate.m):

En iOS, también debes habilitar la previsualización de vistas insertadas, así que agrega una propiedad booleana al archivo Info.plist de la app (ios/Runner/Info.plist) con la clave io.flutter.embedded_views_preview y el valor "true":

Cómo agregar un widget de GoogleMap

Nota: La API de complemento que se describe más abajo es previa a la versión 1.0 y sufrirá modificaciones.
¡Ahora puedes agregar un widget de GoogleMap! Ejecuta flutter clean para asegurarte de que los cambios en la clave de la API se apliquen en la siguiente compilación. Luego, agrega un widget de GoogleMap que cubra toda la pantalla:

Información importante:
  • onMapCreated: Método requerido al que se llama durante la creación del mapa y que toma un elemento MapController como parámetro.
  • mapController: Esencialmente, es el vínculo a todas las interacciones y configuraciones del mapa (al menos en esta iteración de la API) Este patrón es similar a otros controladores disponibles en Flutter, como TextEditingController.
  • options: Almacena la configuración y preferencias del mapa, como cameraPosition, mapType, gestos habilitados o inhabilitados, etc. Consulta el código fuente del complemento para ver una lista de opciones disponibles.
  • cameraPosition: Controla a qué parte del mundo deseas que apunte el mapa.
Si ejecutas la app en este punto, debería verse así:


¿Qué puedes hacer con ella?

Ahora tienes Google Maps en tu app, pero probablemente quieras hacer algo más interesante. ¿Qué opinas sobre poner los widgets de Flutter en la parte superior del mapa, cambiar su apariencia o agregar marcadores de posición? ¡Puedes hacer todo eso!

Cómo agregar un widget en la parte superior del mapa

Es importante recordar que el widget de GoogleMap es solo un widget de Flutter, lo que significa que puedes hacer lo mismo que con cualquier otro widget. Esto incluye colocar otro widget encima de él. Al colocar el widget de GoogleMap dentro de uno de Stack, puedes colocar otros widgets de Flutter encima del widget de mapa:

Cómo cambiar la apariencia del mapa

En este momento, el botón para agregar no realiza ninguna acción interesante. Cambia eso para que cuando se presione, el botón alterne entre dos tipos de mapas diferentes: vista normal y satelital. Como se mencionó anteriormente, para interactuar con el mapa, debes usar el elemento MapController. Agrega un método que use el controlador del mapa para actualizar las opciones:

Ahora reemplaza "() => print(‘button pressed’)" por "_onMapTypeButtonPressed".
child: FloatingActionButton(
  onPressed: _onMapTypeButtonPressed,
  ...),


Cómo agregar un marcador

¿Y si pudieras crear un botón que, cuando lo presiones, agregue marcadores en el mapa? Siguiendo el mismo patrón que antes, agrega un botón a la pila. Coloca otro FloatingActionButton dentro del widget de Align del método de compilación:

Ahora, una vez más, implementa un método que use el MapController para manipular el mapa. En este caso, quieres agregar marcadores de lugar, así que realiza una llamada al elemento addMarker de MapController.

También debes agregar trackCameraPosition: true a GoogleMapOptions en GoogleMapWidget. Esto permite que mapController rastree la posición actual de la cámara del mapa. mapController.cameraPosition.target muestra la posición de LatLng en el centro del widget de GoogleMap. Esta posición se usa en el código anterior para establecer la posición del marcador en el mapa.
GoogleMap(
  ...
  GoogleMapOptions(
    trackCameraPosition: true,
    ...
  ),
),


Puedes personalizar los marcadores con diferentes colores, como BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueViolet), o incluso con íconos personalizados, como BitmapDescriptor.fromAsset(‘assets/asset_name.png).

Código main.dart final


¿Qué más puedes hacer?

Una vez más, el widget de GoogleMap es solo un widget. Esto significa que puedes colocar widgets encima de él (como lo hiciste), dentro de otros widgets (como un ListView, por ejemplo), o si quieres algo de acción, incluso podrías ponerlo en un widget de Transform*.


Hay tantas posibilidades como quieras. Consulta la app de Place Tracker en flutter/samples para obtener una demostración más completa de Google Maps. También puedes ver la app de ejemplo de google_maps_flutter para descubrir cómo usar el complemento.
* Por el momento, no se puede usar widget de Transform para girar el mapa en iOS. Probablemente se habilite en el futuro, pero no es una prioridad actualmente.
También recuerda que este controlador basado en la API no es el final. Se está desarrollando el complemento de google_maps_flutter para que se adapte mejor a Flutter. Actualizaremos este artículo una vez que ese trabajo esté hecho.