tutoriales.com

Flutter: Integrando Mapas Interactivos con Google Maps y Geolocalización en tu App

Descubre cómo añadir mapas interactivos a tus aplicaciones Flutter utilizando el paquete `google_maps_flutter`. Este tutorial te guiará desde la configuración inicial hasta la visualización de la ubicación del usuario, la adición de marcadores personalizados y el dibujo de rutas, mejorando significativamente la funcionalidad de geolocalización de tus apps.

Intermedio25 min de lectura7 views
Reportar error

🗺️ Introducción a Mapas Interactivos en Flutter

En la era de las aplicaciones móviles, la integración de mapas y funcionalidades de geolocalización se ha vuelto casi indispensable para una gran variedad de casos de uso. Desde aplicaciones de viajes y navegación, hasta servicios de entrega o redes sociales basadas en la ubicación, la capacidad de mostrar información geográfica de manera interactiva es un activo valioso.

Flutter, el popular toolkit de UI de Google, ofrece una manera eficiente y flexible de integrar mapas en tus aplicaciones. En este tutorial, nos enfocaremos en utilizar el paquete oficial google_maps_flutter para incorporar Google Maps, y geolocator para obtener la ubicación del usuario. Exploraremos cómo configurar estas herramientas, mostrar la ubicación actual, añadir marcadores personalizados y dibujar polilíneas para representar rutas.

Este tutorial está diseñado para desarrolladores de Flutter que tengan conocimientos básicos del framework y estén listos para llevar sus aplicaciones al siguiente nivel con capacidades de mapas y localización.

💡 Consejo: Asegúrate de tener una conexión a internet estable durante el desarrollo y las pruebas, ya que los mapas y la geolocalización dependen en gran medida de los servicios en línea.

🚀 Configuración Inicial: Requisitos y API Key

Antes de sumergirnos en el código, necesitamos configurar nuestro entorno y obtener una clave de API de Google Maps.

🔑 Obtención de la Clave de API de Google Maps

Para usar Google Maps en tu aplicación, necesitarás una clave de API de Google Cloud Platform. Sigue estos pasos:

  1. Visita Google Cloud Console: Dirígete a Google Cloud Console.
  2. Crea un Proyecto: Si no tienes uno, crea un nuevo proyecto.
  3. Habilita APIs: En el menú de navegación, ve a 'APIs y Servicios' > 'Biblioteca'. Busca y habilita las siguientes APIs:
    • Maps SDK for Android
    • Maps SDK for iOS
    • Places API (Opcional, pero útil para autocompletado de direcciones)
    • Directions API (Opcional, para calcular rutas).
  4. Crea Credenciales: Ve a 'APIs y Servicios' > 'Credenciales'. Haz clic en 'Crear credenciales' y selecciona 'Clave de API'.
  5. Restringe la Clave (Recomendado): Una vez generada la clave, haz clic en 'Restringir clave'. Selecciona 'Aplicaciones Android' y 'Aplicaciones iOS' y añade los nombres de tus paquetes y IDs de bundle correspondientes. Además, restringe la clave a las APIs que habilitaste en el paso 3. Esto es crucial por seguridad.
⚠️ Advertencia: NUNCA expongas tu clave de API directamente en tu código fuente o control de versiones público sin restricciones de seguridad. Las restricciones de API y aplicación son vitales.

📦 Añadir Dependencias al pubspec.yaml

Abre tu archivo pubspec.yaml y añade las siguientes dependencias:

dependencies:
  flutter:
    sdk: flutter
  google_maps_flutter: ^2.5.3 # Asegúrate de usar la última versión
  geolocator: ^11.0.0 # Para obtener la ubicación actual
  permission_handler: ^11.3.1 # Para gestionar permisos de ubicación
  flutter_polyline_points: ^2.0.0 # Para decodificar polilíneas de la API de Directions
  http: ^1.2.1 # Para realizar solicitudes HTTP a la API de Directions

Después de añadir las dependencias, ejecuta flutter pub get en tu terminal para descargarlas.

⚙️ Configuración Específica por Plataforma

Android

  1. Actualizar android/app/src/main/AndroidManifest.xml: Dentro de la etiqueta <application>, añade la clave de API:
