Skip to content

Commit 09297ec

Browse files
authored
[google_maps_flutter_platform_interface] Add Advanced markers support (#9737)
This PR adds Advanced markers support to the platform interface of `google_maps_flutter`. Approved combined PR: #7882 Issue: [#155526](flutter/flutter#155526) ## Pre-Review Checklist **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. [^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
1 parent 6efb759 commit 09297ec

File tree

14 files changed

+821
-40
lines changed

14 files changed

+821
-40
lines changed

packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 2.13.0
2+
3+
* Adds Advanced marker support.
4+
15
## 2.12.1
26

37
* Fixes the `zIndex` issue in the `copyWith` method.

packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,11 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface {
430430
return null;
431431
}
432432

433+
/// Returns true if [AdvancedMarker]s can be used with this map.
434+
Future<bool> isAdvancedMarkersAvailable({required int mapId}) async {
435+
return false;
436+
}
437+
433438
/// Returns a widget displaying the map view.
434439
@Deprecated('Use buildViewWithConfiguration instead.')
435440
Widget buildView(
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:ui' show Offset;
6+
import 'package:flutter/foundation.dart';
7+
8+
import '../../google_maps_flutter_platform_interface.dart';
9+
10+
/// Marks a geographical location on the map.
11+
///
12+
/// Extends [Marker] and provides additional features.
13+
@immutable
14+
class AdvancedMarker extends Marker {
15+
/// Creates a set of marker configuration options.
16+
///
17+
/// Specifies a marker with a given [collisionBehavior]. Default is
18+
/// [MarkerCollisionBehavior.required].
19+
AdvancedMarker({
20+
required super.markerId,
21+
super.alpha,
22+
super.anchor,
23+
super.consumeTapEvents,
24+
super.draggable,
25+
super.flat,
26+
super.icon,
27+
super.infoWindow,
28+
super.position,
29+
super.rotation,
30+
super.visible,
31+
super.clusterManagerId,
32+
super.onTap,
33+
super.onDrag,
34+
super.onDragStart,
35+
super.onDragEnd,
36+
int zIndex = 0,
37+
this.collisionBehavior = MarkerCollisionBehavior.requiredDisplay,
38+
}) : super(zIndex: zIndex.toDouble());
39+
40+
/// Indicates how the marker behaves when it collides with other markers.
41+
final MarkerCollisionBehavior collisionBehavior;
42+
43+
/// Creates a new [AdvancedMarker] object whose values are the same as this
44+
/// instance, unless overwritten by the specified parameters.
45+
@override
46+
AdvancedMarker copyWith({
47+
double? alphaParam,
48+
Offset? anchorParam,
49+
bool? consumeTapEventsParam,
50+
bool? draggableParam,
51+
bool? flatParam,
52+
BitmapDescriptor? iconParam,
53+
InfoWindow? infoWindowParam,
54+
LatLng? positionParam,
55+
double? rotationParam,
56+
bool? visibleParam,
57+
@Deprecated(
58+
'Use zIndexIntParam instead. '
59+
'On some platforms zIndex is truncated to an int, which can lead to incorrect/unstable ordering.',
60+
)
61+
double? zIndexParam,
62+
int? zIndexIntParam,
63+
VoidCallback? onTapParam,
64+
ValueChanged<LatLng>? onDragStartParam,
65+
ValueChanged<LatLng>? onDragParam,
66+
ValueChanged<LatLng>? onDragEndParam,
67+
ClusterManagerId? clusterManagerIdParam,
68+
MarkerCollisionBehavior? collisionBehaviorParam,
69+
double? altitudeParam,
70+
}) {
71+
return AdvancedMarker(
72+
markerId: markerId,
73+
alpha: alphaParam ?? alpha,
74+
anchor: anchorParam ?? anchor,
75+
consumeTapEvents: consumeTapEventsParam ?? consumeTapEvents,
76+
draggable: draggableParam ?? draggable,
77+
flat: flatParam ?? flat,
78+
icon: iconParam ?? icon,
79+
infoWindow: infoWindowParam ?? infoWindow,
80+
position: positionParam ?? position,
81+
rotation: rotationParam ?? rotation,
82+
visible: visibleParam ?? visible,
83+
zIndex: (zIndexIntParam ?? zIndexParam ?? zIndex).toInt(),
84+
onTap: onTapParam ?? onTap,
85+
onDragStart: onDragStartParam ?? onDragStart,
86+
onDrag: onDragParam ?? onDrag,
87+
onDragEnd: onDragEndParam ?? onDragEnd,
88+
clusterManagerId: clusterManagerIdParam ?? clusterManagerId,
89+
collisionBehavior: collisionBehaviorParam ?? collisionBehavior,
90+
);
91+
}
92+
93+
/// Converts this object to something serializable in JSON.
94+
@override
95+
Object toJson() {
96+
final String? clusterManagerIdValue = clusterManagerId?.value;
97+
98+
return <String, Object>{
99+
'markerId': markerId.value,
100+
'alpha': alpha,
101+
'consumeTapEvents': consumeTapEvents,
102+
'draggable': draggable,
103+
'flat': flat,
104+
'icon': icon.toJson(),
105+
'infoWindow': infoWindow.toJson(),
106+
'position': position.toJson(),
107+
'rotation': rotation,
108+
'visible': visible,
109+
'zIndex': zIndex,
110+
'collisionBehavior': collisionBehavior.index,
111+
'anchor': _offsetToJson(anchor),
112+
if (clusterManagerIdValue != null)
113+
'clusterManagerId': clusterManagerIdValue,
114+
};
115+
}
116+
117+
@override
118+
bool operator ==(Object other) {
119+
if (identical(this, other)) {
120+
return true;
121+
}
122+
if (other.runtimeType != runtimeType) {
123+
return false;
124+
}
125+
return other is AdvancedMarker &&
126+
markerId == other.markerId &&
127+
alpha == other.alpha &&
128+
anchor == other.anchor &&
129+
consumeTapEvents == other.consumeTapEvents &&
130+
draggable == other.draggable &&
131+
flat == other.flat &&
132+
icon == other.icon &&
133+
infoWindow == other.infoWindow &&
134+
position == other.position &&
135+
rotation == other.rotation &&
136+
visible == other.visible &&
137+
zIndex == other.zIndex &&
138+
clusterManagerId == other.clusterManagerId &&
139+
collisionBehavior == other.collisionBehavior;
140+
}
141+
142+
@override
143+
int get hashCode => markerId.hashCode;
144+
145+
@override
146+
String toString() {
147+
return 'AdvancedMarker{markerId: $markerId, alpha: $alpha, anchor: $anchor, '
148+
'consumeTapEvents: $consumeTapEvents, draggable: $draggable, flat: $flat, '
149+
'icon: $icon, infoWindow: $infoWindow, position: $position, rotation: $rotation, '
150+
'visible: $visible, zIndex: $zIndex, onTap: $onTap, onDragStart: $onDragStart, '
151+
'onDrag: $onDrag, onDragEnd: $onDragEnd, clusterManagerId: $clusterManagerId, '
152+
'collisionBehavior: $collisionBehavior}';
153+
}
154+
}
155+
156+
/// Indicates how the marker behaves when it collides with other markers.
157+
enum MarkerCollisionBehavior {
158+
/// (default) Always display the marker regardless of collision.
159+
requiredDisplay,
160+
161+
/// Display the marker only if it does not overlap with other markers.
162+
/// If two markers of this type would overlap, the one with the higher zIndex
163+
/// is shown. If they have the same zIndex, the one with the lower vertical
164+
/// screen position is shown.
165+
optionalAndHidesLowerPriority,
166+
167+
/// Always display the marker regardless of collision, and hide any
168+
/// [optionalAndHidesLowerPriority] markers or labels that would overlap with
169+
/// the marker.
170+
requiredAndHidesOptional,
171+
}
172+
173+
/// Convert [Offset] to JSON object.
174+
Object _offsetToJson(Offset offset) {
175+
return <Object>[offset.dx, offset.dy];
176+
}

0 commit comments

Comments
 (0)