diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md index df4d9162be7e..66ca6fed5689 100644 --- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.28 + +* Android: Add liteModeEnabled option. + ## 0.5.27+3 * iOS: Update the gesture recognizer blocking policy to "WaitUntilTouchesEnded", which fixes the camera idle callback not triggered issue. diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java index b671d994b6f9..5ef7b26a4a2c 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java @@ -316,6 +316,10 @@ static void interpretGoogleMapOptions(Object o, GoogleMapOptionsSink sink) { if (zoomGesturesEnabled != null) { sink.setZoomGesturesEnabled(toBoolean(zoomGesturesEnabled)); } + final Object liteModeEnabled = data.get("liteModeEnabled"); + if (liteModeEnabled != null) { + sink.setLiteModeEnabled(toBoolean(liteModeEnabled)); + } final Object myLocationEnabled = data.get("myLocationEnabled"); if (myLocationEnabled != null) { sink.setMyLocationEnabled(toBoolean(myLocationEnabled)); diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java index af42aa901379..97af63c9f63b 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java @@ -128,6 +128,11 @@ public void setZoomGesturesEnabled(boolean zoomGesturesEnabled) { options.zoomGesturesEnabled(zoomGesturesEnabled); } + @Override + public void setLiteModeEnabled(boolean liteModeEnabled) { + options.liteMode(liteModeEnabled); + } + @Override public void setIndoorEnabled(boolean indoorEnabled) { this.indoorEnabled = indoorEnabled; diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java index 6f59aa63688e..40cce4978a19 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java @@ -70,6 +70,7 @@ final class GoogleMapController private final int id; private final AtomicInteger activityState; private final MethodChannel methodChannel; + private final GoogleMapOptions options; private final MapView mapView; private GoogleMap googleMap; private boolean trackCameraPosition = false; @@ -111,6 +112,7 @@ final class GoogleMapController this.id = id; this.context = context; this.activityState = activityState; + this.options = options; this.mapView = new MapView(context, options); this.density = context.getResources().getDisplayMetrics().density; methodChannel = new MethodChannel(binaryMessenger, "plugins.flutter.io/google_maps_" + id); @@ -383,6 +385,11 @@ public void onSnapshotReady(Bitmap bitmap) { result.success(googleMap.getUiSettings().isZoomGesturesEnabled()); break; } + case "map#isLiteModeEnabled": + { + result.success(options.getLiteMode()); + break; + } case "map#isZoomControlsEnabled": { result.success(googleMap.getUiSettings().isZoomControlsEnabled()); @@ -749,6 +756,12 @@ public void setZoomGesturesEnabled(boolean zoomGesturesEnabled) { googleMap.getUiSettings().setZoomGesturesEnabled(zoomGesturesEnabled); } + /** This call will have no effect on already created map */ + @Override + public void setLiteModeEnabled(boolean liteModeEnabled) { + options.liteMode(liteModeEnabled); + } + @Override public void setMyLocationEnabled(boolean myLocationEnabled) { if (this.myLocationEnabled == myLocationEnabled) { diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java index efae01510537..9e6fa2a27236 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java @@ -30,6 +30,8 @@ interface GoogleMapOptionsSink { void setZoomGesturesEnabled(boolean zoomGesturesEnabled); + void setLiteModeEnabled(boolean liteModeEnabled); + void setMyLocationEnabled(boolean myLocationEnabled); void setZoomControlsEnabled(boolean zoomControlsEnabled); diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/lite_mode.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/lite_mode.dart new file mode 100644 index 000000000000..7c814f31a660 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/lite_mode.dart @@ -0,0 +1,45 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// ignore_for_file: public_member_api_docs + +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'page.dart'; + +const CameraPosition _kInitialPosition = + CameraPosition(target: LatLng(-33.852, 151.211), zoom: 11.0); + +class LiteModePage extends GoogleMapExampleAppPage { + LiteModePage() : super(const Icon(Icons.map), 'Lite mode'); + + @override + Widget build(BuildContext context) { + return const _LiteModeBody(); + } +} + +class _LiteModeBody extends StatelessWidget { + const _LiteModeBody(); + + @override + Widget build(BuildContext context) { + return Card( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 30.0), + child: Center( + child: SizedBox( + width: 300.0, + height: 300.0, + child: GoogleMap( + initialCameraPosition: _kInitialPosition, + liteModeEnabled: true, + ), + ), + ), + ), + ); + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/main.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/main.dart index 95d8c4503404..13763edb8216 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/main.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/main.dart @@ -5,6 +5,7 @@ // ignore_for_file: public_member_api_docs import 'package:flutter/material.dart'; +import 'package:google_maps_flutter_example/lite_mode.dart'; import 'animate_camera.dart'; import 'map_click.dart'; import 'map_coordinates.dart'; @@ -34,6 +35,7 @@ final List _allPages = [ PlaceCirclePage(), PaddingPage(), SnapshotPage(), + LiteModePage(), ]; class MapsDemo extends StatelessWidget { diff --git a/packages/google_maps_flutter/google_maps_flutter/example/test_driver/google_map_inspector.dart b/packages/google_maps_flutter/google_maps_flutter/example/test_driver/google_map_inspector.dart index 3583d4fd5b71..2fcfec15713a 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/test_driver/google_map_inspector.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/test_driver/google_map_inspector.dart @@ -45,6 +45,10 @@ class GoogleMapInspector { return await _channel.invokeMethod('map#isZoomControlsEnabled'); } + Future isLiteModeEnabled() async { + return await _channel.invokeMethod('map#isLiteModeEnabled'); + } + Future isRotateGesturesEnabled() async { return await _channel.invokeMethod('map#isRotateGesturesEnabled'); } diff --git a/packages/google_maps_flutter/google_maps_flutter/example/test_driver/google_maps_e2e.dart b/packages/google_maps_flutter/google_maps_flutter/example/test_driver/google_maps_e2e.dart index 9620d6067c65..c47862b2b4d1 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/test_driver/google_maps_e2e.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/test_driver/google_maps_e2e.dart @@ -263,6 +263,46 @@ void main() { } }); + testWidgets('testLiteModeEnabled', (WidgetTester tester) async { + final Key key = GlobalKey(); + final Completer inspectorCompleter = + Completer(); + + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: GoogleMap( + key: key, + initialCameraPosition: _kInitialCameraPosition, + liteModeEnabled: false, + onMapCreated: (GoogleMapController controller) { + final GoogleMapInspector inspector = + // ignore: invalid_use_of_visible_for_testing_member + GoogleMapInspector(controller.channel); + inspectorCompleter.complete(inspector); + }, + ), + )); + + final GoogleMapInspector inspector = await inspectorCompleter.future; + bool liteModeEnabled = await inspector.isLiteModeEnabled(); + expect(liteModeEnabled, false); + + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: GoogleMap( + key: key, + initialCameraPosition: _kInitialCameraPosition, + liteModeEnabled: true, + onMapCreated: (GoogleMapController controller) { + fail("OnMapCreated should get called only once."); + }, + ), + )); + + liteModeEnabled = await inspector.isLiteModeEnabled(); + expect(liteModeEnabled, true); + }, skip: !Platform.isAndroid); + testWidgets('testRotateGesturesEnabled', (WidgetTester tester) async { final Key key = GlobalKey(); final Completer inspectorCompleter = diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart b/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart index a17b30ca6226..b879f3d302cf 100644 --- a/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart +++ b/packages/google_maps_flutter/google_maps_flutter/lib/google_maps_flutter.dart @@ -5,6 +5,7 @@ library google_maps_flutter; import 'dart:async'; +import 'dart:io'; import 'dart:typed_data'; import 'dart:ui'; diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart index ecd1a708e724..a45a1c8e3fe4 100644 --- a/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart +++ b/packages/google_maps_flutter/google_maps_flutter/lib/src/google_map.dart @@ -29,6 +29,7 @@ class GoogleMap extends StatefulWidget { this.scrollGesturesEnabled = true, this.zoomControlsEnabled = true, this.zoomGesturesEnabled = true, + this.liteModeEnabled = false, this.tiltGesturesEnabled = true, this.myLocationEnabled = false, this.myLocationButtonEnabled = true, @@ -90,6 +91,11 @@ class GoogleMap extends StatefulWidget { /// True if the map view should respond to zoom gestures. final bool zoomGesturesEnabled; + /// True if the map view should be in lite mode. Android only. + /// + /// See https://developers.google.com/maps/documentation/android-sdk/lite#overview_of_lite_mode for more details. + final bool liteModeEnabled; + /// True if the map view should respond to tilt gestures. final bool tiltGesturesEnabled; @@ -372,13 +378,18 @@ class _GoogleMapOptions { this.trackCameraPosition, this.zoomControlsEnabled, this.zoomGesturesEnabled, + this.liteModeEnabled, this.myLocationEnabled, this.myLocationButtonEnabled, this.padding, this.indoorViewEnabled, this.trafficEnabled, this.buildingsEnabled, - }); + }) { + assert(liteModeEnabled == null || + !liteModeEnabled || + (liteModeEnabled && Platform.isAndroid)); + } static _GoogleMapOptions fromWidget(GoogleMap map) { return _GoogleMapOptions( @@ -393,6 +404,7 @@ class _GoogleMapOptions { trackCameraPosition: map.onCameraMove != null, zoomControlsEnabled: map.zoomControlsEnabled, zoomGesturesEnabled: map.zoomGesturesEnabled, + liteModeEnabled: map.liteModeEnabled, myLocationEnabled: map.myLocationEnabled, myLocationButtonEnabled: map.myLocationButtonEnabled, padding: map.padding, @@ -424,6 +436,8 @@ class _GoogleMapOptions { final bool zoomGesturesEnabled; + final bool liteModeEnabled; + final bool myLocationEnabled; final bool myLocationButtonEnabled; @@ -455,6 +469,7 @@ class _GoogleMapOptions { addIfNonNull('tiltGesturesEnabled', tiltGesturesEnabled); addIfNonNull('zoomControlsEnabled', zoomControlsEnabled); addIfNonNull('zoomGesturesEnabled', zoomGesturesEnabled); + addIfNonNull('liteModeEnabled', liteModeEnabled); addIfNonNull('trackCameraPosition', trackCameraPosition); addIfNonNull('myLocationEnabled', myLocationEnabled); addIfNonNull('myLocationButtonEnabled', myLocationButtonEnabled); diff --git a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml index cf4b869c1a96..4b302266fdae 100644 --- a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml @@ -1,7 +1,7 @@ name: google_maps_flutter description: A Flutter plugin for integrating Google Maps in iOS and Android applications. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter -version: 0.5.27+3 +version: 0.5.28 dependencies: flutter: diff --git a/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart b/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart index 71741c57057b..adca8b4c2a0e 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/fake_maps_controllers.dart @@ -45,6 +45,8 @@ class FakePlatformGoogleMap { bool zoomControlsEnabled; + bool liteModeEnabled; + bool trackCameraPosition; bool myLocationEnabled; @@ -356,6 +358,9 @@ class FakePlatformGoogleMap { if (options.containsKey('zoomControlsEnabled')) { zoomControlsEnabled = options['zoomControlsEnabled']; } + if (options.containsKey('liteModeEnabled')) { + liteModeEnabled = options['liteModeEnabled']; + } if (options.containsKey('myLocationEnabled')) { myLocationEnabled = options['myLocationEnabled']; } diff --git a/packages/google_maps_flutter/test/android_google_map_test.dart b/packages/google_maps_flutter/test/android_google_map_test.dart new file mode 100644 index 000000000000..194efe9a66f0 --- /dev/null +++ b/packages/google_maps_flutter/test/android_google_map_test.dart @@ -0,0 +1,56 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +@TestOn('android') +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; + +import 'fake_maps_controllers.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + final FakePlatformViewsController fakePlatformViewsController = + FakePlatformViewsController(); + + setUpAll(() { + SystemChannels.platform_views.setMockMethodCallHandler( + fakePlatformViewsController.fakePlatformViewsMethodHandler); + }); + + setUp(() { + fakePlatformViewsController.reset(); + }); + + testWidgets('Can update liteModeEnabled', (WidgetTester tester) async { + await tester.pumpWidget( + const Directionality( + textDirection: TextDirection.ltr, + child: GoogleMap( + initialCameraPosition: CameraPosition(target: LatLng(10.0, 15.0)), + liteModeEnabled: false, + ), + ), + ); + + final FakePlatformGoogleMap platformGoogleMap = + fakePlatformViewsController.lastCreatedView; + + expect(platformGoogleMap.liteModeEnabled, false); + + await tester.pumpWidget( + const Directionality( + textDirection: TextDirection.ltr, + child: GoogleMap( + initialCameraPosition: CameraPosition(target: LatLng(10.0, 15.0)), + liteModeEnabled: true, + ), + ), + ); + + expect(platformGoogleMap.liteModeEnabled, true); + }); +}