diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md index 7d4206bd8cbd..3648e5a185d8 100644 --- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md @@ -1,3 +1,10 @@ +## 2.19.0 + +* Adds support for tapping points of interest on the map. + On iOS, this requires `google_maps_flutter_ios_sdk9` or + `google_maps_flutter_ios_sdk10` (the default `google_maps_flutter_ios` + package does not receive new features). + ## 2.18.2 * Updates README to indicate that `google_maps_flutter_ios` is a legacy diff --git a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_click.dart b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_click.dart index de3f13912cf7..446c34d3d823 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/lib/map_click.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/lib/map_click.dart @@ -35,6 +35,7 @@ class _MapClickBodyState extends State<_MapClickBody> { GoogleMapController? mapController; LatLng? _lastTap; LatLng? _lastLongPress; + String? _lastPointOfInterestPlaceId; @override Widget build(BuildContext context) { @@ -51,6 +52,11 @@ class _MapClickBodyState extends State<_MapClickBody> { _lastLongPress = pos; }); }, + onPointOfInterestTap: (PointOfInterestId pointOfInterestId) { + setState(() { + _lastPointOfInterestPlaceId = pointOfInterestId.value; + }); + }, ); final columnChildren = [ @@ -73,6 +79,17 @@ class _MapClickBodyState extends State<_MapClickBody> { child: Text(_lastLongPress != null ? 'Long pressed' : '', textAlign: TextAlign.center), ), ); + final lastPointOfInterestTap = + 'Point of interest place ID:\n${_lastPointOfInterestPlaceId ?? ""}'; + columnChildren.add(Center(child: Text(lastPointOfInterestTap, textAlign: TextAlign.center))); + columnChildren.add( + Center( + child: Text( + _lastPointOfInterestPlaceId != null ? 'Point of interest tapped' : '', + textAlign: TextAlign.center, + ), + ), + ); } return Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: columnChildren); } diff --git a/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml index bf46080288cf..c60b7be9ab8e 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/example/pubspec.yaml @@ -18,8 +18,8 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - google_maps_flutter_android: ^2.19.1 - google_maps_flutter_platform_interface: ^2.16.0 + google_maps_flutter_android: ^2.20.0 + google_maps_flutter_platform_interface: ^2.17.0 dev_dependencies: build_runner: ^2.1.10 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 931dd16a7211..37afda8be256 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 @@ -54,6 +54,7 @@ export 'package:google_maps_flutter_platform_interface/google_maps_flutter_platf MinMaxZoomPreference, PatternItem, PinConfig, + PointOfInterestId, Polygon, PolygonId, Polyline, diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart index 5fe33cccc93f..a905472bef91 100644 --- a/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart @@ -111,6 +111,11 @@ class GoogleMapController { .onLongPress(mapId: mapId) .listen((MapLongPressEvent e) => _googleMapState.onLongPress(e.position)), ); + _streamSubscriptions.add( + GoogleMapsFlutterPlatform.instance + .onPointOfInterestTap(mapId: mapId) + .listen((PointOfInterestTapEvent e) => _googleMapState.onPointOfInterestTap(e.value)), + ); _streamSubscriptions.add( GoogleMapsFlutterPlatform.instance .onClusterTap(mapId: mapId) 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 d90b7aa175b4..d32fd169d81e 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 @@ -136,6 +136,7 @@ class GoogleMap extends StatefulWidget { this.onCameraIdle, this.onTap, this.onLongPress, + this.onPointOfInterestTap, this.markerType = GoogleMapMarkerType.marker, this.colorScheme, String? mapId, @@ -300,6 +301,11 @@ class GoogleMap extends StatefulWidget { /// Called every time a [GoogleMap] is long pressed. final ArgumentCallback? onLongPress; + /// Called when a point of interest on the map is tapped. + /// + /// May not be supported on all implementations. + final ArgumentCallback? onPointOfInterestTap; + /// True if a "My Location" layer should be shown on the map. /// /// This layer includes a location indicator at the current device location, @@ -717,6 +723,13 @@ class _GoogleMapState extends State { } } + void onPointOfInterestTap(PointOfInterestId pointOfInterestId) { + final ArgumentCallback? onPointOfInterestTap = widget.onPointOfInterestTap; + if (onPointOfInterestTap != null) { + onPointOfInterestTap(pointOfInterestId); + } + } + void onClusterTap(Cluster cluster) { final ClusterManager? clusterManager = _clusterManagers[cluster.clusterManagerId]; if (clusterManager == null) { diff --git a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml index 102dc53f4ef2..ed0a339dfdc8 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 @@ name: google_maps_flutter description: A Flutter plugin for integrating Google Maps in iOS and Android applications. repository: https://github.com/flutter/packages/tree/main/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.18.2 +version: 2.19.0 environment: sdk: ^3.13.0 @@ -21,10 +21,10 @@ flutter: dependencies: flutter: sdk: flutter - google_maps_flutter_android: ^2.19.1 + google_maps_flutter_android: ^2.20.0 google_maps_flutter_ios: ^2.18.0 - google_maps_flutter_platform_interface: ^2.16.0 - google_maps_flutter_web: ^0.6.3 + google_maps_flutter_platform_interface: ^2.17.0 + google_maps_flutter_web: ^0.6.4 dev_dependencies: flutter_test: diff --git a/packages/google_maps_flutter/google_maps_flutter/test/fake_google_maps_flutter_platform.dart b/packages/google_maps_flutter/google_maps_flutter/test/fake_google_maps_flutter_platform.dart index fae706bdb4ed..ffb6303ee4d3 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/fake_google_maps_flutter_platform.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/fake_google_maps_flutter_platform.dart @@ -227,6 +227,11 @@ class FakeGoogleMapsFlutterPlatform extends GoogleMapsFlutterPlatform { return mapEventStreamController.stream.whereType(); } + @override + Stream onPointOfInterestTap({required int mapId}) { + return mapEventStreamController.stream.whereType(); + } + @override Stream onTap({required int mapId}) { return mapEventStreamController.stream.whereType(); diff --git a/packages/google_maps_flutter/google_maps_flutter/test/google_maps_flutter_export_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/google_maps_flutter_export_test.dart index decbeee5292c..c148561cd6ce 100644 --- a/packages/google_maps_flutter/google_maps_flutter/test/google_maps_flutter_export_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter/test/google_maps_flutter_export_test.dart @@ -50,6 +50,7 @@ void main() { main_file.MinMaxZoomPreference; main_file.PatternItem; main_file.PinConfig; + main_file.PointOfInterestId; main_file.Polygon; main_file.PolygonId; main_file.Polyline; diff --git a/packages/google_maps_flutter/google_maps_flutter/test/point_of_interest_tap_test.dart b/packages/google_maps_flutter/google_maps_flutter/test/point_of_interest_tap_test.dart new file mode 100644 index 000000000000..9451be1825db --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter/test/point_of_interest_tap_test.dart @@ -0,0 +1,51 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +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_google_maps_flutter_platform.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + late FakeGoogleMapsFlutterPlatform platform; + + setUp(() { + platform = FakeGoogleMapsFlutterPlatform(); + GoogleMapsFlutterPlatform.instance = platform; + }); + + testWidgets('onPointOfInterestTap callback receives place ID from platform event', ( + WidgetTester tester, + ) async { + PointOfInterestId? tappedPointOfInterestId; + + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: GoogleMap( + initialCameraPosition: const CameraPosition(target: LatLng(0.0, 0.0)), + onPointOfInterestTap: (PointOfInterestId pointOfInterestId) { + tappedPointOfInterestId = pointOfInterestId; + }, + ), + ), + ); + + await tester.pump(); + + expect(platform.createdIds, isNotEmpty); + final int mapId = platform.createdIds.first; + + platform.mapEventStreamController.add( + PointOfInterestTapEvent(mapId, const PointOfInterestId('place-123')), + ); + + await tester.pump(); + + expect(tappedPointOfInterestId, const PointOfInterestId('place-123')); + }); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_ios/CHANGELOG.md index d3aa13254919..859296c34293 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_ios/CHANGELOG.md @@ -1,5 +1,7 @@ ## NEXT +* Updates README to note that `GoogleMap.onPointOfInterestTap` is not supported; + use an SDK-specific implementation package instead. * Updates minimum supported SDK version to Flutter 3.41/Dart 3.11. ## 2.18.6 diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/README.md b/packages/google_maps_flutter/google_maps_flutter_ios/README.md index d3f8ddf4b65a..2f050e1dbe25 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/README.md +++ b/packages/google_maps_flutter/google_maps_flutter_ios/README.md @@ -7,6 +7,10 @@ application's minimum deployment target. **Note**: This package will not receive new feature updates. All clients are encouraged to adopt one of the [SDK-specific implementations](#alternate-implementations). +For example, `GoogleMap.onPointOfInterestTap` is not supported here; use +[`google_maps_flutter_ios_sdk9`](https://pub.dev/packages/google_maps_flutter_ios_sdk9) +or +[`google_maps_flutter_ios_sdk10`](https://pub.dev/packages/google_maps_flutter_ios_sdk10). ## Usage