-
Notifications
You must be signed in to change notification settings - Fork 9.8k
[google_maps_flutter] Fix the visual jarring during the first gesture on the map #2629
Conversation
We don't have a good way currently to test the visual animation on google map, can we get an exemption from testing? As it is a simple change. @amirh |
test? |
change:(NSDictionary*)change | ||
context:(void*)context { | ||
if (object == _mapView && [keyPath isEqualToString:@"frame"]) { | ||
[_mapView moveCamera:[GMSCameraUpdate setCamera:_mapView.camera]]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the intended behavior if a the map frame is resized while it's being animated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case, this method will get called multiple times. However, since we are always setting the camera to the same location, it shouldn't have any behavior effects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
animateWithCameraUpdate is implemented by multiple calls to moveCamera
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made this only happens once during initialization, so it shouldn't have any side effects that you worried about.
// `onMapCreated` is called before the map is actually ready on the platform thread. | ||
// Wait for a second until the map is settled down. | ||
await tester.pumpAndSettle(); | ||
await Future.delayed(Duration(seconds: 1)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have a reliable way to detect when it's ready?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless we add a new callback API in the google map, something like "onMapRendered". This can be in a separate PR tho.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should do that, I'm not blocking this PR since we're trading a 3 seconds timer with a 1 second one , but we should at least add a TODO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do!
@amirh Ready for another review. |
This PR is compatible with the upcoming google_maps_flutter federation PR. |
We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google. ℹ️ Googlers: Go here for more info. |
4bbb047
to
ba74639
Compare
CLAs look good, thanks! ℹ️ Googlers: Go here for more info. |
ba74639
to
5fea81d
Compare
5fea81d
to
8a7c3bb
Compare
// We ignore this type of changes. | ||
return; | ||
} | ||
_cameraDidInitialSetup = YES; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not remove the observer here instead of on the next frame change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point! Thanks. will change.
@@ -511,8 +526,8 @@ - (void)mapView:(GMSMapView*)mapView didLongPressAtCoordinate:(CLLocationCoordin | |||
|
|||
static NSDictionary* PointToJson(CGPoint point) { | |||
return @{ | |||
@"x" : @((int)point.x), | |||
@"y" : @((int)point.y), | |||
@"x" : @((int)(point.x + 0.5)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- 0.5?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to round to the closest int.
The current code is getting a floor, which is less accurate.
updating to use lroundf
to make it more self explanatory.
CGRect bounds = _mapView.bounds; | ||
if (CGRectEqualToRect(bounds, CGRectZero)) { | ||
// Rerely, frame can change without actually changing the size of the view; | ||
// eg, consider a frame change such as: (0, 0, 0, 0) -> (10, 10, 0, 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean (0, 0, 0, 0) -> (10, 10, 10, 10) ?
Is this not the change we get any time we "move" a map? (is that rare?)
I see why we can ignore these changes - this whole thing is working around an issue with our initial frame being sized to zero, but if a consequent frame is zero there's nothing to workaround really... (what I'm saying the code makes sense to me, the comment makes less sense)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about just:
// The workaround is to fix an issue that the camera location is not current when
// the size of the map is zero at initialization.
// So We only care about the size of the `_mapView`, ignore the frame changes when the size is zero.
@@ -906,5 +940,5 @@ void main() { | |||
final GoogleMapInspector inspector = await inspectorCompleter.future; | |||
final Uint8List bytes = await inspector.takeSnapshot(); | |||
expect(bytes?.isNotEmpty, true); | |||
}); | |||
}, skip: true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are we skipping this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
skipped by mistake, will fix
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@amirh Updated based on your comment! PTAL
@@ -906,5 +940,5 @@ void main() { | |||
final GoogleMapInspector inspector = await inspectorCompleter.future; | |||
final Uint8List bytes = await inspector.takeSnapshot(); | |||
expect(bytes?.isNotEmpty, true); | |||
}); | |||
}, skip: true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
skipped by mistake, will fix
CGRect bounds = _mapView.bounds; | ||
if (CGRectEqualToRect(bounds, CGRectZero)) { | ||
// Rerely, frame can change without actually changing the size of the view; | ||
// eg, consider a frame change such as: (0, 0, 0, 0) -> (10, 10, 0, 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about just:
// The workaround is to fix an issue that the camera location is not current when
// the size of the map is zero at initialization.
// So We only care about the size of the `_mapView`, ignore the frame changes when the size is zero.
@@ -511,8 +526,8 @@ - (void)mapView:(GMSMapView*)mapView didLongPressAtCoordinate:(CLLocationCoordin | |||
|
|||
static NSDictionary* PointToJson(CGPoint point) { | |||
return @{ | |||
@"x" : @((int)point.x), | |||
@"y" : @((int)point.y), | |||
@"x" : @((int)(point.x + 0.5)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to round to the closest int.
The current code is getting a floor, which is less accurate.
updating to use lroundf
to make it more self explanatory.
// We ignore this type of changes. | ||
return; | ||
} | ||
_cameraDidInitialSetup = YES; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point! Thanks. will change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
(once presubmits pass)
the crash seems to be something new related to google map sdk |
Description
Instead of workaround in the first delegate callback. We reset the camera location when we know the frame of the
GMSMapView
is changed. This prevents any unwanted artifacts introduced due to the previous workaround.Related Issues
flutter/flutter#53428
flutter/flutter#27550
Checklist
Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes (
[x]
). This will ensure a smooth and quick review process.///
).flutter analyze
) does not report any problems on my PR.Breaking Change
Does your PR require plugin users to manually update their apps to accommodate your change?