Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 3 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
30 changes: 12 additions & 18 deletions packages/google_maps_flutter/example/lib/map_ui.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ class MapUiBodyState extends State<MapUiBody> {
zoom: 11.0,
);

GoogleMapController mapController;

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.

That's nice to see!

CameraPosition _position = _kInitialPosition;
bool _isMapCreated = false;
bool _isMoving = false;
bool _compassEnabled = true;
CameraTargetBounds _cameraTargetBounds = CameraTargetBounds.unbounded;
Expand All @@ -54,20 +54,8 @@ class MapUiBodyState extends State<MapUiBody> {
super.initState();
}

void _onMapChanged() {
setState(() {
_extractMapInfo();
});
}

void _extractMapInfo() {
_position = mapController.cameraPosition;
_isMoving = mapController.isCameraMoving;
}

@override
void dispose() {
mapController.removeListener(_onMapChanged);
super.dispose();
}

Expand Down Expand Up @@ -197,6 +185,7 @@ class MapUiBodyState extends State<MapUiBody> {
tiltGesturesEnabled: _tiltGesturesEnabled,
zoomGesturesEnabled: _zoomGesturesEnabled,
myLocationEnabled: _myLocationEnabled,
onCameraMove: _updateCameraPosition,
);

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

if (mapController != null) {
if (_isMapCreated) {
columnChildren.add(
Expanded(
child: ListView(
Expand Down Expand Up @@ -245,10 +234,15 @@ class MapUiBodyState extends State<MapUiBody> {
);
}

void _updateCameraPosition(CameraPosition position) {
setState(() {
_position = position;
});
}

void onMapCreated(GoogleMapController controller) {
mapController = controller;
mapController.addListener(_onMapChanged);
_extractMapInfo();
setState(() {});
setState(() {
_isMapCreated = true;
});
}
}
40 changes: 12 additions & 28 deletions packages/google_maps_flutter/lib/src/controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

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

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']);
Expand Down Expand Up @@ -98,8 +85,6 @@ class GoogleMapController extends ChangeNotifier {
'options': optionsUpdate,
},
);
_cameraPosition = CameraPosition.fromMap(json);
notifyListeners();
}

/// Updates marker configuration.
Expand All @@ -117,7 +102,6 @@ class GoogleMapController extends ChangeNotifier {
'markers#update',
markerUpdates._toMap(),
);
notifyListeners();
}

/// Starts an animated change of the map camera position.
Expand Down
39 changes: 38 additions & 1 deletion packages/google_maps_flutter/lib/src/google_map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ part of google_maps_flutter;

typedef void MapCreatedCallback(GoogleMapController controller);

/// Callback that receives updates to the camera position.
///

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.

Probably worth adding "Used by: " and listing the relevant GoogleMap fields.

/// This callback is triggered when the platform google map

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.

nit: 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,
Expand All @@ -22,6 +31,9 @@ class GoogleMap extends StatefulWidget {
this.trackCameraPosition = false,
this.myLocationEnabled = false,
this.markers,
this.onCameraMoveStarted,
this.onCameraMove,
this.onCameraIdle,
}) : assert(initialCameraPosition != null);

final MapCreatedCallback onMapCreated;
Expand Down Expand Up @@ -58,9 +70,34 @@ class GoogleMap extends StatefulWidget {
/// 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. Developer initiated animation.

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.

nit: I'd call it "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 callback is not called when trackCameraPosition is false.

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.

link trackCameraPosotion.

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.

nit: since the default for trackCameraPosition is false, I'll reverse the negation (This is only called if [trackCameraPosition] is false).

BTW does it never gets called if trackCameraPosition is false? in that case maybe it would make sense to get rid of trackCameraPosition and use the presence of this callback as the flag?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I am pro getting rid of trackCameraPosition entirely, it's a notion introduced by the plugin and not something that is native to Google Map platform implementations. Cool if i do it in a follow up PR?

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.

SGTM

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,
Expand Down