Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit f84066f

Browse files
authored
[google_maps_flutter]ChangeNotifier is replaced with granular callbacks (#1302)
* ChangeNotifier is replaced with granular callbacks This facilitates better interaction with the map than adding a listener to the controller. * Make docs better * Remove camera update call backs for map and marker update * Fix up some links and caps. * Update changelog and pubspec. * fix unused var
1 parent f74c7c1 commit f84066f

File tree

5 files changed

+69
-49
lines changed

5 files changed

+69
-49
lines changed

packages/google_maps_flutter/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 0.4.0
2+
3+
* Change events are call backs on GoogleMap widget.
4+
* GoogleMapController no longer handles change events.
5+
16
## 0.3.0+3
27

38
* Update Android play-services-maps to 16.1.0

packages/google_maps_flutter/example/lib/map_ui.dart

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ class MapUiBodyState extends State<MapUiBody> {
3636
zoom: 11.0,
3737
);
3838

39-
GoogleMapController mapController;
4039
CameraPosition _position = _kInitialPosition;
40+
bool _isMapCreated = false;
4141
bool _isMoving = false;
4242
bool _compassEnabled = true;
4343
CameraTargetBounds _cameraTargetBounds = CameraTargetBounds.unbounded;
@@ -54,20 +54,8 @@ class MapUiBodyState extends State<MapUiBody> {
5454
super.initState();
5555
}
5656

57-
void _onMapChanged() {
58-
setState(() {
59-
_extractMapInfo();
60-
});
61-
}
62-
63-
void _extractMapInfo() {
64-
_position = mapController.cameraPosition;
65-
_isMoving = mapController.isCameraMoving;
66-
}
67-
6857
@override
6958
void dispose() {
70-
mapController.removeListener(_onMapChanged);
7159
super.dispose();
7260
}
7361

@@ -197,6 +185,7 @@ class MapUiBodyState extends State<MapUiBody> {
197185
tiltGesturesEnabled: _tiltGesturesEnabled,
198186
zoomGesturesEnabled: _zoomGesturesEnabled,
199187
myLocationEnabled: _myLocationEnabled,
188+
onCameraMove: _updateCameraPosition,
200189
);
201190

202191
final List<Widget> columnChildren = <Widget>[
@@ -212,7 +201,7 @@ class MapUiBodyState extends State<MapUiBody> {
212201
),
213202
];
214203

215-
if (mapController != null) {
204+
if (_isMapCreated) {
216205
columnChildren.add(
217206
Expanded(
218207
child: ListView(
@@ -245,10 +234,15 @@ class MapUiBodyState extends State<MapUiBody> {
245234
);
246235
}
247236

237+
void _updateCameraPosition(CameraPosition position) {
238+
setState(() {
239+
_position = position;
240+
});
241+
}
242+
248243
void onMapCreated(GoogleMapController controller) {
249-
mapController = controller;
250-
mapController.addListener(_onMapChanged);
251-
_extractMapInfo();
252-
setState(() {});
244+
setState(() {
245+
_isMapCreated = true;
246+
});
253247
}
254248
}

packages/google_maps_flutter/lib/src/controller.dart

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,13 @@
55
part of google_maps_flutter;
66

77
/// Controller for a single GoogleMap instance running on the host platform.
8-
///
9-
/// Change listeners are notified upon changes to any of
10-
///
11-
/// * the [options] property
12-
/// * the [isCameraMoving] property
13-
/// * the [cameraPosition] property
14-
///
15-
/// Listeners are notified after changes have been applied on the platform side.
16-
class GoogleMapController extends ChangeNotifier {
8+
class GoogleMapController {
179
GoogleMapController._(
1810
MethodChannel channel,
1911
CameraPosition initialCameraPosition,
2012
this._googleMapState,
2113
) : assert(channel != null),
2214
_channel = channel {
23-
_cameraPosition = initialCameraPosition;
2415
_channel.setMethodCallHandler(_handleMethodCall);
2516
}
2617

@@ -45,30 +36,26 @@ class GoogleMapController extends ChangeNotifier {
4536

4637
final MethodChannel _channel;
4738

48-
/// True if the map camera is currently moving.
49-
bool get isCameraMoving => _isCameraMoving;
50-
bool _isCameraMoving = false;
51-
5239
final _GoogleMapState _googleMapState;
5340

54-
/// Returns the most recent camera position reported by the platform side.
55-
/// Will be null, if [GoogleMap.trackCameraPosition] is false.
56-
CameraPosition get cameraPosition => _cameraPosition;
57-
CameraPosition _cameraPosition;
58-
5941
Future<dynamic> _handleMethodCall(MethodCall call) async {
6042
switch (call.method) {
6143
case 'camera#onMoveStarted':
62-
_isCameraMoving = true;
63-
notifyListeners();
44+
if (_googleMapState.widget.onCameraMoveStarted != null) {
45+
_googleMapState.widget.onCameraMoveStarted();
46+
}
6447
break;
6548
case 'camera#onMove':
66-
_cameraPosition = CameraPosition.fromMap(call.arguments['position']);
67-
notifyListeners();
49+
if (_googleMapState.widget.onCameraMove != null) {
50+
_googleMapState.widget.onCameraMove(
51+
CameraPosition.fromMap(call.arguments['position']),
52+
);
53+
}
6854
break;
6955
case 'camera#onIdle':
70-
_isCameraMoving = false;
71-
notifyListeners();
56+
if (_googleMapState.widget.onCameraIdle != null) {
57+
_googleMapState.widget.onCameraIdle();
58+
}
7259
break;
7360
case 'marker#onTap':
7461
_googleMapState.onMarkerTap(call.arguments['markerId']);
@@ -92,14 +79,12 @@ class GoogleMapController extends ChangeNotifier {
9279
// TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter.
9380
// https://github.com/flutter/flutter/issues/26431
9481
// ignore: strong_mode_implicit_dynamic_method
95-
final dynamic json = await _channel.invokeMethod(
82+
await _channel.invokeMethod(
9683
'map#update',
9784
<String, dynamic>{
9885
'options': optionsUpdate,
9986
},
10087
);
101-
_cameraPosition = CameraPosition.fromMap(json);
102-
notifyListeners();
10388
}
10489

10590
/// Updates marker configuration.
@@ -117,7 +102,6 @@ class GoogleMapController extends ChangeNotifier {
117102
'markers#update',
118103
markerUpdates._toMap(),
119104
);
120-
notifyListeners();
121105
}
122106

123107
/// Starts an animated change of the map camera position.

packages/google_maps_flutter/lib/src/google_map.dart

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ part of google_maps_flutter;
66

77
typedef void MapCreatedCallback(GoogleMapController controller);
88

9+
/// Callback that receives updates to the camera position.
10+
///
11+
/// This callback is triggered when the platform Google Map
12+
/// registers a camera movement. This will be called with null if
13+
/// [GoogleMap.trackCameraPosition] is false.
14+
///
15+
/// This is used in [GoogleMap.onCameraMove] and [GoogleMap.onMapOptionsUpdate].
16+
typedef void CameraPositionCallback(CameraPosition position);
17+
918
class GoogleMap extends StatefulWidget {
1019
const GoogleMap({
1120
@required this.initialCameraPosition,
@@ -22,6 +31,9 @@ class GoogleMap extends StatefulWidget {
2231
this.trackCameraPosition = false,
2332
this.myLocationEnabled = false,
2433
this.markers,
34+
this.onCameraMoveStarted,
35+
this.onCameraMove,
36+
this.onCameraIdle,
2537
}) : assert(initialCameraPosition != null);
2638

2739
final MapCreatedCallback onMapCreated;
@@ -58,9 +70,34 @@ class GoogleMap extends StatefulWidget {
5870
/// True if the map view should relay camera move events to Flutter.
5971
final bool trackCameraPosition;
6072

61-
// Markers to be placed on the map.
73+
/// Markers to be placed on the map.
6274
final Set<Marker> markers;
6375

76+
/// Called when the camera starts moving.
77+
///
78+
/// This can be initiated by the following:
79+
/// 1. Non-gesture animation initiated in response to user actions.
80+
/// For example: zoom buttons, my location button, or marker clicks.
81+
/// 2. Programmatically initiated animation.
82+
/// 3. Camera motion initiated in response to user gestures on the map.
83+
/// For example: pan, tilt, pinch to zoom, or rotate.
84+
///
85+
/// Note: This is callback is called even if [trackCameraPosition] is false.
86+
final VoidCallback onCameraMoveStarted;
87+
88+
/// Called repeatedly as the camera continues to move after an
89+
/// onCameraMoveStarted call.
90+
///
91+
/// This may be called as often as once every frame and should
92+
/// not perform expensive operations.
93+
///
94+
/// This is only called if [trackCameraPosition] is true.
95+
final CameraPositionCallback onCameraMove;
96+
97+
/// Called when camera movement has ended, there are no pending
98+
/// animations and the user has stopped interacting with the map.
99+
final VoidCallback onCameraIdle;
100+
64101
/// True if a "My Location" layer should be shown on the map.
65102
///
66103
/// This layer includes a location indicator at the current device location,

packages/google_maps_flutter/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: google_maps_flutter
22
description: A Flutter plugin for integrating Google Maps in iOS and Android applications.
33
author: Flutter Team <[email protected]>
44
homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter
5-
version: 0.3.0+3
5+
version: 0.4.0
66

77
dependencies:
88
flutter:

0 commit comments

Comments
 (0)