Skip to content

Commit a5cd0c3

Browse files
[google_maps_flutter_platfomr_interface] Add Marker drag events (flutter#2653)
This PR adds onDragStart(LatLng) and onDrag(LatLng) events to Marker objects, in addition to the already existing onDragEnd.
1 parent d2c6c43 commit a5cd0c3

File tree

8 files changed

+295
-2
lines changed

8 files changed

+295
-2
lines changed

packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 2.1.2
2+
3+
* Add additional marker drag events
4+
15
## 2.1.1
26

37
* Method `buildViewWithTextDirection` has been added to the platform interface.

packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/events/map_event.dart

+20
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,26 @@ class InfoWindowTapEvent extends MapEvent<MarkerId> {
102102
InfoWindowTapEvent(int mapId, MarkerId markerId) : super(mapId, markerId);
103103
}
104104

105+
/// An event fired when a [Marker] is starting to be dragged to a new [LatLng].
106+
class MarkerDragStartEvent extends _PositionedMapEvent<MarkerId> {
107+
/// Build a MarkerDragStart Event triggered from the map represented by `mapId`.
108+
///
109+
/// The `position` on this event is the [LatLng] on which the Marker was picked up from.
110+
/// The `value` of this event is a [MarkerId] object that represents the Marker.
111+
MarkerDragStartEvent(int mapId, LatLng position, MarkerId markerId)
112+
: super(mapId, position, markerId);
113+
}
114+
115+
/// An event fired when a [Marker] is being dragged to a new [LatLng].
116+
class MarkerDragEvent extends _PositionedMapEvent<MarkerId> {
117+
/// Build a MarkerDrag Event triggered from the map represented by `mapId`.
118+
///
119+
/// The `position` on this event is the [LatLng] on which the Marker was dragged to.
120+
/// The `value` of this event is a [MarkerId] object that represents the Marker.
121+
MarkerDragEvent(int mapId, LatLng position, MarkerId markerId)
122+
: super(mapId, position, markerId);
123+
}
124+
105125
/// An event fired when a [Marker] is dragged to a new [LatLng].
106126
class MarkerDragEndEvent extends _PositionedMapEvent<MarkerId> {
107127
/// Build a MarkerDragEnd Event triggered from the map represented by `mapId`.

packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart

+24
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,16 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform {
124124
return _events(mapId).whereType<InfoWindowTapEvent>();
125125
}
126126

127+
@override
128+
Stream<MarkerDragStartEvent> onMarkerDragStart({required int mapId}) {
129+
return _events(mapId).whereType<MarkerDragStartEvent>();
130+
}
131+
132+
@override
133+
Stream<MarkerDragEvent> onMarkerDrag({required int mapId}) {
134+
return _events(mapId).whereType<MarkerDragEvent>();
135+
}
136+
127137
@override
128138
Stream<MarkerDragEndEvent> onMarkerDragEnd({required int mapId}) {
129139
return _events(mapId).whereType<MarkerDragEndEvent>();
@@ -174,6 +184,20 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform {
174184
MarkerId(call.arguments['markerId']),
175185
));
176186
break;
187+
case 'marker#onDragStart':
188+
_mapEventStreamController.add(MarkerDragStartEvent(
189+
mapId,
190+
LatLng.fromJson(call.arguments['position'])!,
191+
MarkerId(call.arguments['markerId']),
192+
));
193+
break;
194+
case 'marker#onDrag':
195+
_mapEventStreamController.add(MarkerDragEvent(
196+
mapId,
197+
LatLng.fromJson(call.arguments['position'])!,
198+
MarkerId(call.arguments['markerId']),
199+
));
200+
break;
177201
case 'marker#onDragEnd':
178202
_mapEventStreamController.add(MarkerDragEndEvent(
179203
mapId,

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

+10
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,16 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface {
303303
throw UnimplementedError('onInfoWindowTap() has not been implemented.');
304304
}
305305

306+
/// A [Marker] has been dragged to a different [LatLng] position.
307+
Stream<MarkerDragStartEvent> onMarkerDragStart({required int mapId}) {
308+
throw UnimplementedError('onMarkerDragEnd() has not been implemented.');
309+
}
310+
311+
/// A [Marker] has been dragged to a different [LatLng] position.
312+
Stream<MarkerDragEvent> onMarkerDrag({required int mapId}) {
313+
throw UnimplementedError('onMarkerDragEnd() has not been implemented.');
314+
}
315+
306316
/// A [Marker] has been dragged to a different [LatLng] position.
307317
Stream<MarkerDragEndEvent> onMarkerDragEnd({required int mapId}) {
308318
throw UnimplementedError('onMarkerDragEnd() has not been implemented.');

packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/marker.dart

+14-1
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ class Marker implements MapsObject {
147147
this.visible = true,
148148
this.zIndex = 0.0,
149149
this.onTap,
150+
this.onDrag,
151+
this.onDragStart,
150152
this.onDragEnd,
151153
}) : assert(alpha == null || (0.0 <= alpha && alpha <= 1.0));
152154

@@ -207,9 +209,15 @@ class Marker implements MapsObject {
207209
/// Callbacks to receive tap events for markers placed on this map.
208210
final VoidCallback? onTap;
209211

212+
/// Signature reporting the new [LatLng] at the start of a drag event.
213+
final ValueChanged<LatLng>? onDragStart;
214+
210215
/// Signature reporting the new [LatLng] at the end of a drag event.
211216
final ValueChanged<LatLng>? onDragEnd;
212217

218+
/// Signature reporting the new [LatLng] during the drag event.
219+
final ValueChanged<LatLng>? onDrag;
220+
213221
/// Creates a new [Marker] object whose values are the same as this instance,
214222
/// unless overwritten by the specified parameters.
215223
Marker copyWith({
@@ -225,6 +233,8 @@ class Marker implements MapsObject {
225233
bool? visibleParam,
226234
double? zIndexParam,
227235
VoidCallback? onTapParam,
236+
ValueChanged<LatLng>? onDragStartParam,
237+
ValueChanged<LatLng>? onDragParam,
228238
ValueChanged<LatLng>? onDragEndParam,
229239
}) {
230240
return Marker(
@@ -241,6 +251,8 @@ class Marker implements MapsObject {
241251
visible: visibleParam ?? visible,
242252
zIndex: zIndexParam ?? zIndex,
243253
onTap: onTapParam ?? onTap,
254+
onDragStart: onDragStartParam ?? onDragStart,
255+
onDrag: onDragParam ?? onDrag,
244256
onDragEnd: onDragEndParam ?? onDragEnd,
245257
);
246258
}
@@ -300,6 +312,7 @@ class Marker implements MapsObject {
300312
return 'Marker{markerId: $markerId, alpha: $alpha, anchor: $anchor, '
301313
'consumeTapEvents: $consumeTapEvents, draggable: $draggable, flat: $flat, '
302314
'icon: $icon, infoWindow: $infoWindow, position: $position, rotation: $rotation, '
303-
'visible: $visible, zIndex: $zIndex, onTap: $onTap}';
315+
'visible: $visible, zIndex: $zIndex, onTap: $onTap, onDragStart: $onDragStart, '
316+
'onDrag: $onDrag, onDragEnd: $onDragEnd}';
304317
}
305318
}

packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ repository: https://github.com/flutter/plugins/tree/master/packages/google_maps_
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22
55
# NOTE: We strongly prefer non-breaking changes, even at the expense of a
66
# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
7-
version: 2.1.1
7+
version: 2.1.2
88

99
environment:
1010
sdk: '>=2.12.0 <3.0.0'
@@ -19,6 +19,7 @@ dependencies:
1919
stream_transform: ^2.0.0
2020

2121
dev_dependencies:
22+
async: ^2.5.0
2223
flutter_test:
2324
sdk: flutter
2425
mockito: ^5.0.0

packages/google_maps_flutter/google_maps_flutter_platform_interface/test/method_channel/method_channel_google_maps_flutter_test.dart

+54
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@
55
import 'package:flutter/services.dart';
66
import 'package:flutter_test/flutter_test.dart';
77

8+
import 'package:google_maps_flutter_platform_interface/src/events/map_event.dart';
89
import 'package:google_maps_flutter_platform_interface/src/method_channel/method_channel_google_maps_flutter.dart';
910
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
11+
import 'dart:async';
12+
13+
import 'package:async/async.dart';
1014

1115
void main() {
1216
TestWidgetsFlutterBinding.ensureInitialized();
@@ -33,6 +37,15 @@ void main() {
3337
});
3438
}
3539

40+
Future<void> sendPlatformMessage(
41+
int mapId, String method, Map<dynamic, dynamic> data) async {
42+
final ByteData byteData = const StandardMethodCodec()
43+
.encodeMethodCall(MethodCall(method, data));
44+
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger
45+
.handlePlatformMessage(
46+
"plugins.flutter.io/google_maps_$mapId", byteData, (data) {});
47+
}
48+
3649
// Calls each method that uses invokeMethod with a return type other than
3750
// void to ensure that the casting/nullability handling succeeds.
3851
//
@@ -68,5 +81,46 @@ void main() {
6881
'map#takeSnapshot',
6982
]);
7083
});
84+
test('markers send drag event to correct streams', () async {
85+
const int mapId = 1;
86+
final jsonMarkerDragStartEvent = <dynamic, dynamic>{
87+
"mapId": mapId,
88+
"markerId": "drag-start-marker",
89+
"position": <double>[1.0, 1.0]
90+
};
91+
final jsonMarkerDragEvent = <dynamic, dynamic>{
92+
"mapId": mapId,
93+
"markerId": "drag-marker",
94+
"position": <double>[1.0, 1.0]
95+
};
96+
final jsonMarkerDragEndEvent = <dynamic, dynamic>{
97+
"mapId": mapId,
98+
"markerId": "drag-end-marker",
99+
"position": <double>[1.0, 1.0]
100+
};
101+
102+
final MethodChannelGoogleMapsFlutter maps =
103+
MethodChannelGoogleMapsFlutter();
104+
maps.ensureChannelInitialized(mapId);
105+
106+
final StreamQueue<MarkerDragStartEvent> markerDragStartStream =
107+
StreamQueue(maps.onMarkerDragStart(mapId: mapId));
108+
final StreamQueue<MarkerDragEvent> markerDragStream =
109+
StreamQueue(maps.onMarkerDrag(mapId: mapId));
110+
final StreamQueue<MarkerDragEndEvent> markerDragEndStream =
111+
StreamQueue(maps.onMarkerDragEnd(mapId: mapId));
112+
113+
await sendPlatformMessage(
114+
mapId, "marker#onDragStart", jsonMarkerDragStartEvent);
115+
await sendPlatformMessage(mapId, "marker#onDrag", jsonMarkerDragEvent);
116+
await sendPlatformMessage(
117+
mapId, "marker#onDragEnd", jsonMarkerDragEndEvent);
118+
119+
expect((await markerDragStartStream.next).value.value,
120+
equals("drag-start-marker"));
121+
expect((await markerDragStream.next).value.value, equals("drag-marker"));
122+
expect((await markerDragEndStream.next).value.value,
123+
equals("drag-end-marker"));
124+
});
71125
});
72126
}

0 commit comments

Comments
 (0)