Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit 8086f9d

Browse files
committed
[google_maps_flutter] cloud-based map id support
1 parent ca3d569 commit 8086f9d

File tree

37 files changed

+679
-12
lines changed

37 files changed

+679
-12
lines changed

packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
## NEXT
1+
## 2.3.0
22

3+
* Adds implementation for `cloudMapId` parameter to support cloud-based maps styling.
34
* Updates code for new analysis options.
45
* Updates code for `no_leading_underscores_for_local_identifiers` lint.
56

packages/google_maps_flutter/google_maps_flutter/example/integration_test/google_maps_test.dart

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const LatLng _kInitialMapCenter = LatLng(0, 0);
1717
const double _kInitialZoomLevel = 5;
1818
const CameraPosition _kInitialCameraPosition =
1919
CameraPosition(target: _kInitialMapCenter, zoom: _kInitialZoomLevel);
20+
const String _kCloudMapId = '8e0a97af9386fef';
2021

2122
void main() {
2223
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
@@ -1161,6 +1162,32 @@ void main() {
11611162
expect(tileOverlayInfo1, isNull);
11621163
},
11631164
);
1165+
1166+
testWidgets(
1167+
'testCloudMapId',
1168+
(WidgetTester tester) async {
1169+
final Completer<int> mapIdCompleter = Completer<int>();
1170+
final Key key = GlobalKey();
1171+
1172+
await tester.pumpWidget(
1173+
Directionality(
1174+
textDirection: TextDirection.ltr,
1175+
child: GoogleMap(
1176+
key: key,
1177+
initialCameraPosition: _kInitialCameraPosition,
1178+
onMapCreated: (GoogleMapController controller) {
1179+
mapIdCompleter.complete(controller.mapId);
1180+
},
1181+
cloudMapId: _kCloudMapId,
1182+
),
1183+
),
1184+
);
1185+
1186+
// Await mapIdCompleter to finish to make sure map can be created with styledMapId
1187+
// Styled map
1188+
await mapIdCompleter.future;
1189+
},
1190+
);
11641191
}
11651192

11661193
class _DebugTileProvider implements TileProvider {

packages/google_maps_flutter/google_maps_flutter/example/lib/main.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import 'animate_camera.dart';
1010
import 'lite_mode.dart';
1111
import 'map_click.dart';
1212
import 'map_coordinates.dart';
13+
import 'map_map_id.dart';
1314
import 'map_ui.dart';
1415
import 'marker_icons.dart';
1516
import 'move_camera.dart';
@@ -39,6 +40,7 @@ final List<GoogleMapExampleAppPage> _allPages = <GoogleMapExampleAppPage>[
3940
const SnapshotPage(),
4041
const LiteModePage(),
4142
const TileOverlayPage(),
43+
const MapIdPage(),
4244
];
4345

4446
/// MapsDemo is the Main Application.
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// ignore_for_file: public_member_api_docs
6+
7+
import 'dart:async';
8+
import 'dart:io';
9+
10+
import 'package:flutter/material.dart';
11+
import 'package:google_maps_flutter/google_maps_flutter.dart';
12+
import 'package:google_maps_flutter_android/google_maps_flutter_android.dart';
13+
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
14+
import 'page.dart';
15+
16+
class MapIdPage extends GoogleMapExampleAppPage {
17+
const MapIdPage({Key? key})
18+
: super(const Icon(Icons.map), 'Cloud-based maps styling', key: key);
19+
20+
@override
21+
Widget build(BuildContext context) {
22+
return const MapIdBody();
23+
}
24+
}
25+
26+
class MapIdBody extends StatefulWidget {
27+
const MapIdBody({Key? key}) : super(key: key);
28+
29+
@override
30+
State<StatefulWidget> createState() => MapIdBodyState();
31+
}
32+
33+
const LatLng _kMapCenter = LatLng(52.4478, -3.5402);
34+
35+
class MapIdBodyState extends State<MapIdBody> {
36+
GoogleMapController? controller;
37+
38+
Key _key = const Key('mapId#');
39+
String? _mapId;
40+
final TextEditingController _mapIdController = TextEditingController();
41+
AndroidMapRenderer? _initializedRenderer;
42+
43+
@override
44+
void initState() {
45+
_initializeMapRenderer()
46+
.then<void>((AndroidMapRenderer? initializedRenderer) => setState(() {
47+
_initializedRenderer = initializedRenderer;
48+
}));
49+
super.initState();
50+
}
51+
52+
String _getInitializedsRendererType() {
53+
switch (_initializedRenderer) {
54+
case AndroidMapRenderer.latest:
55+
return 'latest';
56+
case AndroidMapRenderer.legacy:
57+
return 'legacy';
58+
default:
59+
return 'initializing';
60+
}
61+
}
62+
63+
void _setMapId() {
64+
setState(() {
65+
_mapId = _mapIdController.text;
66+
67+
// Change key to initialize new map instance for new mapId.
68+
_key = Key(_mapId ?? 'mapId#');
69+
});
70+
}
71+
72+
@override
73+
Widget build(BuildContext context) {
74+
final GoogleMap googleMap = GoogleMap(
75+
onMapCreated: _onMapCreated,
76+
initialCameraPosition: const CameraPosition(
77+
target: _kMapCenter,
78+
zoom: 7.0,
79+
),
80+
key: _key,
81+
cloudMapId: _mapId);
82+
83+
final List<Widget> columnChildren = <Widget>[
84+
Padding(
85+
padding: const EdgeInsets.all(10.0),
86+
child: Center(
87+
child: SizedBox(
88+
width: 300.0,
89+
height: 200.0,
90+
child: googleMap,
91+
),
92+
),
93+
),
94+
Padding(
95+
padding: const EdgeInsets.all(10.0),
96+
child: TextField(
97+
controller: _mapIdController,
98+
decoration: const InputDecoration(
99+
hintText: 'Map Id',
100+
),
101+
)),
102+
Padding(
103+
padding: const EdgeInsets.all(10.0),
104+
child: ElevatedButton(
105+
onPressed: () => _setMapId(),
106+
child: const Text(
107+
'Press to use specified map Id',
108+
),
109+
)),
110+
if (Platform.isAndroid)
111+
Padding(
112+
padding: const EdgeInsets.all(10.0),
113+
child: Text(
114+
'On Android, Cloud-based maps styling only works with "latest" renderer.\n\n'
115+
'Current initialized renderer is "${_getInitializedsRendererType()}".'),
116+
),
117+
if (Platform.isIOS)
118+
const Padding(
119+
padding: EdgeInsets.all(10.0),
120+
child:
121+
Text('On iOS, cloud based map styling works only if iOS platform '
122+
'version 12 or above is targeted in project Podfile. '
123+
"Run command 'pod update GoogleMaps' to update plugin"),
124+
)
125+
];
126+
127+
return Column(
128+
crossAxisAlignment: CrossAxisAlignment.stretch,
129+
children: columnChildren,
130+
);
131+
}
132+
133+
@override
134+
void dispose() {
135+
_mapIdController.dispose();
136+
super.dispose();
137+
}
138+
139+
void _onMapCreated(GoogleMapController controllerParam) {
140+
setState(() {
141+
controller = controllerParam;
142+
});
143+
}
144+
}
145+
146+
Completer<AndroidMapRenderer?>? _initializedRendererCompleter;
147+
Future<AndroidMapRenderer?> _initializeMapRenderer() async {
148+
if (_initializedRendererCompleter != null) {
149+
return _initializedRendererCompleter!.future;
150+
}
151+
152+
_initializedRendererCompleter = Completer<AndroidMapRenderer?>();
153+
final GoogleMapsFlutterPlatform mapsImplementation =
154+
GoogleMapsFlutterPlatform.instance;
155+
if (mapsImplementation is GoogleMapsFlutterAndroid) {
156+
mapsImplementation.initializeWithRenderer(AndroidMapRenderer.latest).then(
157+
(AndroidMapRenderer initializedRenderer) =>
158+
_initializedRendererCompleter!.complete(initializedRenderer));
159+
} else {
160+
_initializedRendererCompleter!.complete(null);
161+
}
162+
163+
return _initializedRendererCompleter!.future;
164+
}

packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ dependencies:
1919
# the parent directory to use the current plugin's version.
2020
path: ../
2121
google_maps_flutter_android: ^2.1.10
22+
google_maps_flutter_ios: ^2.1.10
2223
google_maps_flutter_platform_interface: ^2.2.1
2324

2425
dev_dependencies:
@@ -34,3 +35,15 @@ flutter:
3435
uses-material-design: true
3536
assets:
3637
- assets/
38+
39+
40+
# FOR TESTING ONLY. DO NOT MERGE.
41+
dependency_overrides:
42+
google_maps_flutter:
43+
path: ../../../google_maps_flutter/google_maps_flutter
44+
google_maps_flutter_android:
45+
path: ../../../google_maps_flutter/google_maps_flutter_android
46+
google_maps_flutter_ios:
47+
path: ../../../google_maps_flutter/google_maps_flutter_ios
48+
google_maps_flutter_platform_interface:
49+
path: ../../../google_maps_flutter/google_maps_flutter_platform_interface

packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ class GoogleMap extends StatefulWidget {
123123
this.onCameraIdle,
124124
this.onTap,
125125
this.onLongPress,
126+
this.cloudMapId,
126127
}) : assert(initialCameraPosition != null),
127128
super(key: key);
128129

@@ -283,6 +284,12 @@ class GoogleMap extends StatefulWidget {
283284
/// were not claimed by any other gesture recognizer.
284285
final Set<Factory<OneSequenceGestureRecognizer>> gestureRecognizers;
285286

287+
/// Identifier that's associated with a specific cloud bases map style.
288+
///
289+
/// See https://developers.google.com/maps/documentation/get-map-id
290+
/// for more details.
291+
final String? cloudMapId;
292+
286293
/// Creates a [State] for this [GoogleMap].
287294
@override
288295
State createState() => _GoogleMapState();
@@ -553,5 +560,6 @@ MapConfiguration _configurationFromMapWidget(GoogleMap map) {
553560
indoorViewEnabled: map.indoorViewEnabled,
554561
trafficEnabled: map.trafficEnabled,
555562
buildingsEnabled: map.buildingsEnabled,
563+
cloudMapId: map.cloudMapId,
556564
);
557565
}

packages/google_maps_flutter/google_maps_flutter/pubspec.yaml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: google_maps_flutter
22
description: A Flutter plugin for integrating Google Maps in iOS and Android applications.
33
repository: https://github.com/flutter/plugins/tree/main/packages/google_maps_flutter/google_maps_flutter
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22
5-
version: 2.2.1
5+
version: 2.3.0
66

77
environment:
88
sdk: ">=2.14.0 <3.0.0"
@@ -20,11 +20,20 @@ dependencies:
2020
flutter:
2121
sdk: flutter
2222
google_maps_flutter_android: ^2.1.10
23-
google_maps_flutter_ios: ^2.1.10
2423
google_maps_flutter_platform_interface: ^2.2.1
2524

2625
dev_dependencies:
2726
flutter_test:
2827
sdk: flutter
2928
plugin_platform_interface: ^2.0.0
3029
stream_transform: ^2.0.0
30+
31+
32+
# FOR TESTING ONLY. DO NOT MERGE.
33+
dependency_overrides:
34+
google_maps_flutter_android:
35+
path: ../../google_maps_flutter/google_maps_flutter_android
36+
google_maps_flutter_ios:
37+
path: ../../google_maps_flutter/google_maps_flutter_ios
38+
google_maps_flutter_platform_interface:
39+
path: ../../google_maps_flutter/google_maps_flutter_platform_interface

packages/google_maps_flutter/google_maps_flutter_android/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 2.5.0
2+
3+
* Adds implementation for `cloudMapId` parameter to support cloud-based map styling.
4+
15
## 2.4.0
26

37
* Adds the ability to request a specific map renderer.

packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,10 @@ static void interpretGoogleMapOptions(Object o, GoogleMapOptionsSink sink) {
376376
if (buildingsEnabled != null) {
377377
sink.setBuildingsEnabled(toBoolean(buildingsEnabled));
378378
}
379+
final Object cloudMapId = data.get("cloudMapId");
380+
if (buildingsEnabled != null) {
381+
sink.setMapId(toString(cloudMapId));
382+
}
379383
}
380384

381385
/** Returns the dartMarkerId of the interpreted marker. */

packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,4 +174,9 @@ public void setInitialCircles(Object initialCircles) {
174174
public void setInitialTileOverlays(List<Map<String, ?>> initialTileOverlays) {
175175
this.initialTileOverlays = initialTileOverlays;
176176
}
177+
178+
@Override
179+
public void setMapId(String mapId) {
180+
options.mapId(mapId);
181+
}
177182
}

0 commit comments

Comments
 (0)