<meta-data android:name="com.google.android.geo.API_KEY" android:value="TU_API_KEY_AQUI"/>
Asegúrate de reemplazar `TU_API_KEY_AQUI` con tu clave real. También añade los permisos necesarios:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
  1. Actualizar android/app/build.gradle: Asegúrate de que minSdkVersion sea al menos 20. Si tu proyecto es nuevo, probablemente ya lo sea:
android {
defaultConfig {
minSdkVersion 20
// ... otros settings
}
}

iOS

  1. Actualizar ios/Runner/AppDelegate.swift o AppDelegate.m: Para Swift:
import UIKit
import Flutter
import GoogleMaps // Importar GoogleMaps

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GMSServices.provideAPIKey("TU_API_KEY_AQUI") // Añade tu clave aquí
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
Para Objective-C:

```objective-c
#import "AppDelegate.h"
#import "GeneratedPluginRegistrant.h"
#import <GoogleMaps/GoogleMaps.h> // Importar GoogleMaps

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GMSServices provideAPIKey:@"TU_API_KEY_AQUI"]; // Añade tu clave aquí
  [GeneratedPluginRegistrant registerWithRegistry:self];
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

@end

2.  **Actualizar `ios/Runner/Info.plist`:**
Añade las siguientes claves para los permisos de ubicación:

```xml
    <key>NSLocationWhenInUseUsageDescription</key>
    <string>Esta aplicación necesita acceso a tu ubicación para mostrarla en el mapa.</string>
    <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
    <string>Esta aplicación necesita acceso a tu ubicación para mostrarla en el mapa, incluso en segundo plano.</string>
    ```

    <div class="callout note">📌 <strong>Nota:</strong> Para iOS 14+, si deseas un permiso de ubicación más preciso, considera añadir `NSLocationTemporaryUsageDescriptionDictionary` si tu aplicación tiene un uso temporal de alta precisión.</div>

---

## 📍 Solicitud de Permisos y Obtención de la Ubicación Actual

Antes de poder acceder a la ubicación del usuario, debemos solicitar los permisos adecuados. Utilizaremos el paquete `permission_handler` para esto.

### 📝 Función para Solicitar Permisos

Crea un nuevo archivo, por ejemplo, `location_service.dart`, para encapsular la lógica de ubicación.

```dart
import 'package:geolocator/geolocator.dart';
import 'package:permission_handler/permission_handler.dart';

class LocationService {
  static Future<Position?> getCurrentLocation() async {
    // Solicitar permisos de ubicación
    PermissionStatus permissionStatus = await Permission.locationWhenInUse.request();

    if (permissionStatus.isGranted) {
      // Permiso concedido, verificar si los servicios de ubicación están habilitados
      bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
      if (!serviceEnabled) {
        // Los servicios de ubicación no están habilitados. Pídele al usuario que los habilite.
        print('Servicios de ubicación deshabilitados.');
        // Opcional: Abre la configuración para que el usuario habilite la ubicación
        // await Geolocator.openLocationSettings();
        return null;
      }
      
      // Obtener la posición actual
      try {
        Position position = await Geolocator.getCurrentPosition(
          desiredAccuracy: LocationAccuracy.high,
          timeLimit: Duration(seconds: 10),
        );
        print('Ubicación obtenida: ${position.latitude}, ${position.longitude}');
        return position;
      } catch (e) {
        print('Error al obtener la ubicación: $e');
        return null;
      }
    } else if (permissionStatus.isDenied) {
      // Permiso denegado por el usuario. Pídele que lo habilite en la configuración.
      print('Permiso de ubicación denegado.');
      // Opcional: Abre la configuración de la aplicación para que el usuario habilite el permiso
      // await openAppSettings();
      return null;
    } else if (permissionStatus.isPermanentlyDenied) {
      // Permiso denegado permanentemente. Guía al usuario a la configuración.
      print('Permiso de ubicación denegado permanentemente. Abre la configuración.');
      await openAppSettings(); // Abre la configuración de la app para que el usuario pueda cambiarlo
      return null;
    } else {
      // Otros estados de permiso (restricted, limited, etc.)
      print('Estado de permiso desconocido: $permissionStatus');
      return null;
    }
  }
}

