Skip to content

Commit 5deb828

Browse files
committed
feat: add support for mapID
1 parent 0d2c538 commit 5deb828

File tree

24 files changed

+350
-34
lines changed

24 files changed

+350
-34
lines changed

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,32 @@ This parameter has only an effect on Android.
199199
200200
```
201201

202+
#### Using Map IDs
203+
You can configure your map by providing a `mapId` parameter during map initialization. Map IDs are created in the [Google Cloud Console](https://console.cloud.google.com/google/maps-apis/studio/maps) and allow you to [enable various Google Maps Platform features](https://developers.google.com/maps/documentation/android-sdk/map-ids/mapid-over#features-available), such as cloud-based map styling.
204+
205+
> [!NOTE]
206+
> The `mapId` can only be set once during map initialization and cannot be changed afterwards. Both `GoogleMapsMapView` and `GoogleMapsNavigationView` support the `mapId` parameter.
207+
208+
For `GoogleMapsMapView`:
209+
210+
```dart
211+
GoogleMapsMapView(
212+
mapId: 'YOUR_MAP_ID', // Can only be set during initialization
213+
...
214+
)
215+
```
216+
217+
For `GoogleMapsNavigationView`:
218+
219+
```dart
220+
GoogleMapsNavigationView(
221+
mapId: 'YOUR_MAP_ID', // Can only be set during initialization
222+
...
223+
)
224+
```
225+
226+
For more information about map IDs and how to create them, see the [Google Maps Platform documentation](https://developers.google.com/maps/documentation/get-map-id).
227+
202228
See the [example](./example) directory for a complete navigation sample app.
203229

204230
### Requesting and handling permissions

android/src/main/kotlin/com/google/maps/flutter/navigation/Convert.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ object Convert {
8282
options.minZoomPreference?.let { googleMapOptions.minZoomPreference(it.toFloat()) }
8383
options.maxZoomPreference?.let { googleMapOptions.maxZoomPreference(it.toFloat()) }
8484
googleMapOptions.zoomControlsEnabled(options.zoomControlsEnabled)
85+
options.mapId?.let { googleMapOptions.mapId(it) }
8586

8687
return MapOptions(googleMapOptions, options.padding)
8788
}

android/src/main/kotlin/com/google/maps/flutter/navigation/messages.g.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,11 @@ data class MapOptionsDto(
594594
val cameraTargetBounds: LatLngBoundsDto? = null,
595595
/** Specifies the padding for the map. */
596596
val padding: MapPaddingDto? = null,
597+
/**
598+
* The map ID for advanced map options eg. cloud-based map styling. This value can only be set on
599+
* map initialization and cannot be changed afterwards.
600+
*/
601+
val mapId: String? = null,
597602
) {
598603
companion object {
599604
fun fromList(pigeonVar_list: List<Any?>): MapOptionsDto {
@@ -611,6 +616,7 @@ data class MapOptionsDto(
611616
val zoomControlsEnabled = pigeonVar_list[11] as Boolean
612617
val cameraTargetBounds = pigeonVar_list[12] as LatLngBoundsDto?
613618
val padding = pigeonVar_list[13] as MapPaddingDto?
619+
val mapId = pigeonVar_list[14] as String?
614620
return MapOptionsDto(
615621
cameraPosition,
616622
mapType,
@@ -626,6 +632,7 @@ data class MapOptionsDto(
626632
zoomControlsEnabled,
627633
cameraTargetBounds,
628634
padding,
635+
mapId,
629636
)
630637
}
631638
}
@@ -646,6 +653,7 @@ data class MapOptionsDto(
646653
zoomControlsEnabled,
647654
cameraTargetBounds,
648655
padding,
656+
mapId,
649657
)
650658
}
651659

example/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ Run the app with the API key as a Dart define.
1717
flutter run --dart-define MAPS_API_KEY=YOUR_API_KEY
1818
```
1919

20+
You can also optionally provide a Map ID with another Dart define:
21+
```bash
22+
flutter run --dart-define MAPS_API_KEY=YOUR_API_KEY --dart-define MAP_ID=YOUR_MAP_ID
23+
```
24+
2025
The example app demonstrates multiple ways to provide the Maps API key for platforms.
2126

2227
### Android specific API key

example/integration_test/t06_map_test.dart

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ import 'package:flutter/material.dart';
2626

2727
import 'shared.dart';
2828

