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

Support Hybrid Composition on Android #4017

Merged
merged 16 commits into from
Jun 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -587,4 +587,34 @@ void main() {

expect(platformGoogleMap.buildingsEnabled, true);
});

testWidgets(
'Default Android widget is AndroidView',
(WidgetTester tester) async {
await tester.pumpWidget(
const Directionality(
textDirection: TextDirection.ltr,
child: GoogleMap(
initialCameraPosition: CameraPosition(target: LatLng(10.0, 15.0)),
),
),
);

expect(find.byType(AndroidView), findsOneWidget);
},
);

// TODO(bparrishMines): Uncomment once https://github.com/flutter/plugins/pull/4017 has landed.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it required in this order?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests for the widget are in google_maps_flutter, but the changes to the code are in google_maps_flutter_platform_interface. However, google_maps_flutter pulls the latest version of the platform interface from pub.

// 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);
// });
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 2.1.0

* Add support for Hybrid Composition when building the Google Maps widget on Android. Set
`MethodChannelGoogleMapsFlutter.useAndroidViewSurface` to `true` to build with Hybrid Composition.

## 2.0.4

* Preserve the `TileProvider` when copying `TileOverlay`, fixing a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

export 'src/method_channel/method_channel_google_maps_flutter.dart'
show MethodChannelGoogleMapsFlutter;
export 'src/platform_interface/google_maps_flutter_platform.dart';
export 'src/types/types.dart';
export 'src/events/map_event.dart';
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
import 'package:stream_transform/stream_transform.dart';
Expand Down Expand Up @@ -441,6 +442,98 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform {
return channel(mapId).invokeMethod<Uint8List>('map#takeSnapshot');
}

/// Set [GoogleMapsFlutterPlatform] to use [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.
///
/// If set to true, the google map widget should be built with
/// [buildViewWithTextDirection] instead of [buildView].
///
/// Defaults to false.
bool useAndroidViewSurface = false;

/// Returns a widget displaying the map view.
///
/// This method includes a parameter for platforms that require a text
/// direction. For example, this should be used when using hybrid composition
/// on Android.
Widget buildViewWithTextDirection(
int creationId,
PlatformViewCreatedCallback onPlatformViewCreated, {
required CameraPosition initialCameraPosition,
required TextDirection textDirection,
Set<Marker> markers = const <Marker>{},
Set<Polygon> polygons = const <Polygon>{},
Set<Polyline> polylines = const <Polyline>{},
Set<Circle> circles = const <Circle>{},
Set<TileOverlay> tileOverlays = const <TileOverlay>{},
Set<Factory<OneSequenceGestureRecognizer>>? gestureRecognizers,
Map<String, dynamic> mapOptions = const <String, dynamic>{},
}) {
if (defaultTargetPlatform == TargetPlatform.android &&
useAndroidViewSurface) {
final Map<String, dynamic> creationParams = <String, dynamic>{
'initialCameraPosition': initialCameraPosition.toMap(),
'options': mapOptions,
'markersToAdd': serializeMarkerSet(markers),
'polygonsToAdd': serializePolygonSet(polygons),
'polylinesToAdd': serializePolylineSet(polylines),
'circlesToAdd': serializeCircleSet(circles),
'tileOverlaysToAdd': serializeTileOverlaySet(tileOverlays),
};
return PlatformViewLink(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this snippet of creating the platform view looks good to me, i'll still defer to @blasten to confirm.

viewType: 'plugins.flutter.io/google_maps',
surfaceFactory: (
BuildContext context,
PlatformViewController controller,
) {
return AndroidViewSurface(
controller: controller as AndroidViewController,
gestureRecognizers: gestureRecognizers ??
const <Factory<OneSequenceGestureRecognizer>>{},
hitTestBehavior: PlatformViewHitTestBehavior.opaque,
);
},
onCreatePlatformView: (PlatformViewCreationParams params) {
final SurfaceAndroidViewController controller =
PlatformViewsService.initSurfaceAndroidView(
id: params.id,
viewType: 'plugins.flutter.io/google_maps',
layoutDirection: textDirection,
creationParams: creationParams,
creationParamsCodec: const StandardMessageCodec(),
onFocus: () => params.onFocusChanged(true),
);
controller.addOnPlatformViewCreatedListener(
params.onPlatformViewCreated,
);
controller.addOnPlatformViewCreatedListener(
onPlatformViewCreated,
);

controller.create();
return controller;
},
);
}
return buildView(
creationId,
onPlatformViewCreated,
initialCameraPosition: initialCameraPosition,
markers: markers,
polygons: polygons,
polylines: polylines,
circles: circles,
tileOverlays: tileOverlays,
gestureRecognizers: gestureRecognizers,
mapOptions: mapOptions,
);
}

@override
Widget buildView(
int creationId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ repository: https://github.com/flutter/plugins/tree/master/packages/google_maps_
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22
# NOTE: We strongly prefer non-breaking changes, even at the expense of a
# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
version: 2.0.4
version: 2.1.0

environment:
sdk: '>=2.12.0 <3.0.0'
Expand Down