Skip to content
Open
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
@@ -1,3 +1,7 @@
## 2.17.0

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

## 2.16.1

* Fixes the `PinConfig` code sample in the `BitmapDescriptor` documentation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,15 @@ class GroundOverlayTapEvent extends MapEvent<GroundOverlayId> {
GroundOverlayTapEvent(super.mapId, super.croundOverlayId);
}

/// An event fired when a point of interest is tapped.
class PointOfInterestTapEvent extends MapEvent<PointOfInterestId> {
/// Build a PointOfInterestTap Event triggered from the map represented by `mapId`.
///
/// The `value` of this event is a [PointOfInterestId] object that represents the
/// tapped point of interest.
PointOfInterestTapEvent(super.mapId, super.pointOfInterestId);
}
Comment on lines +163 to +170

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

The native Google Maps SDKs on both Android (OnPoiClickListener) and iOS (mapView:didTapPOIWithPlaceID:name:location:) provide the name and location (LatLng) of the tapped point of interest, in addition to the place ID. \n\nBy only exposing PointOfInterestId (which only wraps the place ID string), developers will not be able to know the name or coordinates of the tapped POI without performing a separate, paid Google Places API lookup. \n\nTo make this API fully functional and useful, please consider defining a PointOfInterest class containing id, name, and latLng, and have PointOfInterestTapEvent wrap that instead of just the ID.


/// An event fired when a Map is tapped.
class MapTapEvent extends _PositionedMapEvent<void> {
/// Build an MapTap Event triggered from the map represented by `mapId`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,11 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface {
throw UnimplementedError('onCircleTap() has not been implemented.');
}

/// A point of interest has been tapped.
Stream<PointOfInterestTapEvent> onPointOfInterestTap({required int mapId}) {
return const Stream<PointOfInterestTapEvent>.empty();
}
Comment on lines +341 to +343

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

To maintain consistency with all other stream methods in this class (such as onClusterTap, onGroundOverlayTap, onMarkerTap, etc.) and to adhere to the class's documented design principle (which states that default implementations of new methods should throw at runtime to signal unimplemented status), this method should throw an UnimplementedError instead of returning an empty stream.

Suggested change
Stream<PointOfInterestTapEvent> onPointOfInterestTap({required int mapId}) {
return const Stream<PointOfInterestTapEvent>.empty();
}
Stream<PointOfInterestTapEvent> onPointOfInterestTap({required int mapId}) {
throw UnimplementedError('onPointOfInterestTap() has not been implemented.');
}


/// A Map has been tapped at a certain [LatLng].
Stream<MapTapEvent> onTap({required int mapId}) {
throw UnimplementedError('onTap() has not been implemented.');
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// 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/foundation.dart' show immutable;

import 'types.dart';

/// Uniquely identifies a point of interest on a [GoogleMap].
///
/// The [value] is the Google Maps place ID for the tapped point of interest.
@immutable
class PointOfInterestId extends MapsObjectId<PointOfInterestId> {
/// Creates an immutable identifier for a point of interest.
const PointOfInterestId(super.value);
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export 'maps_object_updates.dart';
export 'marker.dart';
export 'marker_updates.dart';
export 'pattern_item.dart';
export 'point_of_interest_id.dart';
export 'polygon.dart';
export 'polygon_updates.dart';
export 'polyline.dart';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ repository: https://github.com/flutter/packages/tree/main/packages/google_maps_f
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.16.1
version: 2.17.0

environment:
sdk: ^3.10.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ void main() {
);
});

test('onPointOfInterestTap() returns empty stream', () async {
final Stream<PointOfInterestTapEvent> stream = BuildViewGoogleMapsFlutterPlatform()
.onPointOfInterestTap(mapId: 0);
expect(await stream.isEmpty, isTrue);
});
Comment on lines +98 to +102

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Update this test to expect an UnimplementedError to match the corrected default implementation of onPointOfInterestTap.

Suggested change
test('onPointOfInterestTap() returns empty stream', () async {
final Stream<PointOfInterestTapEvent> stream = BuildViewGoogleMapsFlutterPlatform()
.onPointOfInterestTap(mapId: 0);
expect(await stream.isEmpty, isTrue);
});
test('onPointOfInterestTap() throws UnimplementedError', () {
expect(
() => BuildViewGoogleMapsFlutterPlatform().onPointOfInterestTap(mapId: 0),
throwsUnimplementedError,
);
});


test('default implementation of `getStyleError` returns null', () async {
final GoogleMapsFlutterPlatform platform = BuildViewGoogleMapsFlutterPlatform();
expect(await platform.getStyleError(mapId: 0), null);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// 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_test/flutter_test.dart';
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';

void main() {
test('PointOfInterestId equality', () {
const id1 = PointOfInterestId('place-123');
const id2 = PointOfInterestId('place-123');
const id3 = PointOfInterestId('place-456');

expect(id1, equals(id2));
expect(id1, isNot(equals(id3)));
expect(id1.hashCode, equals(id2.hashCode));
});

test('PointOfInterestId toString', () {
const id = PointOfInterestId('place-123');
expect(id.toString(), contains('place-123'));
});
}