29+
const String testMapId = 'DEMO_MAP_ID';
30+
2931
void main() {
3032
final mapTypeVariants = getMapTypeVariants();
3133
patrol('Test map types', (PatrolIntegrationTester $) async {
@@ -123,6 +125,48 @@ void main() {
123125
expect(await controller.settings.isZoomControlsEnabled(), false);
124126
expect(await controller.settings.isMapToolbarEnabled(), false);
125127
}
128+
129+
// Test that view can be created with a mapID.
130+
// Note: mapID cannot be fetched back from the map, so we only test
131+
// that creation succeeds.
132+
final ControllerCompleter<GoogleMapViewController>
133+
controllerCompleterWithMapId =
134+
ControllerCompleter<GoogleMapViewController>();
135+
136+
switch (mapTypeVariants.currentValue!) {
137+
case TestMapType.mapView:
138+
final Key key = GlobalKey();
139+
await pumpMapView(
140+
$,
141+
GoogleMapsMapView(
142+
key: key,
143+
mapId: testMapId,
144+
onViewCreated: (GoogleMapViewController viewController) {
145+
controllerCompleterWithMapId.complete(viewController);
146+
},
147+
),
148+
);
149+
break;
150+
case TestMapType.navigationView:
151+
final Key key = GlobalKey();
152+
await pumpNavigationView(
153+
$,
154+
GoogleMapsNavigationView(
155+
key: key,
156+
mapId: testMapId,
157+
onViewCreated: (GoogleNavigationViewController viewController) {
158+
controllerCompleterWithMapId.complete(viewController);
159+
},
160+
),
161+
);
162+
break;
163+
}
164+
165+
final GoogleMapViewController controllerWithMapId =
166+
await controllerCompleterWithMapId.future;
167+
168+
// Verify the controller was created successfully
169+
expect(controllerWithMapId, isNotNull);
126170
}, variant: mapTypeVariants);
127171

128172
patrol('Test map UI settings', (PatrolIntegrationTester $) async {

example/ios/RunnerTests/ConvertTests.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,8 @@ class ConvertTests: XCTestCase {
551551
zoomGesturesEnabled: false,
552552
scrollGesturesEnabledDuringRotateOrZoom: false,
553553
mapToolbarEnabled: false,
554-
zoomControlsEnabled: false
554+
zoomControlsEnabled: false,
555+
mapId: "test-map-id"
555556
)
556557

557558
let navigationViewOptions =
@@ -584,6 +585,7 @@ class ConvertTests: XCTestCase {
584585
mapOptions.scrollGesturesEnabledDuringRotateOrZoom,
585586
configuration.scrollGesturesEnabledDuringRotateOrZoom
586587
)
588+
XCTAssertEqual(mapOptions.mapId, configuration.mapId)
587589
}
588590

589591
func testConvertPath() {

example/lib/main.dart

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import 'package:google_navigation_flutter/google_navigation_flutter.dart';
2222
import 'package:permission_handler/permission_handler.dart';
2323
import 'pages/circles.dart';
2424
import 'pages/pages.dart';
25+
import 'utils/utils.dart';
2526
import 'widgets/widgets.dart';
2627

2728
/// The list of pages to show in the Google Maps Navigation demo.
@@ -106,40 +107,60 @@ class _NavigationDemoState extends State<NavigationBody> {
106107
body: SafeArea(
107108
top: false,
108109
minimum: const EdgeInsets.all(8.0),
109-
child: ListView.builder(
110-
itemCount: _allPages.length + 1,
111-
itemBuilder: (_, int index) {
112-
if (index == 0) {
113-
return Card(
114-
child: Container(
115-
padding: const EdgeInsets.symmetric(vertical: 4.0),
116-
alignment: Alignment.center,
117-
child: Column(
118-
children: <Widget>[
119-
Text(
120-
Platform.isIOS
121-
? 'Location ${_locationPermitted ? 'granted' : 'denied'} • Notifications ${_notificationsPermitted ? 'granted' : 'denied'}'
122-
: 'Location ${_locationPermitted ? 'granted' : 'denied'} ',
123-
),
124-
Text('Navigation SDK version: $_navSDKVersion'),
125-
],
126-
),
110+
child: Column(
111+
children: <Widget>[
112+
Card(
113+
child: Container(
114+
padding: const EdgeInsets.symmetric(vertical: 4.0),
115+
alignment: Alignment.center,
116+
child: Column(
117+
children: <Widget>[
118+
Text(
119+
Platform.isIOS
120+
? 'Location ${_locationPermitted ? 'granted' : 'denied'} • Notifications ${_notificationsPermitted ? 'granted' : 'denied'}'
121+
: 'Location ${_locationPermitted ? 'granted' : 'denied'} ',
122+
),
123+
Text('Navigation SDK version: $_navSDKVersion'),
124+
Text(
125+
'Current map ID: ${MapIdManager.instance.mapIdDisplay}',
126+
),
127+
],
127128
),
128-
);
129-
}
130-
return ListTile(
131-
leading: _allPages[index - 1].leading,
132-
title: Text(_allPages[index - 1].title),
133-
onTap: () => _pushPage(context, _allPages[index - 1]),
134-
);
135-
},
129+
),
130+
),
131+
Expanded(
132+
child: Scrollbar(
133+
thumbVisibility: true,
134+
child: ListView.builder(
135+
itemCount: _allPages.length,
136+
itemBuilder: (_, int index) {
137+
return ListTile(
138+
leading: _allPages[index].leading,
139+
title: Text(_allPages[index].title),
140+
onTap: () => _pushPage(context, _allPages[index]),
141+
);
142+
},
143+
),
144+
),
145+
),
146+
Padding(
147+
padding: const EdgeInsets.all(8.0),
148+
child: ElevatedButton(
149+
onPressed:
150+
() => showMapIdDialog(context, () => setState(() {})),
151+
child: const Text('Set Map ID'),
152+
),
153+
),
154+
],
136155
),
137156
),
138157
);
139158
}
140159
}
141160

142161
void main() {
162+
MapIdManager.instance.initialize();
163+
143164
final ElevatedButtonThemeData exampleButtonDefaultTheme =
144165
ElevatedButtonThemeData(
145166
style: ElevatedButton.styleFrom(minimumSize: const Size(160, 36)),

example/lib/pages/map.dart

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ class _MapPageState extends ExamplePageState<BasicMapPage> {
113113
onViewCreated: _onViewCreated,
114114
onMyLocationClicked: _onMyLocationClicked,
115115
onMyLocationButtonClicked: _onMyLocationButtonClicked,
116+
mapId: MapIdManager.instance.mapId,
116117
),
117118
Padding(
118119
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
@@ -165,17 +166,26 @@ class _MapPageState extends ExamplePageState<BasicMapPage> {
165166
children: <Widget>[
166167
ElevatedButton(
167168
style: mapTypeStyle,
168-
onPressed: () => setMapStyleDefault(),
169+
onPressed:
170+
MapIdManager.instance.mapId != null
171+
? null
172+
: () => setMapStyleDefault(),
169173
child: const Text('Default style'),
170174
),
171175
ElevatedButton(
172176
style: mapTypeStyle,
173-
onPressed: () => setMapStyleNight(),
177+
onPressed:
178+
MapIdManager.instance.mapId != null
179+
? null
180+
: () => setMapStyleNight(),
174181
child: const Text('Night style'),
175182
),
176183
ElevatedButton(
177184
style: mapTypeStyle,
178-
onPressed: () => setMapStyleSepia(),
185+
onPressed:
186+
MapIdManager.instance.mapId != null
187+
? null
188+
: () => setMapStyleSepia(),
179189
child: const Text('Sepia style'),
180190
),
181191
],

example/lib/pages/multiple_views.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,10 @@ class _MultiplexState extends ExamplePageState<MultipleMapViewsPage> {
237237
children: <Widget>[
238238
SizedBox(
239239
height: 200,
240-
child: GoogleMapsMapView(onViewCreated: _onViewCreated),
240+
child: GoogleMapsMapView(
241+
onViewCreated: _onViewCreated,
242+
mapId: MapIdManager.instance.mapId,
243+
),
241244
),
242245
const SizedBox(height: 20),
243246
SizedBox(
@@ -251,6 +254,7 @@ class _MultiplexState extends ExamplePageState<MultipleMapViewsPage> {
251254
target: _userLocation!,
252255
zoom: 15,
253256
),
257+
mapId: MapIdManager.instance.mapId,
254258
)
255259
: const Center(
256260
child: Column(

example/lib/pages/navigation.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,6 +1193,7 @@ class _NavigationPageState extends ExamplePageState<NavigationPage> {
11931193
? NavigationUIEnabledPreference.automatic
11941194
: NavigationUIEnabledPreference.disabled,
11951195
initialPadding: const EdgeInsets.all(0),
1196+
mapId: MapIdManager.instance.mapId,
11961197
)
11971198
: const Center(
11981199
child: Column(

0 commit comments

Comments
 (0)