💻 Uso en un Widget

Puedes llamar a LocationService.getCurrentLocation() en el initState de tu widget de mapa o en respuesta a un botón.

// ... dentro de un StatefulWidget para el mapa

class MapScreen extends StatefulWidget {
  const MapScreen({super.key});

  @override
  State<MapScreen> createState() => _MapScreenState();
}

class _MapScreenState extends State<MapScreen> {
  Position? _currentPosition;

  @override
  void initState() {
    super.initState();
    _getLocation();
  }

  Future<void> _getLocation() async {
    Position? position = await LocationService.getCurrentLocation();
    if (position != null) {
      setState(() {
        _currentPosition = position;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Mapa Interactivo')),
      body: _currentPosition == null
          ? const Center(child: CircularProgressIndicator())
          : Text('Lat: ${_currentPosition!.latitude}, Lng: ${_currentPosition!.longitude}'), // Placeholder
    );
  }
}

🗺️ Visualización del Mapa y Ubicación Actual

Ahora que podemos obtener la ubicación, vamos a mostrarla en un GoogleMap widget.

🏗️ Construyendo el Widget de Mapa

Modifica el build método de _MapScreenState para mostrar el mapa.

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:geolocator/geolocator.dart';
import 'location_service.dart'; // Asegúrate de importar tu servicio de ubicación

class MapScreen extends StatefulWidget {
  const MapScreen({super.key});

  @override
  State<MapScreen> createState() => _MapScreenState();
}

class _MapScreenState extends State<MapScreen> {
  GoogleMapController? mapController;
  Position? _currentPosition;
  final Set<Marker> _markers = {}; // Para almacenar los marcadores en el mapa

  @override
  void initState() {
    super.initState();
    _getLocationAndSetupMap();
  }

  Future<void> _getLocationAndSetupMap() async {
    Position? position = await LocationService.getCurrentLocation();
    if (position != null) {
      setState(() {
        _currentPosition = position;
        _markers.add(
          Marker(
            markerId: const MarkerId('currentLocation'),
            position: LatLng(position.latitude, position.longitude),
            infoWindow: const InfoWindow(title: 'Tu Ubicación Actual'),
            icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueBlue),
          ),
        );
      });
      // Mover la cámara a la ubicación actual si el controlador está disponible
      mapController?.animateCamera(
        CameraUpdate.newCameraPosition(
          CameraPosition(
            target: LatLng(position.latitude, position.longitude),
            zoom: 15.0,
          ),
        ),
      );
    }
  }

  void _onMapCreated(GoogleMapController controller) {
    mapController = controller;
    // Si la ubicación ya está disponible, animar la cámara al crear el mapa
    if (_currentPosition != null) {
      mapController?.animateCamera(
        CameraUpdate.newCameraPosition(
          CameraPosition(
            target: LatLng(_currentPosition!.latitude, _currentPosition!.longitude),
            zoom: 15.0,
          ),
        ),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Mapa Interactivo')),
      body: _currentPosition == null
          ? const Center(child: CircularProgressIndicator())
          : GoogleMap(
              onMapCreated: _onMapCreated,
              initialCameraPosition: CameraPosition(
                target: LatLng(_currentPosition!.latitude, _currentPosition!.longitude), // Usar ubicación actual si disponible
                zoom: 15.0,
              ),
              markers: _markers, // Añadir los marcadores al mapa
              myLocationEnabled: true, // Muestra el punto azul de la ubicación del usuario
              myLocationButtonEnabled: true, // Botón para centrar en la ubicación del usuario
              zoomControlsEnabled: true,
              compassEnabled: true,
            ),
      floatingActionButton: FloatingActionButton(
        onPressed: _getLocationAndSetupMap,
        child: const Icon(Icons.location_searching),
      ),
    );
  }
}
Inicio Obtener Ubicación Actual ¿Permisos concedidos? No Solicitar Permisos Volver a intentar ¿Ubicación obtenida? No Mostrar error / progreso Inicializar GoogleMap con LatLng y Zoom Añadir marcador de ubicación actual Fin

🎯 Explicación de Componentes Clave

  • GoogleMapController: Permite controlar el mapa programáticamente, como mover la cámara o añadir elementos.
  • CameraPosition: Define la posición inicial de la cámara del mapa (latitud, longitud y zoom).
  • Marker: Representa un marcador en el mapa. Podemos personalizar su ID, posición, icono e InfoWindow.
  • myLocationEnabled y myLocationButtonEnabled: Opciones que muestran la ubicación actual del usuario con un punto azul y un botón para centrar la vista en ella, respectivamente.

✨ Añadiendo Marcadores Personalizados e Interacción

Además de la ubicación actual, a menudo necesitamos añadir marcadores estáticos o dinámicos en puntos de interés.

📌 Añadir Múltiples Marcadores

Podemos crear una lista de Marker objetos y añadirlos al Set<Marker> de nuestro estado.

// ... dentro de _MapScreenState

  final Set<Marker> _markers = {}; // Ya la teníamos

  void _addCustomMarkers() {
    _markers.add(
      Marker(
        markerId: const MarkerId('london'),
        position: const LatLng(51.5074, -0.1278), // Coordenadas de Londres
        infoWindow: const InfoWindow(title: 'Londres'),
        icon: BitmapDescriptor.defaultMarker,
      ),
    );
    _markers.add(
      Marker(
        markerId: const MarkerId('paris'),
        position: const LatLng(48.8566, 2.3522), // Coordenadas de París
        infoWindow: const InfoWindow(title: 'París'),
        icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueViolet),
      ),
    );
    // Actualizar el estado para que los marcadores aparezcan en el mapa
    setState(() {});
  }

// Puedes llamar a _addCustomMarkers() en initState después de _getLocationAndSetupMap()
// O a través de un botón en tu UI.

👆 Interacción del Usuario: Eventos del Mapa

El widget GoogleMap ofrece varios callbacks para interactuar con el usuario, como onTap, onLongPress, onCameraMove, etc.

Utilicemos onTap para añadir un nuevo marcador donde el usuario toque el mapa:

// ... dentro de _MapScreenState

