Support Hybrid Composition through the GoogleMaps Widget (#4082)
diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md
index 0c95abd..4bc4ce3 100644
--- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md
+++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 2.1.0
+
+* Add iOS unit and UI integration test targets.
+* Provide access to Hybrid Composition on Android through the `GoogleMap` widget.
+
## 2.0.11
* Add additional marker drag events.
diff --git a/packages/google_maps_flutter/google_maps_flutter/README.md b/packages/google_maps_flutter/google_maps_flutter/README.md
index 99c04f3..038126f 100644
--- a/packages/google_maps_flutter/google_maps_flutter/README.md
+++ b/packages/google_maps_flutter/google_maps_flutter/README.md
@@ -46,6 +46,18 @@
android:value="YOUR KEY HERE"/>
```
+#### Hybrid Composition
+
+To use [Hybrid Composition](https://flutter.dev/docs/development/platform-integration/platform-views)
+to render the `GoogleMap` widget on Android, set `AndroidGoogleMapsFlutter.useAndroidViewSurface` to
+true.
+
+```dart
+if (defaultTargetPlatform == TargetPlatform.android) {
+ AndroidGoogleMapsFlutter.useAndroidViewSurface = true;
+}
+```
+
### iOS
This plugin requires iOS 9.0 or higher. To set up, specify your API key in the application delegate `ios/Runner/AppDelegate.m`:
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 15b14db..f67e4ff 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
@@ -4,7 +4,10 @@
// ignore_for_file: public_member_api_docs
+import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
+
+import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:google_maps_flutter_example/lite_mode.dart';
import 'animate_camera.dart';
import 'map_click.dart';
@@ -66,5 +69,8 @@
}
void main() {
+ if (defaultTargetPlatform == TargetPlatform.android) {
+ AndroidGoogleMapsFlutter.useAndroidViewSurface = true;
+ }
runApp(MaterialApp(home: MapsDemo()));
}
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 b4ffd22..b153832 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
@@ -38,6 +38,44 @@
}
}
+/// Android specific settings for [GoogleMap].
+class AndroidGoogleMapsFlutter {
+ /// Whether to render [GoogleMap] with a [AndroidViewSurface] to build the Google Maps widget.
+ ///
+ /// This implementation uses hybrid composition to render the Google Maps
+ /// Widget on Android. This comes at the cost of some performance on Android
+ /// versions below 10. See
+ /// https://flutter.dev/docs/development/platform-integration/platform-views#performance for more
+ /// information.
+ ///
+ /// Defaults to false.
+ static bool get useAndroidViewSurface {
+ final GoogleMapsFlutterPlatform platform =
+ GoogleMapsFlutterPlatform.instance;
+ if (platform is MethodChannelGoogleMapsFlutter) {
+ return platform.useAndroidViewSurface;
+ }
+ return false;
+ }
+
+ /// Set whether to render [GoogleMap] with a [AndroidViewSurface] to build the Google Maps widget.
+ ///
+ /// This implementation uses hybrid composition to render the Google Maps
+ /// Widget on Android. This comes at the cost of some performance on Android
+ /// versions below 10. See
+ /// https://flutter.dev/docs/development/platform-integration/platform-views#performance for more
+ /// information.
+ ///
+ /// Defaults to false.
+ static set useAndroidViewSurface(bool useAndroidViewSurface) {
+ final GoogleMapsFlutterPlatform platform =
+ GoogleMapsFlutterPlatform.instance;
+ if (platform is MethodChannelGoogleMapsFlutter) {
+ platform.useAndroidViewSurface = useAndroidViewSurface;
+ }
+ }
+}
+
/// A widget which displays a map with data obtained from the Google Maps service.
class GoogleMap extends StatefulWidget {
/// Creates a widget displaying data from Google Maps services.
@@ -61,6 +99,7 @@
this.tiltGesturesEnabled = true,
this.myLocationEnabled = false,
this.myLocationButtonEnabled = true,
+ this.layoutDirection,
/// If no padding is specified default padding will be 0.
this.padding = const EdgeInsets.all(0),
@@ -100,6 +139,12 @@
/// Type of map tiles to be rendered.
final MapType mapType;
+ /// The layout direction to use for the embedded view.
+ ///
+ /// If this is null, the ambient [Directionality] is used instead. If there is
+ /// no ambient [Directionality], [TextDirection.ltr] is used.
+ final TextDirection? layoutDirection;
+
/// Preferred bounds for the camera zoom level.
///
/// Actual bounds depend on map data and device.
@@ -250,9 +295,12 @@
@override
Widget build(BuildContext context) {
- return GoogleMapsFlutterPlatform.instance.buildView(
+ return GoogleMapsFlutterPlatform.instance.buildViewWithTextDirection(
_mapId,
onPlatformViewCreated,
+ textDirection: widget.layoutDirection ??
+ Directionality.maybeOf(context) ??
+ TextDirection.ltr,
initialCameraPosition: widget.initialCameraPosition,
markers: widget.markers,
polygons: widget.polygons,
diff --git a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml
index 61ac88a..dae5a28 100644
--- a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml
+++ b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml
@@ -2,7 +2,7 @@
description: A Flutter plugin for integrating Google Maps in iOS and Android applications.
repository: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22
-version: 2.0.11
+version: 2.1.0
environment:
sdk: ">=2.14.0 <3.0.0"
diff --git a/packages/google_maps_flutter/google_maps_flutter/test/google_map_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/google_map_test.dart
index d1ec87a..003ae06 100644
--- a/packages/google_maps_flutter/google_maps_flutter/test/google_map_test.dart
+++ b/packages/google_maps_flutter/google_maps_flutter/test/google_map_test.dart
@@ -6,6 +6,7 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
+import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
import 'fake_maps_controllers.dart';
@@ -604,17 +605,21 @@
},
);
- // TODO(bparrishMines): Uncomment once https://github.com/flutter/plugins/pull/4017 has landed.
- // testWidgets('Use AndroidViewSurface on Android', (WidgetTester tester) async {
- // await tester.pumpWidget(
- // const Directionality(
- // textDirection: TextDirection.ltr,
- // child: GoogleMap(
- // initialCameraPosition: CameraPosition(target: LatLng(10.0, 15.0)),
- // ),
- // ),
- // );
- //
- // expect(find.byType(AndroidViewSurface), findsOneWidget);
- // });
+ testWidgets('Use PlatformViewLink on Android', (WidgetTester tester) async {
+ final MethodChannelGoogleMapsFlutter platform =
+ GoogleMapsFlutterPlatform.instance as MethodChannelGoogleMapsFlutter;
+ platform.useAndroidViewSurface = true;
+
+ await tester.pumpWidget(
+ const Directionality(
+ textDirection: TextDirection.ltr,
+ child: GoogleMap(
+ initialCameraPosition: CameraPosition(target: LatLng(10.0, 15.0)),
+ ),
+ ),
+ );
+
+ expect(find.byType(PlatformViewLink), findsOneWidget);
+ platform.useAndroidViewSurface = false;
+ });
}