Google Maps in Flutter

By | May 12, 2019

For Adding Google Maps in Flutter, you need the API keys for each app.

Let’s Start


Flutter Google Maps

Flutter Google Maps


Watch Video Tutorial


Get API Key

To get API key, you have to go to Google Platform Cloud Console and register your app there. Create a new project or set up a new one, the enable Google Maps to get the API key. Follow the instructions in the below link to get the API keys for Android and iOS.

Android:
https://developers.google.com/maps/documentation/android-sdk/signup

iOS
https://developers.google.com/maps/documentation/ios-sdk/get-api-key


Add Plugin

Go to your pubspec.yaml file in the root of your project

dependencies:
  flutter: 
    sdk: flutter

  ...
  google_maps_flutter: ^0.5.11
  ...

Android Integration

Once you have the API key, add the key to the AndroidManifest.xml file.
For that open the Android project which is present inside your flutter project and app level build.gradle.

Add the below tag inside the Application tag.

    <meta-data android:name="com.google.android.geo.API_KEY"
               android:value="YOUR_ANDROID_API_KEY_HERE"/>

Google Maps initial set up for Android is complete.


iOS Integration

Open the AppDelegate.m file in your iOS project.

Add the below imports and code

#import "GoogleMaps/GoogleMaps.h"
....

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    [GMSServices provideAPIKey:@"YOUR_IOS_API_KEY_HERE"];
    [GeneratedPluginRegistrant registerWithRegistry:self];

    
  // Override point for customization after application launch.
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

<hr />

<strong><font color="purple" size="5">Flutter Code</font></strong>

Now let's start the flutter code.

import the necessary packages and initializing necessary variables.


import 'dart:async';
import 'package:google_maps_flutter/google_maps_flutter.dart';

Completer<GoogleMapController> _controller = Completer();
  static const LatLng _center = const LatLng(45.521563, -122.677433);
  final Set<Marker> _markers = {};
  LatLng _lastMapPosition = _center;
  MapType _currentMapType = MapType.normal;


Add Google Maps Widget

Go to your build method and add the Google Maps Widget

...
Stack(
    children: <Widget>[
    GoogleMap(
        onMapCreated: _onMapCreated,
        initialCameraPosition: CameraPosition(
        target: _center,
        zoom: 11.0,
        ),
        mapType: _currentMapType,
        markers: _markers,
        onCameraMove: _onCameraMove,
),
...


// intialize the controller on Map Create
 _onMapCreated(GoogleMapController controller) {
    _controller.complete(controller);
  }

// Update the position on CameraMove
 _onCameraMove(CameraPosition position) {
    _lastMapPosition = position.target;
  }


Add Map Type Toggle

We will toggle the MapType on press of a button

_onMapTypeButtonPressed() {
    setState(() {
      _currentMapType = _currentMapType == MapType.normal
          ? MapType.satellite
          : MapType.normal;
    });
}

Add Marker

Add Marker to the last map position.

_onAddMarkerButtonPressed() {
    setState(() {
      _markers.add(
        Marker(
          markerId: MarkerId(_lastMapPosition.toString()),
          position: _lastMapPosition,
          infoWindow: InfoWindow(
            title: 'This is a Title',
            snippet: 'This is a snippet',
          ),
          icon: BitmapDescriptor.defaultMarker,
        ),
      );
    });
 }

Add Buttons on top of Map

Below function creates a button and returns it. we will add it to the main UI

Widget button(Function function, IconData icon) {
    return FloatingActionButton(
        onPressed: function,
        materialTapTargetSize: MaterialTapTargetSize.padded,
        backgroundColor: Colors.blue,
        child: Icon(
        icon,
        size: 36.0,
        ),
    );
}

// in the build method
...
Padding(
    padding: EdgeInsets.all(16.0),
    child: Align(
    alignment: Alignment.topRight,
    child: Column(
        children: <Widget>[
        button(_onMapTypeButtonPressed, Icons.map),
        SizedBox(
            height: 16.0,
        ),
        button(_onAddMarkerButtonPressed, Icons.add_location),
        SizedBox(
            height: 16.0,
        ),
        button(_goToPosition1, Icons.location_searching),
        ],
    ),
    ),
),

Animate to a new Position

Let’s create a new Position to animate to.

static final CameraPosition _position1 = CameraPosition(
    bearing: 192.833,
    target: LatLng(45.531563, -122.677433),
    tilt: 59.440,
    zoom: 11.0,
);

Future<void> _goToPosition1() async {
    final GoogleMapController controller = await _controller.future;
    controller.animateCamera(CameraUpdate.newCameraPosition(_position1));
}

The above function will move the map position to the new position.


Complete Code

import 'package:flutter/material.dart';
import 'dart:async';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class MapsDemo extends StatefulWidget {
  MapsDemo() : super();

  final String title = "Maps Demo";

  @override
  MapsDemoState createState() => MapsDemoState();
}

class MapsDemoState extends State<MapsDemo> {
  //
  Completer<GoogleMapController> _controller = Completer();
  static const LatLng _center = const LatLng(45.521563, -122.677433);
  final Set<Marker> _markers = {};
  LatLng _lastMapPosition = _center;
  MapType _currentMapType = MapType.normal;

  static final CameraPosition _position1 = CameraPosition(
    bearing: 192.833,
    target: LatLng(45.531563, -122.677433),
    tilt: 59.440,
    zoom: 11.0,
  );

  Future<void> _goToPosition1() async {
    final GoogleMapController controller = await _controller.future;
    controller.animateCamera(CameraUpdate.newCameraPosition(_position1));
  }

  _onMapCreated(GoogleMapController controller) {
    _controller.complete(controller);
  }

  _onCameraMove(CameraPosition position) {
    _lastMapPosition = position.target;
  }

  _onMapTypeButtonPressed() {
    setState(() {
      _currentMapType = _currentMapType == MapType.normal
          ? MapType.satellite
          : MapType.normal;
    });
  }

  _onAddMarkerButtonPressed() {
    setState(() {
      _markers.add(
        Marker(
          markerId: MarkerId(_lastMapPosition.toString()),
          position: _lastMapPosition,
          infoWindow: InfoWindow(
            title: 'This is a Title',
            snippet: 'This is a snippet',
          ),
          icon: BitmapDescriptor.defaultMarker,
        ),
      );
    });
  }

  Widget button(Function function, IconData icon) {
    return FloatingActionButton(
      onPressed: function,
      materialTapTargetSize: MaterialTapTargetSize.padded,
      backgroundColor: Colors.blue,
      child: Icon(
        icon,
        size: 36.0,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
          backgroundColor: Colors.blue,
        ),
        body: Stack(
          children: <Widget>[
            GoogleMap(
              onMapCreated: _onMapCreated,
              initialCameraPosition: CameraPosition(
                target: _center,
                zoom: 11.0,
              ),
              mapType: _currentMapType,
              markers: _markers,
              onCameraMove: _onCameraMove,
            ),
            Padding(
              padding: EdgeInsets.all(16.0),
              child: Align(
                alignment: Alignment.topRight,
                child: Column(
                  children: <Widget>[
                    button(_onMapTypeButtonPressed, Icons.map),
                    SizedBox(
                      height: 16.0,
                    ),
                    button(_onAddMarkerButtonPressed, Icons.add_location),
                    SizedBox(
                      height: 16.0,
                    ),
                    button(_goToPosition1, Icons.location_searching),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Complete Source code

The complete source code is available in this link.


Leave a Reply

Your email address will not be published. Required fields are marked *