[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
diff --git a/packages/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/CHANGELOG.md
index 618af9b..36915e5 100644
--- a/packages/google_maps_flutter/CHANGELOG.md
+++ b/packages/google_maps_flutter/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 0.4.0
+
+* Change events are call backs on GoogleMap widget.
+* GoogleMapController no longer handles change events.
+
## 0.3.0+3
* Update Android play-services-maps to 16.1.0
diff --git a/packages/google_maps_flutter/example/lib/map_ui.dart b/packages/google_maps_flutter/example/lib/map_ui.dart
index 993bddd..486d87b 100644
--- a/packages/google_maps_flutter/example/lib/map_ui.dart
+++ b/packages/google_maps_flutter/example/lib/map_ui.dart
@@ -36,8 +36,8 @@
zoom: 11.0,
);
- GoogleMapController mapController;
CameraPosition _position = _kInitialPosition;
+ bool _isMapCreated = false;
bool _isMoving = false;
bool _compassEnabled = true;
CameraTargetBounds _cameraTargetBounds = CameraTargetBounds.unbounded;
@@ -54,20 +54,8 @@
super.initState();
}
- void _onMapChanged() {
- setState(() {
- _extractMapInfo();
- });
- }
-
- void _extractMapInfo() {
- _position = mapController.cameraPosition;
- _isMoving = mapController.isCameraMoving;
- }
-
@override
void dispose() {
- mapController.removeListener(_onMapChanged);
super.dispose();
}
@@ -197,6 +185,7 @@
tiltGesturesEnabled: _tiltGesturesEnabled,
zoomGesturesEnabled: _zoomGesturesEnabled,
myLocationEnabled: _myLocationEnabled,
+ onCameraMove: _updateCameraPosition,
);
final List<Widget> columnChildren = <Widget>[
@@ -212,7 +201,7 @@
),
];
- if (mapController != null) {
+ if (_isMapCreated) {
columnChildren.add(
Expanded(
child: ListView(
@@ -245,10 +234,15 @@
);
}
+ void _updateCameraPosition(CameraPosition position) {
+ setState(() {
+ _position = position;
+ });
+ }
+
void onMapCreated(GoogleMapController controller) {
- mapController = controller;
- mapController.addListener(_onMapChanged);
- _extractMapInfo();
- setState(() {});
+ setState(() {
+ _isMapCreated = true;
+ });
}
}
diff --git a/packages/google_maps_flutter/lib/src/controller.dart b/packages/google_maps_flutter/lib/src/controller.dart
index ecfc4d8..3d56400 100644
--- a/packages/google_maps_flutter/lib/src/controller.dart
+++ b/packages/google_maps_flutter/lib/src/controller.dart
@@ -5,22 +5,13 @@
part of google_maps_flutter;
/// Controller for a single GoogleMap instance running on the host platform.
-///
-/// Change listeners are notified upon changes to any of
-///
-/// * the [options] property
-/// * the [isCameraMoving] property
-/// * the [cameraPosition] property
-///
-/// Listeners are notified after changes have been applied on the platform side.
-class GoogleMapController extends ChangeNotifier {
+class GoogleMapController {
GoogleMapController._(
MethodChannel channel,
CameraPosition initialCameraPosition,
this._googleMapState,
) : assert(channel != null),
_channel = channel {
- _cameraPosition = initialCameraPosition;
_channel.setMethodCallHandler(_handleMethodCall);
}
@@ -45,30 +36,26 @@
final MethodChannel _channel;
- /// True if the map camera is currently moving.
- bool get isCameraMoving => _isCameraMoving;
- bool _isCameraMoving = false;
-
final _GoogleMapState _googleMapState;
- /// Returns the most recent camera position reported by the platform side.
- /// Will be null, if [GoogleMap.trackCameraPosition] is false.
- CameraPosition get cameraPosition => _cameraPosition;
- CameraPosition _cameraPosition;
-
Future<dynamic> _handleMethodCall(MethodCall call) async {
switch (call.method) {
case 'camera#onMoveStarted':
- _isCameraMoving = true;
- notifyListeners();
+ if (_googleMapState.widget.onCameraMoveStarted != null) {
+ _googleMapState.widget.onCameraMoveStarted();
+ }
break;
case 'camera#onMove':
- _cameraPosition = CameraPosition.fromMap(call.arguments['position']);
- notifyListeners();
+ if (_googleMapState.widget.onCameraMove != null) {
+ _googleMapState.widget.onCameraMove(
+ CameraPosition.fromMap(call.arguments['position']),
+ );
+ }
break;
case 'camera#onIdle':
- _isCameraMoving = false;
- notifyListeners();
+ if (_googleMapState.widget.onCameraIdle != null) {
+ _googleMapState.widget.onCameraIdle();
+ }
break;
case 'marker#onTap':
_googleMapState.onMarkerTap(call.arguments['markerId']);
@@ -92,14 +79,12 @@
// TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter.
// https://github.com/flutter/flutter/issues/26431
// ignore: strong_mode_implicit_dynamic_method
- final dynamic json = await _channel.invokeMethod(
+ await _channel.invokeMethod(
'map#update',
<String, dynamic>{
'options': optionsUpdate,
},
);
- _cameraPosition = CameraPosition.fromMap(json);
- notifyListeners();
}
/// Updates marker configuration.
@@ -117,7 +102,6 @@
'markers#update',
markerUpdates._toMap(),
);
- notifyListeners();
}
/// Starts an animated change of the map camera position.
diff --git a/packages/google_maps_flutter/lib/src/google_map.dart b/packages/google_maps_flutter/lib/src/google_map.dart
index 365ac0c..fca62f1 100644
--- a/packages/google_maps_flutter/lib/src/google_map.dart
+++ b/packages/google_maps_flutter/lib/src/google_map.dart
@@ -6,6 +6,15 @@
typedef void MapCreatedCallback(GoogleMapController controller);
+/// Callback that receives updates to the camera position.
+///
+/// This callback is triggered when the platform Google Map
+/// registers a camera movement. This will be called with null if
+/// [GoogleMap.trackCameraPosition] is false.
+///
+/// This is used in [GoogleMap.onCameraMove] and [GoogleMap.onMapOptionsUpdate].
+typedef void CameraPositionCallback(CameraPosition position);
+
class GoogleMap extends StatefulWidget {
const GoogleMap({
@required this.initialCameraPosition,
@@ -22,6 +31,9 @@
this.trackCameraPosition = false,
this.myLocationEnabled = false,
this.markers,
+ this.onCameraMoveStarted,
+ this.onCameraMove,
+ this.onCameraIdle,
}) : assert(initialCameraPosition != null);
final MapCreatedCallback onMapCreated;
@@ -58,9 +70,34 @@
/// True if the map view should relay camera move events to Flutter.
final bool trackCameraPosition;
- // Markers to be placed on the map.
+ /// Markers to be placed on the map.
final Set<Marker> markers;
+ /// Called when the camera starts moving.
+ ///
+ /// This can be initiated by the following:
+ /// 1. Non-gesture animation initiated in response to user actions.
+ /// For example: zoom buttons, my location button, or marker clicks.
+ /// 2. Programmatically initiated animation.
+ /// 3. Camera motion initiated in response to user gestures on the map.
+ /// For example: pan, tilt, pinch to zoom, or rotate.
+ ///
+ /// Note: This is callback is called even if [trackCameraPosition] is false.
+ final VoidCallback onCameraMoveStarted;
+
+ /// Called repeatedly as the camera continues to move after an
+ /// onCameraMoveStarted call.
+ ///
+ /// This may be called as often as once every frame and should
+ /// not perform expensive operations.
+ ///
+ /// This is only called if [trackCameraPosition] is true.
+ final CameraPositionCallback onCameraMove;
+
+ /// Called when camera movement has ended, there are no pending
+ /// animations and the user has stopped interacting with the map.
+ final VoidCallback onCameraIdle;
+
/// True if a "My Location" layer should be shown on the map.
///
/// This layer includes a location indicator at the current device location,
diff --git a/packages/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/pubspec.yaml
index 4aadb3f..81169e4 100644
--- a/packages/google_maps_flutter/pubspec.yaml
+++ b/packages/google_maps_flutter/pubspec.yaml
@@ -2,7 +2,7 @@
description: A Flutter plugin for integrating Google Maps in iOS and Android applications.
author: Flutter Team <flutter-dev@googlegroups.com>
homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter
-version: 0.3.0+3
+version: 0.4.0
dependencies:
flutter: