Introduction to google_maps_flutter
Introduction to google_maps_flutter
The google_maps_flutter package is the official Flutter plugin for embedding Google Maps into Android and iOS applications. It provides a GoogleMap widget that wraps the native Google Maps SDK on each platform, giving you full access to markers, polylines, polygons, camera controls, and map type switching — all through a declarative Flutter API.
In this lesson you will add the package to a project, configure the required API keys for both platforms, and render your first interactive map with a fixed initial camera position.
google_maps_flutter requires a valid Google Maps API key with the Maps SDK for Android and Maps SDK for iOS APIs enabled in the Google Cloud Console. Without a key the map will render as a grey grid.Step 1 — Adding the Package
Open your project's pubspec.yaml and add the dependency under dependencies:
pubspec.yaml
dependencies:
flutter:
sdk: flutter
google_maps_flutter: ^2.9.0
After saving, run flutter pub get to fetch the package. The plugin automatically links the native Google Maps SDK on both Android and iOS through Flutter's plugin system — no manual Gradle or CocoaPods edits are needed for the plugin itself, only the API-key configuration below.
Step 2 — Configuring the Android API Key
Open android/app/src/main/AndroidManifest.xml and add a <meta-data> element inside the <application> tag:
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:label="my_app"
android:icon="@mipmap/ic_launcher">
<!-- Google Maps API key -->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="YOUR_ANDROID_API_KEY"/>
<activity ... />
</application>
</manifest>
local.properties file (already in .gitignore) or environment injection via a CI/CD pipeline. The placeholder above is fine for development but must be secured before shipping.Also ensure the minimum SDK version in android/app/build.gradle is at least 21:
android/app/build.gradle
android {
defaultConfig {
minSdkVersion 21 // google_maps_flutter requires API 21+
targetSdkVersion 34
}
}
Step 3 — Configuring the iOS API Key
Open ios/Runner/AppDelegate.swift and call GMSServices.provideAPIKey before the Flutter engine starts:
ios/Runner/AppDelegate.swift
import UIKit
import Flutter
import GoogleMaps // 1. Import the SDK
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// 2. Provide the API key before GeneratedPluginRegistrant
GMSServices.provideAPIKey("YOUR_IOS_API_KEY")
GeneratedPluginRegistrant.register(with: self)
return super.application(application,
didFinishLaunchingWithOptions: launchOptions)
}
}
[GMSServices provideAPIKey:@"YOUR_IOS_API_KEY"] in AppDelegate.m before [GeneratedPluginRegistrant registerWithRegistry:self].Then run cd ios && pod install (or flutter pub get which triggers pod install automatically on first run) so that CocoaPods links the GoogleMaps framework.
Step 4 — Rendering a Basic GoogleMap Widget
With the package added and keys configured, you can now embed a map anywhere in your widget tree. The GoogleMap widget requires one mandatory parameter: initialCameraPosition. A CameraPosition needs at minimum a LatLng target and a zoom level.
Basic GoogleMap widget
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class MapScreen extends StatefulWidget {
const MapScreen({super.key});
@override
State<MapScreen> createState() => _MapScreenState();
}
class _MapScreenState extends State<MapScreen> {
// Optional: keep a reference to animate the camera later
GoogleMapController? _controller;
static const CameraPosition _initialPosition = CameraPosition(
target: LatLng(24.7136, 46.6753), // Riyadh, Saudi Arabia
zoom: 12.0,
);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Map')),
body: GoogleMap(
initialCameraPosition: _initialPosition,
onMapCreated: (GoogleMapController controller) {
_controller = controller;
},
myLocationButtonEnabled: false,
zoomControlsEnabled: true,
),
);
}
@override
void dispose() {
_controller?.dispose();
super.dispose();
}
}
Key points from the code above:
initialCameraPosition— mandatory; sets where the camera is aimed when the map first loads.onMapCreated— callback that fires once the underlying native map is ready; use it to store theGoogleMapControllerfor later camera animations.GoogleMapController.dispose()— must be called indispose()to free the native map resources and avoid memory leaks.myLocationButtonEnabled: false— disables the blue dot and button until you request thelocationpermission (covered in a later lesson).
Zoom Levels Reference
The zoom property of CameraPosition follows Google Maps' standard scale:
- 1 — World view
- 5 — Continent / large country
- 10 — City
- 15 — Streets
- 20 — Buildings / individual blocks
bearing (rotation in degrees, 0 = North) and tilt (0–90 degrees) in CameraPosition for a perspective view. For most use-cases the defaults (bearing: 0, tilt: 0) are fine.Summary
In this lesson you learned how to:
- Add
google_maps_fluttertopubspec.yamland runflutter pub get. - Register the Maps API key in
AndroidManifest.xmlfor Android. - Call
GMSServices.provideAPIKeyinAppDelegate.swiftfor iOS. - Render a
GoogleMapwidget with a fixedCameraPosition. - Store a
GoogleMapControllerand dispose it correctly to avoid memory leaks.