Using Google Maps with FLutter

Using Google Maps with Flutter

James Fielder Development Technologies, Flutter, Mobile, Tutorial Leave a Comment

Flutter has a lot of amazing plugins that make it easy to develop cross-platform apps. Recently, I had the opportunity to work with a theater chain that made use of a map view to show nearby theaters. We used Flutter in conjunction with Google Maps.

In this blog post, we will take a look at the Google Maps Flutter plugin, which allows you to add an interactive map to your iOS or Android app and customize it in many different ways!

Getting Started

To get started, go ahead and create a new flutter project. Then, you will need to create a project on Google Cloud, and then follow the instructions detailed here to get your API keys.

Once you get your API keys, the next step varies whether you’re working with Android or iOS. I’ll explain both separately below.

For Android

Set the minSdkVersion in android/app/build.gradle.

android {
    defaultConfig {
        minSdkVersion 20
    }
}

Also, set the API key in android/app/src/main/AndroidManifest.xml.

<manifest ...
  <application ...
    <meta-data android:name="com.google.android.geo.API_KEY"
               android:value="API KEY"/>

For iOS

The instructions for iOS are different depending on whether you’re using Objective-C or Swift.

Objective-C

Add the key to ios/Runner/AppDelegate.m

#include "AppDelegate.h"
#include "GeneratedPluginRegistrant.h"
#import "GoogleMaps/GoogleMaps.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GMSServices provideAPIKey:@"API KEY"];
  [GeneratedPluginRegistrant registerWithRegistry:self];
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end

Swift

Add the key to ios/Runner/AppDelegate.swift.

import UIKit
import Flutter
import GoogleMaps

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GMSServices.provideAPIKey("API KEY")
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

Don’t forget the #import "GoogleMaps/GoogleMaps.h" or import GoogleMaps for iOS!

Creating the map in Flutter

Now we are ready to create and add the map widget to our views. For testing purposes, I will be using iOS.

Let’s start by first creating a regular map similar to the one you would see using the Maps app on your phone. Replace the generated code in your main.dart file with:

import 'dart:async';

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Map Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyMapPage(),
    );
  }
}

class MyMapPage extends StatefulWidget {
  @override
  State<MyMapPage> createState() => MapPageState();
}

class MapPageState extends State<MyMapPage> {
  Completer<GoogleMapController> _controller = Completer();

  static const CameraPosition initialCameraPosition = CameraPosition(
    target: LatLng(
      32.776665,
      -96.796989,
    ),
    zoom: 10.0,
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GoogleMap(
        mapType: MapType.normal,
        initialCameraPosition: initialCameraPosition,
        onMapCreated: (GoogleMapController controller) {
          _controller.complete(controller);
        },
      ),
    );
  }
}

Like everything else in Flutter, GoogleMap is a widget. That means you can place this anywhere a widget can be placed! This leads to a lot of flexibility in creating your UI as you can manipulate it like any other widget. For now, though, we will stick to simply putting it as the body of the Scaffold widget.

We also used the MapType.normal, which, as I mentioned above, is similar to the regular map you would see. There are other options such as MapType.satellite, MapType.hyprid, etc. However, for the sake of simplicity, in this post, we will just use the normal variation.

Flutter with Google Maps

Now we have a basic map centered in Dallas, but something like this is pretty useless on its own. Take this for example: let’s say you were making an app that showed parks around an area you were in. You would want to add some markers to denote where the parks were, right?

So, let’s add some markers to our map. Copy the following code under Completer _controller = Completer();.

This will create a set of markers with the specified coordinates and unique marker id. It is also prefixed with the late keyword to allow us to lazy initialize. That way, we can add some code later that will allow us to interact with the marker.

  late Set<Marker> _markers = {
    Marker(
      markerId: MarkerId('lakeside_park'),
      position: LatLng(32.8284240447788, -96.8010946692594),
    ),
    Marker(
      markerId: MarkerId('aquarium'),
      position: LatLng(32.7845126858013, -96.80515900833115),
    ),
    Marker(
      markerId: MarkerId('university_hospital'),
      position: LatLng(32.79155578373443, -96.77746552465636),
    ),
    Marker(
      markerId: MarkerId('zoo'),
      position: LatLng(32.74343301670828, -96.81628470752499),
    ),
  };

Then, pass the variable into the GoogleMap markers: parameter.

All you have to do now is reload the app, and you should see four markers on the map!

Now, let’s try and make the markers interactive. We will add some code that will change the color of the marker when it’s pressed.

First, add a new method called UpdateMarker. It will take the parameter of the marker id so that we know which marker we want to change color on and a boolean flag that we will use to flip the color back and forth.

We will first find the marker by its ID and then remove it from the set and add a new one with a different color. With all this logic wrapped in setState, it will update the UI to look like the marker has changed color.

void UpdateMarker(String markerId, bool colorSwitch) {
    setState(() {
      var marker =
          _markers.firstWhere((element) => element.markerId.value == markerId);

      _markers.removeWhere((element) => element.markerId.value == markerId);

      double hueColor;

      if (colorSwitch) {
        hueColor = BitmapDescriptor.hueBlue;
      } else {
        hueColor = BitmapDescriptor.hueRed;
      }

      _markers.add(Marker(
        markerId: MarkerId(markerId),
        position: LatLng(32.8284240447788, -96.8010946692594),
        icon: BitmapDescriptor.defaultMarkerWithHue(hueColor),
        onTap: () => UpdateMarker(markerId, !colorSwitch),
      ));
    });
  }
 

Then, add the following code to the lakeside_park marker, icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueBlue), and
onTap: () => UpdateMarker('lakeside_park', false).

Now, the topmost marker has turned blue, and you can click on each marker and change its color. You can easily switch out the marker with your own icons as well and make it as interactive as you want!

Flutter with Google Maps

We can also add other items to the maps such as Circles, which would be great for apps that require the user to be inside a certain location to use their services. Let’s do that now.

Add the following code above _markers.

 late Set<Circle> _circles = {
    Circle(
      circleId: CircleId(
        'myCircle',
      ),
      center: LatLng(
        32.776665,
        -96.796989,
      ),
      radius: 1500,
      fillColor: Colors.red.withOpacity(.25),
      strokeColor: Colors.red,
      strokeWidth: 2,
    ),
  };

Then, set the circles parameter in GoogleMap, circles: _circles. This creates a circle with the center at the specified coordinate and a radius of 1500m.

The fillColor sets the inner fill of the circle and makes it a little transparent so that it is easier to see under the circle. The strokeColor and strokeWidth sets the color and thickness of the circle outline.

     

Conclusion

This is just a small sample of the Flutter Google Maps package. There are many other ways to customize and add functionality to the map such as adding Polylines , Polygons, and TileOverlay – just to name a few.

Since the map is a widget like everything else in Flutter, any UI manipulations that can be done on widgets can be done on the map! Basically, the potential is huge.

I hope that you learned something from this post and might try out adding maps to your next app! If you have questions or comments, leave them in the comments below, and if you liked this post, check out the many more we have on the Keyhole Dev Blog.

5 1 vote
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments