Skip to content

Commit 7a78626

Browse files
ditmanEgor
authored and
Egor
committed
[google_maps_flutter + platform] Tweaks to enable a web implementation. (flutter#2903)
This change tweaks slightly the core maps plugin and the platform interface package to make the web implementation possible. The most important changes are two: * The core plugin now passes a constant identifier to the buildView platform call, so the web version can cache effectively the contents of the platform view, so it doesn't repaint. This might go away once Scenelets for web come online. * The platform interface now encodes the (optional) width and height of custom Icons for Markers, so the web can render High DPI assets at the correct size. The rest are some examples to the 'example' app so it can be run on web.
1 parent 13380ef commit 7a78626

File tree

9 files changed

+100
-7
lines changed

9 files changed

+100
-7
lines changed

packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 0.5.29
2+
3+
* Pass a constant `_web_only_mapCreationId` to `platform.buildView`, so web can return a cached widget DOM when flutter attempts to repaint there.
4+
* Modify some examples slightly so they're more web-friendly.
5+
16
## 0.5.28+2
27

38
* Move test introduced in #2449 to its right location.

packages/google_maps_flutter/google_maps_flutter/example/lib/marker_icons.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class MarkerIconsBodyState extends State<MarkerIconsBody> {
7373
Future<void> _createMarkerImageFromAsset(BuildContext context) async {
7474
if (_markerIcon == null) {
7575
final ImageConfiguration imageConfiguration =
76-
createLocalImageConfiguration(context);
76+
createLocalImageConfiguration(context, size: Size.square(48));
7777
BitmapDescriptor.fromAssetImage(
7878
imageConfiguration, 'assets/red_square.png')
7979
.then(_updateBitmap);

packages/google_maps_flutter/google_maps_flutter/example/lib/place_polyline.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44

55
// ignore_for_file: public_member_api_docs
66

7-
import 'dart:io' show Platform;
8-
7+
import 'package:flutter/foundation.dart';
98
import 'package:flutter/material.dart';
109
import 'package:google_maps_flutter/google_maps_flutter.dart';
1110

@@ -202,7 +201,9 @@ class PlacePolylineBodyState extends State<PlacePolylineBody> {
202201

203202
@override
204203
Widget build(BuildContext context) {
205-
final bool iOSorNotSelected = Platform.isIOS || (selectedPolyline == null);
204+
final bool iOSorNotSelected =
205+
(!kIsWeb && defaultTargetPlatform == TargetPlatform.iOS) ||
206+
(selectedPolyline == null);
206207

207208
return Column(
208209
mainAxisAlignment: MainAxisAlignment.spaceEvenly,

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ part of google_maps_flutter;
1010
/// map is created.
1111
typedef void MapCreatedCallback(GoogleMapController controller);
1212

13+
// This counter is used to provide a stable "constant" initialization id
14+
// to the buildView function, so the web implementation can use it as a
15+
// cache key. This needs to be provided from the outside, because web
16+
// views seem to re-render much more often that mobile platform views.
17+
int _webOnlyMapId = 0;
18+
1319
/// A widget which displays a map with data obtained from the Google Maps service.
1420
class GoogleMap extends StatefulWidget {
1521
/// Creates a widget displaying data from Google Maps services.
@@ -205,6 +211,8 @@ class GoogleMap extends StatefulWidget {
205211
}
206212

207213
class _GoogleMapState extends State<GoogleMap> {
214+
final _webOnlyMapCreationId = _webOnlyMapId++;
215+
208216
final Completer<GoogleMapController> _controller =
209217
Completer<GoogleMapController>();
210218

@@ -223,7 +231,9 @@ class _GoogleMapState extends State<GoogleMap> {
223231
'polygonsToAdd': serializePolygonSet(widget.polygons),
224232
'polylinesToAdd': serializePolylineSet(widget.polylines),
225233
'circlesToAdd': serializeCircleSet(widget.circles),
234+
'_webOnlyMapCreationId': _webOnlyMapCreationId,
226235
};
236+
227237
return _googleMapsFlutterPlatform.buildView(
228238
creationParams,
229239
widget.gestureRecognizers,

packages/google_maps_flutter/google_maps_flutter/pubspec.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: google_maps_flutter
22
description: A Flutter plugin for integrating Google Maps in iOS and Android applications.
33
homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter
4-
version: 0.5.28+2
4+
version: 0.5.29
55

66
dependencies:
77
flutter:
@@ -19,6 +19,8 @@ dev_dependencies:
1919
sdk: flutter
2020
test: ^1.6.0
2121
pedantic: ^1.8.0
22+
plugin_platform_interface: ^1.0.2
23+
mockito: ^4.1.1
2224

2325
flutter:
2426
plugin:
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright 2018 The Chromium 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+
import 'package:flutter/widgets.dart';
6+
import 'package:flutter_test/flutter_test.dart';
7+
import 'package:google_maps_flutter/google_maps_flutter.dart';
8+
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
9+
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
10+
import 'package:mockito/mockito.dart';
11+
12+
class MockGoogleMapsFlutterPlatform extends Mock
13+
with MockPlatformInterfaceMixin
14+
implements GoogleMapsFlutterPlatform {}
15+
16+
void main() {
17+
TestWidgetsFlutterBinding.ensureInitialized();
18+
final platform = MockGoogleMapsFlutterPlatform();
19+
20+
setUp(() {
21+
// Use a mock platform so we never need to hit the MethodChannel code.
22+
GoogleMapsFlutterPlatform.instance = platform;
23+
when(platform.buildView(any, any, any)).thenReturn(Container());
24+
});
25+
26+
testWidgets('_webOnlyMapCreationId increments with each GoogleMap widget', (
27+
WidgetTester tester,
28+
) async {
29+
// Inject two map widgets...
30+
await tester.pumpWidget(
31+
Directionality(
32+
textDirection: TextDirection.ltr,
33+
child: Column(
34+
children: const [
35+
GoogleMap(
36+
initialCameraPosition: CameraPosition(
37+
target: LatLng(43.362, -5.849),
38+
),
39+
),
40+
GoogleMap(
41+
initialCameraPosition: CameraPosition(
42+
target: LatLng(47.649, -122.350),
43+
),
44+
),
45+
],
46+
),
47+
),
48+
);
49+
50+
// Verify that each one was created with a different _webOnlyMapCreationId.
51+
verifyInOrder([
52+
platform.buildView(
53+
argThat(containsPair('_webOnlyMapCreationId', 0)),
54+
any,
55+
any,
56+
),
57+
platform.buildView(
58+
argThat(containsPair('_webOnlyMapCreationId', 1)),
59+
any,
60+
any,
61+
),
62+
]);
63+
});
64+
}

packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 1.0.3
2+
3+
* Pass icon width/height if present on `fromAssetImage` BitmapDescriptors (web only)
4+
15
## 1.0.2
26

37
* Update lower bound of dart dependency to 2.1.0.

packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/bitmap.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import 'package:flutter/material.dart'
99
show ImageConfiguration, AssetImage, AssetBundleImageKey;
1010
import 'package:flutter/services.dart' show AssetBundle;
1111

12+
import 'package:flutter/foundation.dart' show kIsWeb;
13+
1214
/// Defines a bitmap image. For a marker, this class can be used to set the
1315
/// image of the marker icon. For a ground overlay, it can be used to set the
1416
/// image to place on the surface of the earth.
@@ -100,6 +102,11 @@ class BitmapDescriptor {
100102
'fromAssetImage',
101103
assetBundleImageKey.name,
102104
assetBundleImageKey.scale,
105+
if (kIsWeb && configuration?.size != null)
106+
[
107+
configuration.size.width,
108+
configuration.size.height,
109+
],
103110
]);
104111
}
105112

packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ description: A common platform interface for the google_maps_flutter plugin.
33
homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter_platform_interface
44
# NOTE: We strongly prefer non-breaking changes, even at the expense of a
55
# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
6-
version: 1.0.2
6+
version: 1.0.3
77

88
dependencies:
99
flutter:
@@ -19,5 +19,5 @@ dev_dependencies:
1919
pedantic: ^1.8.0
2020

2121
environment:
22-
sdk: ">=2.1.0 <3.0.0"
22+
sdk: ">=2.3.0 <3.0.0"
2323
flutter: ">=1.9.1+hotfix.4 <2.0.0"

0 commit comments

Comments
 (0)