" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button">
<meta-data android:name="com.google.android.geo.API_KEY"
android:value="YOUR_API_KEY"/>
(iOS) Your minimum iOS version must be 9.0 or higher
This should already be the case because Flutter itself requires that version. Otherwise, check this article at the step iOS Deployment Target.
(iOS) Your API key must be added to the application delegate
In your Flutter project directory go to ios/Runner/AppDelegate.swift
and adjust the code as seen below
import UIKit
import Flutter
import GoogleMaps
@UIApplicationMain@objcclassAppDelegate:FlutterAppDelegate {
overridefuncapplication(
_ application:UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey:Any]?
) -> Bool {
GMSServices.provideAPIKey("YOUR_API_KEY")
GeneratedPluginRegistrant.register(with:self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
You have configured your app properly. Let’s move on to integrate a Google Maps widget.
Warning
Newer versions of the package might require different settings. Make sure to check the setup guidelines and adjust your code accordingly.
To add a map, you can use the following code. It will display a map with the center over Berlin in Europe. For a more complex version, please refer to the GitHub repository with code samples.
@override | |
Widget build(BuildContext context) { | |
_setCustomMarkerImage(); | |
return const Scaffold( | |
body: Padding( | |
padding: EdgeInsets.only(top: 30), | |
child: GoogleMap( | |
initialCameraPosition: CameraPosition( | |
zoom: 15, | |
target: LatLng(52.52309894124325, 13.413122125924026))))); | |
} |
There are a lot of properties to configure the map like rotateGesturesEnabled
, zoomGesturesEnabled
, trafficEnabled
, or liteModeEnabled
(only for Android). Customize it completely your way!
The widget offers various events that you can handle
onTap
onLongPress
onCameraMove
onMapCreated
The onMapCreated
event returns a GoogleMapController
which gives you complete control over the map. Some exposed methods are
getLatLng
– returns the latitude/longitude combination of a screen positiontakeSnapshot
– returns a byte array of the current map imagemoveCamera
– jumps to a given position (see section “Moving the camera”)animateCamera
– moves to a given position (see section “Moving the camera”showMarkerInfoWindow
– shows the info window of a given marker (see section “Adding markers”)The following example will display a rotated blue marker pin in Berlin/Europe.
GoogleMap( | |
... | |
markers: <Marker>{ | |
Marker( | |
markerId: const MarkerId("BerlinMarker"), | |
rotation: 180, | |
consumeTapEvents: true, | |
onTap: () => print( | |
"infoWindow is ignoriert, if consumeTapEvents is true!"), | |
infoWindow: const InfoWindow( | |
title: "Berlin", | |
snippet: | |
"Location is 52.52309894124325, 13.413122125924026"), | |
icon: BitmapDescriptor.defaultMarkerWithHue( | |
BitmapDescriptor.hueAzure), | |
position: | |
const LatLng(52.52309894124325, 13.413122125924026))}), |
By default, a tap on the marker centers the map over it. If an InfoWindow
is defined, it will be displayed. The onTap
event will only be handled if consumeTapEvents
is set to true. In that case, the InfoWindow
is ignored. You can also use the GoogleMapController to trigger the InfoWindow
.
The following example will display a circle around the center of Berlin/Europe.
GoogleMap( | |
... | |
circles: <Circle>{ | |
Circle( | |
circleId: const CircleId("BerlinCircle"), | |
consumeTapEvents: true, | |
onTap: () => print("onTap: Berlin circle tapped"), | |
center: | |
const LatLng(52.52309894124325, 13.413122125924026), | |
radius: 25000, | |
fillColor: Colors.grey.shade300, | |
strokeWidth: 1, | |
strokeColor: Colors.black)}), |
The radius
is denoted in meters. You can adjust the style with fillColor
, strokeColor
, and strokeWidth
and handle the onTap
event if required.
The following code sets a custom marker image by using the asset image “icon.png” in Munich/Europe.
BitmapDescriptor? _customIcon; | |
Future _setCustomMarkerImage() async { | |
if (_customIcon != null) return; | |
// replaces the default marker with an asset image "icon.png" | |
final ImageConfiguration imageConfiguration = | |
createLocalImageConfiguration(context, size: const Size.square(24)); | |
var bmp = await BitmapDescriptor.fromAssetImage( | |
imageConfiguration, "icon.png", | |
mipmaps: false); | |
setState(() { | |
_customIcon = bmp; | |
}); | |
} | |
@override | |
Widget build(BuildContext context) { | |
_setCustomMarkerImage(); | |
return Scaffold( | |
body: Padding( | |
padding: const EdgeInsets.only(top: 30), | |
child: GoogleMap( | |
... | |
markers: <Marker>{ | |
(_customIcon == null) | |
? const Marker( | |
markerId: MarkerId("MünchenMarker"), | |
rotation: 315, | |
infoWindow: InfoWindow( | |
title: "München", | |
snippet: | |
"Location is 48.1272193947633, 11.555870900278869"), | |
position: | |
LatLng(48.1272193947633, 11.555870900278869)) | |
: Marker( | |
markerId: const MarkerId("MünchenMarker"), | |
rotation: 315, | |
infoWindow: const InfoWindow( | |
title: "München", | |
snippet: | |
"Location is 48.1272193947633, 11.555870900278869"), | |
icon: _customIcon!, | |
position: const LatLng( | |
48.1272193947633, 11.555870900278869)) | |
}))); | |
} |
Make sure to reference the asset image in your pubspec.yaml
file.
The GoogleMapController
(see section “Handling events”) can be used to move the camera so that you can show a specific location to the user. It will either jump (moveCamera
) or scroll (animateCamera
) to the target position. An example looks like this:
await controller.moveCamera(
CameraUpdate.newLatLng(LatLng(52.52309894124325, 13.413122125924026)));
await controller.animateCamera(
CameraUpdate.newLatLng(LatLng(52.52309894124325, 13.413122125924026)));
The google maps widget has the property myLocationEnabled
. If set to true your current location will be marked as a blue dot on the map. To make this work, your app needs to ask for permission to use location services. If location services are enabled and permission was granted, the location will automatically be displayed. I created a separate article on that topic.
Hint
You don’t need to install the package, but you need to add the capabilities for Android and iOS. The Google Maps widget has built-in location support without any further requirements.
The source code is available on GitHub. Be aware that you need to replace the API keys inside the code with your own to make the demo code work!
You can see a screenshot of the app below.
In this article, we talked about adding a map to a Flutter application. Though the setup might be a bit time-consuming, it will be worth the trouble. The Google Maps widget is quite powerful and allows you to enrich your app in a very unique way.