  void _onMapTap(LatLng latLng) {
    setState(() {
      _markers.add(
        Marker(
          markerId: MarkerId(latLng.toString()), // Un ID único para cada toque
          position: latLng,
          infoWindow: InfoWindow(title: 'Nuevo punto: ${latLng.latitude.toStringAsFixed(4)}, ${latLng.longitude.toStringAsFixed(4)}'),
          icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueOrange),
          onTap: () { // Callback al tocar este marcador específico
            print('Marcador ${latLng.toString()} pulsado!');
          }
        ),
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // ... otros widgets
      body: _currentPosition == null
          ? const Center(child: CircularProgressIndicator())
          : GoogleMap(
              // ... propiedades existentes
              onTap: _onMapTap, // Aquí se añade el callback de tap
              // ... otras propiedades
            ),
      // ... FloatingActionButton
    );
  }
¿Cómo personalizar aún más los iconos de los marcadores? Puedes usar `BitmapDescriptor.fromAssetImage` para cargar una imagen desde tus assets como icono de marcador, o `BitmapDescriptor.fromBytes` para cargarla desde datos en memoria. Asegúrate de que las imágenes estén optimizadas para el tamaño deseado.
// Ejemplo de marcador con icono personalizado desde assets
// Future<BitmapDescriptor> customMarkerIcon = BitmapDescriptor.fromAssetImage(
//   const ImageConfiguration(size: Size(48, 48)), 'assets/my_custom_marker.png');
// Luego, usa await customMarkerIcon y pásalo al 'icon' del Marker.

🛣️ Dibujando Rutas y Polilíneas

Un caso de uso común es dibujar rutas entre dos o más puntos. Para esto, necesitamos utilizar la Directions API de Google Maps y el paquete flutter_polyline_points.

🌐 Obtener Datos de Ruta de Google Directions API

Necesitamos una función que haga una solicitud HTTP a la Google Directions API para obtener la información de la ruta en formato de polilínea codificada.

Primero, crea una constante para tu clave de API en un lugar seguro (por ejemplo, un archivo constants.dart que no esté en control de versiones).

// constants.dart
const String googleApiKey = 'TU_API_KEY_AQUI';

Luego, modifica tu location_service.dart o crea un nuevo servicio para las rutas.

// ... dentro de LocationService o un nuevo RoutesService

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter_polyline_points/flutter_polyline_points.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'constants.dart'; // Importa tu archivo de constantes con la API key

class RoutesService {
  static Future<List<LatLng>> getRouteCoordinates(
      LatLng origin, LatLng destination) async {
    List<LatLng> polylineCoordinates = [];

    final String url = 'https://maps.googleapis.com/maps/api/directions/json?' +
        'origin=${origin.latitude},${origin.longitude}&' +
        'destination=${destination.latitude},${destination.longitude}&' +
        'mode=driving&' + // Puedes cambiar a walking, bicycling, transit
        'key=$googleApiKey';

    final response = await http.get(Uri.parse(url));

    if (response.statusCode == 200) {
      final data = json.decode(response.body);
      if (data['routes'].isNotEmpty) {
        final String encodedPolyline = data['routes'][0]['overview_polyline']['points'];
        polylineCoordinates = PolylinePoints().decodePolyline(encodedPolyline);
        print('Polilínea decodificada con ${polylineCoordinates.length} puntos.');
      } else {
        print('No se encontraron rutas.');
      }
    } else {
      print('Error al obtener la ruta: ${response.statusCode}');
      print('Response body: ${response.body}');
    }
    return polylineCoordinates;
  }
}

🎨 Dibujar la Polilínea en el Mapa

Ahora, integra esto en tu MapScreen para dibujar la ruta.

// ... dentro de _MapScreenState

  final Set<Polyline> _polylines = {}; // Para almacenar las polilíneas

  // Agrega una función para dibujar una ruta entre dos puntos
  Future<void> _drawRoute(LatLng origin, LatLng destination) async {
    _polylines.clear(); // Limpia rutas anteriores
    setState(() {}); // Actualiza la UI

    List<LatLng> routePoints = await RoutesService.getRouteCoordinates(origin, destination);

    if (routePoints.isNotEmpty) {
      setState(() {
        _polylines.add(
          Polyline(
            polylineId: const PolylineId('route'),
            points: routePoints,
            color: Colors.blue, // Color de la línea
            width: 5, // Ancho de la línea
            jointType: JointType.round,
            startCap: Cap.roundCap,
            endCap: Cap.buttCap,
          ),
        );
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // ...
      body: _currentPosition == null
          ? const Center(child: CircularProgressIndicator())
          : GoogleMap(
              // ... propiedades existentes
              polylines: _polylines, // Añade las polilíneas al mapa
              // ...
            ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          await _getLocationAndSetupMap();
          if (_currentPosition != null) {
            // Ejemplo: Dibujar una ruta desde la ubicación actual hasta Londres
            await _drawRoute(
              LatLng(_currentPosition!.latitude, _currentPosition!.longitude),
              const LatLng(51.5074, -0.1278), // Coordenadas de Londres
            );
          }
        },
        child: const Icon(Icons.route),
      ),
    );
  }
Inicio Seleccionar Origen y Destino Llamar Google Directions API con clave de API ¿Respuesta 200 OK? No Mostrar error Decodificar Polilínea con flutter_polyline_points Crear objeto Polyline con puntos y estilo Añadir Polyline al GoogleMap Fin
🔥 Importante: Asegúrate de que la API de Directions esté habilitada en tu Google Cloud Console y de que tu clave de API tenga los permisos adecuados para acceder a ella.

🌐 Actualización Continua de la Ubicación (Opcional)

Para aplicaciones que requieren seguir al usuario en tiempo real, geolocator ofrece un stream de actualizaciones de ubicación.

🔄 Escuchando Cambios de Ubicación

Puedes usar Geolocator.getPositionStream para recibir actualizaciones de ubicación. Es importante manejar la suscripción y desuscripción correctamente.

// ... dentro de _MapScreenState
import 'dart:async';

  StreamSubscription<Position>? _positionStreamSubscription;

  void _startLocationUpdates() async {
    // Configura la precisión y distancia mínima para las actualizaciones
    LocationSettings locationSettings = const LocationSettings(
      accuracy: LocationAccuracy.high,
      distanceFilter: 10, // Actualizar si el usuario se mueve al menos 10 metros
    );

    _positionStreamSubscription = Geolocator.getPositionStream(locationSettings: locationSettings)
        .listen((Position? position) {
      if (position != null) {
        setState(() {
          _currentPosition = position;
          // Actualizar la posición del marcador de ubicación actual
          _markers.removeWhere((marker) => marker.markerId.value == 'currentLocation');
          _markers.add(
            Marker(
              markerId: const MarkerId('currentLocation'),
              position: LatLng(position.latitude, position.longitude),
              infoWindow: const InfoWindow(title: 'Tu Ubicación Actual (En Vivo)'),
              icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueBlue),
            ),
          );
          // Opcional: Animar la cámara para seguir al usuario
          mapController?.animateCamera(
            CameraUpdate.newCameraPosition(
              CameraPosition(
                target: LatLng(position.latitude, position.longitude),
                zoom: 15.0,
              ),
            ),
          );
        });
      }
    });
  }

  // Es crucial cancelar la suscripción cuando el widget ya no está activo
  @override
  void dispose() {
    _positionStreamSubscription?.cancel();
    super.dispose();
  }

// Llama a _startLocationUpdates() en initState después de haber obtenido la primera ubicación
// para comenzar a escuchar actualizaciones.

🛠️ Consejos Adicionales y Optimización

🖼️ Carga de Mapas y Rendimiento

  • Precarga de Mapas: Si tu aplicación siempre muestra un mapa, considera precargar la información del mapa en segundo plano o al inicio de la aplicación para una experiencia más fluida.
  • Optimización de Marcadores: Para un gran número de marcadores, considera técnicas como el clustering para agrupar marcadores cercanos y mejorar el rendimiento y la legibilidad del mapa.

🔒 Seguridad de la API Key

Aunque ya mencionamos las restricciones, es buena práctica considerar ocultar la API key de Google Maps en el código, especialmente en entornos de producción. Puedes usar variables de entorno o un sistema de configuración seguro en tu proceso de construcción.

🧪 Pruebas en Emuladores/Simuladores y Dispositivos Reales

  • Emuladores Android: Puedes simular ubicaciones en Android Studio (Tools > Device Manager > Virtual Device > Edit > Show Advanced Settings > Camera > VirtualScene/Emulated). O usa el panel de 'Extended Controls' del emulador (los tres puntos a la derecha) y ve a 'Location'.
  • Simuladores iOS: En Xcode, cuando tu aplicación está corriendo en el simulador, puedes ir a Debug > Simulate Location y elegir una ubicación predefinida o personalizada.
  • Dispositivos Reales: Siempre prueba en un dispositivo real para verificar el comportamiento de los permisos y la precisión de la geolocalización.
Casi Listo

✅ Conclusión

Has llegado al final de este completo tutorial sobre cómo integrar mapas interactivos y geolocalización en tus aplicaciones Flutter. Hemos cubierto los pasos esenciales, desde la configuración de tu proyecto y la obtención de la clave de API, hasta la visualización de la ubicación actual del usuario, la adición de marcadores personalizados y el dibujo de rutas entre puntos.

La capacidad de integrar mapas es una habilidad poderosa que abre un sinfín de posibilidades para tus aplicaciones. ¡Experimenta con las diferentes funcionalidades, personaliza los marcadores y las polilíneas, y crea experiencias de usuario increíbles con Flutter y Google Maps!

Paso 1: Configuración del entorno y API Key.
Paso 2: Adición de dependencias en `pubspec.yaml`.
Paso 3: Configuración específica para Android e iOS.
Paso 4: Solicitud de permisos de ubicación y obtención de la posición actual.
Paso 5: Implementación del widget `GoogleMap` y visualización de marcadores.
Paso 6: Adición de interactividad y marcadores personalizados.
Paso 7: Integración de la Google Directions API para dibujar rutas.
Paso 8: Implementación de actualizaciones continuas de ubicación (opcional).

Esperamos que este tutorial te haya sido de gran utilidad. ¡Feliz codificación! 🚀

Tutoriales relacionados

Comentarios (0)

Aún no hay comentarios. ¡Sé el primero!