Skip to content
Draft
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
4 changes: 4 additions & 0 deletions packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.18.0

* Adds support for tapping points of interest on the map.

## 2.17.1

* Updates README to link to implementation packages for platform-specific
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class _MapClickBodyState extends State<_MapClickBody> {
GoogleMapController? mapController;
LatLng? _lastTap;
LatLng? _lastLongPress;
String? _lastPoiPlaceId;

@override
Widget build(BuildContext context) {
Expand All @@ -51,6 +52,11 @@ class _MapClickBodyState extends State<_MapClickBody> {
_lastLongPress = pos;
});
},
onPointOfInterestTap: (PointOfInterestId pointOfInterestId) {
setState(() {
_lastPoiPlaceId = pointOfInterestId.value;
});
},
);

final columnChildren = <Widget>[
Expand All @@ -73,6 +79,16 @@ class _MapClickBodyState extends State<_MapClickBody> {
child: Text(_lastLongPress != null ? 'Long pressed' : '', textAlign: TextAlign.center),
),
);
final lastPoiTap = 'Point of interest place ID:\n${_lastPoiPlaceId ?? ""}\n';
columnChildren.add(Center(child: Text(lastPoiTap, textAlign: TextAlign.center)));
columnChildren.add(
Center(
child: Text(
_lastPoiPlaceId != null ? 'Point of interest tapped' : '',
textAlign: TextAlign.center,
),
),
);
}
return Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: columnChildren);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export 'package:google_maps_flutter_platform_interface/google_maps_flutter_platf
MinMaxZoomPreference,
PatternItem,
PinConfig,
PointOfInterestId,
Polygon,
PolygonId,
Polyline,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ class GoogleMapController {
.listen((_) => _googleMapState.widget.onCameraIdle!()),
);
}
_streamSubscriptions.add(
GoogleMapsFlutterPlatform.instance
.onPointOfInterestTap(mapId: mapId)
.listen(
(PointOfInterestTapEvent e) => _googleMapState.onPointOfInterestTap(e.value),
),
);
_streamSubscriptions.add(
GoogleMapsFlutterPlatform.instance
.onMarkerTap(mapId: mapId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ class GoogleMap extends StatefulWidget {
this.onCameraIdle,
this.onTap,
this.onLongPress,
this.onPointOfInterestTap,
this.markerType = GoogleMapMarkerType.marker,
this.colorScheme,
String? mapId,
Expand Down Expand Up @@ -297,6 +298,11 @@ class GoogleMap extends StatefulWidget {
/// Called every time a [GoogleMap] is long pressed.
final ArgumentCallback<LatLng>? onLongPress;

/// Called when a point of interest on the map is tapped.
///
/// May not be supported on all platforms.
final ArgumentCallback<PointOfInterestId>? onPointOfInterestTap;

/// True if a "My Location" layer should be shown on the map.
///
/// This layer includes a location indicator at the current device location,
Expand Down Expand Up @@ -685,6 +691,14 @@ class _GoogleMapState extends State<GoogleMap> {
}
}

void onPointOfInterestTap(PointOfInterestId pointOfInterestId) {
final ArgumentCallback<PointOfInterestId>? onPointOfInterestTap =
widget.onPointOfInterestTap;
if (onPointOfInterestTap != null) {
onPointOfInterestTap(pointOfInterestId);
}
}

void onTap(LatLng position) {
final ArgumentCallback<LatLng>? onTap = widget.onTap;
if (onTap != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.17.1
version: 2.18.0

environment:
sdk: ^3.10.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,11 @@ class FakeGoogleMapsFlutterPlatform extends GoogleMapsFlutterPlatform {
return mapEventStreamController.stream.whereType<CircleTapEvent>();
}

@override
Stream<PointOfInterestTapEvent> onPointOfInterestTap({required int mapId}) {
return mapEventStreamController.stream.whereType<PointOfInterestTapEvent>();
}

@override
Stream<MapTapEvent> onTap({required int mapId}) {
return mapEventStreamController.stream.whereType<MapTapEvent>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -776,4 +776,29 @@ void main() {
const GoogleMap(initialCameraPosition: CameraPosition(target: LatLng(10.0, 15.0)));
}, returnsNormally);
});

testWidgets('onPointOfInterestTap invokes callback', (WidgetTester tester) async {
final poiCompleter = Completer<PointOfInterestId>();
final controllerCompleter = Completer<GoogleMapController>();

await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: GoogleMap(
initialCameraPosition: const CameraPosition(target: LatLng(0.0, 0.0)),
onMapCreated: controllerCompleter.complete,
onPointOfInterestTap: poiCompleter.complete,
),
),
);

await controllerCompleter.future;
final int mapId = platform.createdIds.first;

platform.mapEventStreamController.add(
PointOfInterestTapEvent(mapId, const PointOfInterestId('place-123')),
);

expect(await poiCompleter.future, const PointOfInterestId('place-123'));
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.20.0

* Adds support for tapping points of interest on the map.

## 2.19.12

* Bumps the androidx group across 10 directories with 1 update.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import com.google.android.gms.maps.model.MapCapabilities;
import com.google.android.gms.maps.model.MapStyleOptions;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.PointOfInterest;
import com.google.android.gms.maps.model.Polygon;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.TileOverlay;
Expand Down Expand Up @@ -385,6 +386,14 @@ public void onCircleClick(Circle circle) {
circlesController.onCircleTap(circle.getId());
}

@Override
public void onPoiClick(PointOfInterest pointOfInterest) {
if (pointOfInterest != null && pointOfInterest.placeId != null) {
flutterApi.onPointOfInterestTap(
pointOfInterest.placeId, (Result<Unit> result) -> Unit.INSTANCE);
}
}

@Override
public void onGroundOverlayClick(@NonNull GroundOverlay groundOverlay) {
groundOverlaysController.onGroundOverlayTap(groundOverlay.getId());
Expand Down Expand Up @@ -421,6 +430,7 @@ private void setGoogleMapListener(@Nullable GoogleMapListener listener) {
googleMap.setOnPolygonClickListener(listener);
googleMap.setOnPolylineClickListener(listener);
googleMap.setOnCircleClickListener(listener);
googleMap.setOnPoiClickListener(listener);
googleMap.setOnMapClickListener(listener);
googleMap.setOnMapLongClickListener(listener);
googleMap.setOnGroundOverlayClickListener(listener);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ interface GoogleMapListener
GoogleMap.OnPolygonClickListener,
GoogleMap.OnPolylineClickListener,
GoogleMap.OnCircleClickListener,
GoogleMap.OnPoiClickListener,
GoogleMap.OnMapClickListener,
GoogleMap.OnMapLongClickListener,
GoogleMap.OnMarkerDragListener,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4071,6 +4071,25 @@ class MapsCallbackApi(
}
}
}
/** Called when a point of interest is tapped. */
fun onPointOfInterestTap(placeIdArg: String, callback: (Result<Unit>) -> Unit) {
val separatedMessageChannelSuffix =
if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
val channelName =
"dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onPointOfInterestTap$separatedMessageChannelSuffix"
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
channel.send(listOf(placeIdArg)) {
if (it is List<*>) {
if (it.size > 1) {
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
} else {
callback(Result.success(Unit))
}
} else {
callback(Result.failure(MessagesPigeonUtils.createConnectionError(channelName)))
}
}
}
/** Called when a marker cluster is tapped. */
fun onClusterTap(clusterArg: PlatformCluster, callback: (Result<Unit>) -> Unit) {
val separatedMessageChannelSuffix =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MapCapabilities;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.PointOfInterest;
import com.google.maps.android.clustering.ClusterManager;
import io.flutter.plugin.common.BinaryMessenger;
import java.util.ArrayList;
Expand Down Expand Up @@ -258,6 +259,18 @@ public void OnClusterItemInfoWindowClickCallsMarkersController() {
verify(mockMarkersController, times(1)).onClusterItemInfoWindowTap(markerBuilder.markerId());
}

@Test
public void OnPoiClickCallsFlutterApi() {
GoogleMapController googleMapController = getGoogleMapControllerWithMockedDependencies();
googleMapController.onMapReady(mockGoogleMap);

PointOfInterest pointOfInterest =
new PointOfInterest(new LatLng(0, 0), "place-123", "Test Place");
googleMapController.onPoiClick(pointOfInterest);

verify(flutterApi, times(1)).onPointOfInterestTap(eq("place-123"), any());
}

@Test
public void SetInitialHeatmaps() {
GoogleMapController googleMapController = getGoogleMapControllerWithMockedDependencies();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,11 @@ class FakeGoogleMapsFlutterPlatform extends GoogleMapsFlutterPlatform {
return mapEventStreamController.stream.whereType<CircleTapEvent>();
}

@override
Stream<PointOfInterestTapEvent> onPointOfInterestTap({required int mapId}) {
return mapEventStreamController.stream.whereType<PointOfInterestTapEvent>();
}

@override
Stream<GroundOverlayTapEvent> onGroundOverlayTap({required int mapId}) {
return mapEventStreamController.stream.whereType<GroundOverlayTapEvent>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,11 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform {
return _events(mapId).whereType<CircleTapEvent>();
}

@override
Stream<PointOfInterestTapEvent> onPointOfInterestTap({required int mapId}) {
return _events(mapId).whereType<PointOfInterestTapEvent>();
}

@override
Stream<GroundOverlayTapEvent> onGroundOverlayTap({required int mapId}) {
return _events(mapId).whereType<GroundOverlayTapEvent>();
Expand Down Expand Up @@ -1079,6 +1084,11 @@ class HostMapMessageHandler implements MapsCallbackApi {
streamController.add(CircleTapEvent(mapId, CircleId(circleId)));
}

@override
void onPointOfInterestTap(String placeId) {
streamController.add(PointOfInterestTapEvent(mapId, PointOfInterestId(placeId)));
}

@override
void onClusterTap(PlatformCluster cluster) {
streamController.add(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3436,6 +3436,9 @@ abstract class MapsCallbackApi {
/// Called when a circle is tapped.
void onCircleTap(String circleId);

/// Called when a point of interest is tapped.
void onPointOfInterestTap(String placeId);

/// Called when a marker cluster is tapped.
void onClusterTap(PlatformCluster cluster);

Expand Down Expand Up @@ -3731,6 +3734,31 @@ abstract class MapsCallbackApi {
});
}
}
{
final pigeonVar_channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onPointOfInterestTap$messageChannelSuffix',
pigeonChannelCodec,
binaryMessenger: binaryMessenger,
);
if (api == null) {
pigeonVar_channel.setMessageHandler(null);
} else {
pigeonVar_channel.setMessageHandler((Object? message) async {
final List<Object?> args = message! as List<Object?>;
final String arg_placeId = args[0]! as String;
try {
api.onPointOfInterestTap(arg_placeId);
return wrapResponse(empty: true);
} on PlatformException catch (e) {
return wrapResponse(error: e);
} catch (e) {
return wrapResponse(
error: PlatformException(code: 'error', message: e.toString()),
);
}
});
}
}
{
final pigeonVar_channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.google_maps_flutter_android.MapsCallbackApi.onClusterTap$messageChannelSuffix',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -831,6 +831,9 @@ abstract class MapsCallbackApi {
/// Called when a circle is tapped.
void onCircleTap(String circleId);

/// Called when a point of interest is tapped.
void onPointOfInterestTap(String placeId);

/// Called when a marker cluster is tapped.
void onClusterTap(PlatformCluster cluster);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: google_maps_flutter_android
description: Android implementation of the google_maps_flutter plugin.
repository: https://github.com/flutter/packages/tree/main/packages/google_maps_flutter/google_maps_flutter_android
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22
version: 2.19.12
version: 2.20.0

environment:
sdk: ^3.12.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,22 @@ void main() {
expect((await stream.next).value.value, equals(objectId));
});

test('points of interest send tap events to correct stream', () async {
const mapId = 1;
const placeId = 'place-123';

final maps = GoogleMapsFlutterAndroid();
final HostMapMessageHandler callbackHandler = maps.ensureHandlerInitialized(mapId);

final stream = StreamQueue<PointOfInterestTapEvent>(
maps.onPointOfInterestTap(mapId: mapId),
);

callbackHandler.onPointOfInterestTap(placeId);

expect((await stream.next).value.value, equals(placeId));
});

test('clusters send tap events to correct stream', () async {
const mapId = 1;
const managerId = 'manager-id';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.19.0

* Adds support for tapping points of interest on the map.

## 2.18.3

* Updates README to include setup information.
Expand Down
Loading