Flutter How-To: Integrate Google Maps

Google Map integration

This post is about an experimental and unpublished version of a to-be-official Google Maps widget that is being developed internally at Google with some community support.

Update (6-Sep-2018): The current version of the plugin does not support iOS anymore so I’ve added a ‘ref’ property in pubspec.yaml to fetch the older unbroken plugin code. The latest version, though, simplifies a lot of stuff so if you’re targeting Android, go for it.

Most probably you’ve come across this post because you want to integrate Google Maps in a Flutter app with all (or at least most of) the interactivity of a typical Google Maps app. Currently (Aug 2018), we do not have a very strong support for maps in a Flutter app but it’s coming soon as part of plugins offered by Flutter Team itself. The sample that we will be making will look like:

     Sample app with Google Map integration

The plugin that I’m talking about can be found here. Work on this plugin is underway and it is not production ready as yet (that’s why it’s only available as a preview for now). But nonetheless, I found that it can be used for some very basic map features. The widget does come with some caveats and the most important ones for me are:

  • It requires some initialization outside the app widget
  • It doesn’t scale itself well and requires explicit width and height
  • No other widget can be overlaid on it

The basics

The sample code and example app are good ways to learn the basics. One thing to keep in mind is that we have to write some initialization code inside main method in order to properly show the map.

Updating pubspec.yaml

You’ll need to add the dependency first.

google_maps_flutter:
   git:
     url: git://github.com/flutter/plugins
     path: packages/google_maps_flutter
     ref: 'ce3a913c3834'

Acquiring API key and adding meta data

Get an API key at https://cloud.google.com/maps-platform/.

Android

Add the API key in application manifest

android/app/src/main/AndroidManifest.xml:

<manifest …
<application …
<meta-data android:name=”com.google.android.geo.API_KEY”
android:value=”YOUR KEY HERE”/>

iOS

Specify your API key in application delgate ios/Runner/AppDelegate.m:

[php]
#include "AppDelegate.h"
#include "GeneratedPluginRegistrant.h"
#import "GoogleMaps/GoogleMaps.h"

@implementation AppDelegate

– (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GMSServices provideAPIKey:@"YOUR KEY HERE"];
[GeneratedPluginRegistrant registerWithRegistry:self];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end
[/php]

Using the widget

Here’s the complete sample code picked up shamelessly from original repo 😀

[php]
import ‘package:flutter/material.dart’;
import ‘package:google_maps_flutter/google_maps_flutter.dart’;

void main() {
GoogleMapController.init();
final GoogleMapOverlayController controller =
GoogleMapOverlayController.fromSize(width: 300.0, height: 200.0);
final Widget mapWidget = GoogleMapOverlay(controller: controller);
runApp(MaterialApp(
home: new Scaffold(
appBar: AppBar(title: const Text(‘Google Maps demo’)),
body: MapsDemo(mapWidget, controller.mapController),
),
navigatorObservers: <NavigatorObserver>[controller.overlayController],
));
}

class MapsDemo extends StatelessWidget {
MapsDemo(this.mapWidget, this.controller);

final Widget mapWidget;
final GoogleMapController controller;

@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(15.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Center(child: mapWidget),
RaisedButton(
child: const Text(‘Go to London’),
onPressed: () {
controller.animateCamera(CameraUpdate.newCameraPosition(
const CameraPosition(
bearing: 270.0,
target: LatLng(51.5160895, -0.1294527),
tilt: 30.0,
zoom: 17.0,
),
));
},
),
],
),
);
}
}
[/php]

I’ve modified this code a little bit in order to make the map cover the page body:

[php]
import ‘dart:ui’ as ui;

import ‘package:flutter/material.dart’;
import ‘package:google_maps_flutter/google_maps_flutter.dart’;

void main() {
GoogleMapController.init();
final size = MediaQueryData.fromWindow(ui.window).size;
final GoogleMapOverlayController controller =
GoogleMapOverlayController.fromSize(
width: size.width,
height: size.height – 72.0,
);
final mapController = controller.mapController;
final Widget mapWidget = GoogleMapOverlay(controller: controller);
runApp(
MaterialApp(
home: new Scaffold(
appBar: AppBar(
title: TextField(
decoration: InputDecoration.collapsed(hintText: ‘Search’),
),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.my_location),
onPressed: () {
final location = LatLng(24.934163, 67.044612);
mapController.markers.clear();
mapController.addMarker(MarkerOptions(
position: location,
));
mapController.animateCamera(
CameraUpdate.newLatLngZoom(
location, 15.0),
);
},
),
],
),
body: MapsDemo(mapWidget, controller.mapController),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.my_location),
),
),
navigatorObservers: <NavigatorObserver>[controller.overlayController],
),
);
}

class MapsDemo extends StatelessWidget {
MapsDemo(this.mapWidget, this.controller);

final Widget mapWidget;
final GoogleMapController controller;

@override
Widget build(BuildContext context) {
return Center(child: mapWidget);
}
}
[/php]

Note that I’ve used MediaQueryData and dart:ui to get the size of current window. I’m then using relevant size for map initialization like so:

[php]
final size = MediaQueryData.fromWindow(ui.window).size;
final GoogleMapOverlayController controller = GoogleMapOverlayController.fromSize(
<strong class="markup–strong markup–pre-strong">width: size.width,
height: size.height – 72.0, //roughly subtracting appbar height</strong>
);
[/php]

And that’s all you need to do in order to have a basic full-screen map running with in-built gestures (zooming and panning etc).

Hope you like this post, happy Fluttering!

Credit : https://medium.com/flutter-community/flutter-how-to-integrate-google-maps-experimental-5ec8485c0c59

Next Article : Building Places & Location Search with Map View Using Flutter 1.0

Leave a Comment

Your email address will not be published.