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 1 commit
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
31 changes: 13 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
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,8 @@ class MapUiBodyState extends State<MapUiBody> {
tiltGesturesEnabled: _tiltGesturesEnabled,
zoomGesturesEnabled: _zoomGesturesEnabled,
myLocationEnabled: _myLocationEnabled,
onCameraMove: _updateCameraPosition,
onMapOptionsUpdate: _updateCameraPosition,
);

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

if (mapController != null) {
if (_isMapCreated) {
columnChildren.add(
Expanded(
child: ListView(
Expand Down Expand Up @@ -245,10 +235,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;
});
}
}
48 changes: 20 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,11 @@ class GoogleMapController extends ChangeNotifier {
'options': optionsUpdate,
},
);
_cameraPosition = CameraPosition.fromMap(json);
notifyListeners();
if (_googleMapState.widget.onMapOptionsUpdate != null) {
_googleMapState.widget.onMapOptionsUpdate(
CameraPosition.fromMap(json),
);
}
}

/// Updates marker configuration.
Expand All @@ -117,7 +107,9 @@ class GoogleMapController extends ChangeNotifier {
'markers#update',
markerUpdates._toMap(),
);
notifyListeners();
if (_googleMapState.widget.onMarkersUpdate != null) {
_googleMapState.widget.onMarkersUpdate();
}
}

/// Starts an animated change of the map camera position.
Expand Down
27 changes: 26 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,11 @@ part of google_maps_flutter;

typedef void MapCreatedCallback(GoogleMapController controller);

/// Callback that tracks camera position.
Copy link
Contributor

Choose a reason for hiding this comment

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

Callback for getting updates on a new camera position?

///
Copy link
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.

/// Will be null if trackCameraPosition on [GoogleMap] is false.
Copy link
Contributor

Choose a reason for hiding this comment

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

What will be null?

typedef void CameraPositionCallback(CameraPosition position);

class GoogleMap extends StatefulWidget {
const GoogleMap({
@required this.initialCameraPosition,
Expand All @@ -22,6 +27,11 @@ class GoogleMap extends StatefulWidget {
this.trackCameraPosition = false,
this.myLocationEnabled = false,
this.markers,
this.onCameraMoveStarted,
this.onCameraMove,
this.onCameraIdle,
this.onMapOptionsUpdate,
this.onMarkersUpdate,
}) : assert(initialCameraPosition != null);

final MapCreatedCallback onMapCreated;
Expand Down Expand Up @@ -58,9 +68,24 @@ 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;

/// Callback for when the camera move started.
Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn't add much information.
https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#avoid-useless-documentation

Documentation is definitely hard 😄 I sometimes find the prompts here helpful:
https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#writing-prompts-for-good-documentation

Some questions I might have been looking for answers in the docs are: is this called on the first time the map is loaded? is this called when the position is updated programmatically?

(similar comments to the docs of the other new fields below)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great read. Will revise the docs based on this.

final VoidCallback onCameraMoveStarted;

/// Callback for when the camera is moving.
Copy link
Contributor

Choose a reason for hiding this comment

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

This should probably say something about [GoogleMap.trackCameraPosition]

final CameraPositionCallback onCameraMove;

/// Callback for when the camera has entered an idle stage.
final VoidCallback onCameraIdle;

/// Callback when the [GoogleMap] options have been applied on the platform.
final CameraPositionCallback onMapOptionsUpdate;
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if the onOptionsUpdate and onMarkersUpdate callback are really needed? do you have some concrete use-cases in mind?
We can always add fields later, but removing will be a breaking API change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They provide a way for users to know when the platform has "committed" the update. It might be useful to take an action based on it. We could remove them, I put them here to maintain compatibility with the behavior before.


/// Callback for when the [Marker] options have been applied on the platform.
final VoidCallback onMarkersUpdate;

/// 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