Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix camera animators ordering on Android 6 and lower #597

Merged
merged 2 commits into from
Sep 6, 2021

Conversation

zeac
Copy link
Contributor

@zeac zeac commented Aug 30, 2021

Pull request checklist:

  • Briefly describe the changes in this PR.
  • Include before/after visuals or gifs if this PR includes visual changes.
  • Write tests for all new functionality. If tests were not written, please explain why.
  • Add example if relevant.
  • Document any changes to public APIs.
  • Apply changelog label ('breaking change', 'bug 🪲', 'build', 'docs', 'feature 🍏', 'performance ⚡', 'testing 💯') or use the label 'skip changelog'
  • Add an entry inside this element for inclusion in the mapbox-maps-android changelog: <changelog>Fix issue with camera animators ordering on Android 6 and lower by revisiting overall approach of applying accumulated camera changes.</changelog>.

Fixes: #596

Summary of changes

The root of the problem is in the order of callbacks from ValueAnimators, that is different on Android 6. This PR changes core logic of applying animators making it easier to support and delegating updating accumulated CameraOptions to Handler instead of relying on update of "oldest" animator (which as said before is not working as expected on Android 6 and below). This should not affect camera animation in any way, the only possible drawback is applying camera changes on each animator update if user has added ValueAnimator.AnimatorUpdateListener instead of accumulating which should be a pretty rare use-case.

assertEquals(10.0, updateList[1].pitch!!, EPS)
// Both, tick and bearing are updated to the start values at first tick.
assertEquals(20.0, updateList.first().bearing!!, EPS)
assertEquals(10.0, updateList.first().pitch!!, EPS)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The resulting behavior seems like more correct that the previous one.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Originally, the test was added here - #352.

The problem i am trying to fix is similar, this solution covers them both.

@zeac zeac force-pushed the 596-fix-camera-issue branch 6 times, most recently from 4508752 to 2e5e990 Compare September 1, 2021 05:48
if (animator.haveUserListeners) {
// If the animator have third-party listeners camera changes must be applied immediately
// to be seen from the listeners.
if (commitScheduled) handler.removeCallbacks(commitChangesRunnable)
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: let's use {} even for single line and separate with new lines

Copy link
Contributor

Choose a reason for hiding this comment

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

Generally I'm seeing

if (commitScheduled) handler.removeCallbacks(commitChangesRunnable)
commitChangesRunnable.run()

for 3 times, let's move it to private function

Copy link
Contributor

Choose a reason for hiding this comment

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

@zeac so do I get it correctly that accumulating camera optimization is not working if we do have userUpdateListeners? Could there be a better way?

thanks to @LukasPaczos for stating it out.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Accumulated camera changes is flushed after value updates from Animators with third-party listeners only, so this optimization still works for NavigationCamera or GesturePlugin animations.

The only other way i see is to call all userUpdateListeners manually after camera is updated. I'm not sure that it is a better way.

Copy link
Contributor

@kiryldz kiryldz left a comment

Choose a reason for hiding this comment

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

@zeac thanks for your fantastic work in preparing this contribution!
LGTM

@kiryldz kiryldz added the bug 🪲 Something isn't working label Sep 6, 2021
@kiryldz kiryldz changed the title Fix camera twitch Fix camera animators ordering on Android 6 and lower Sep 6, 2021
@zeac zeac merged commit ceeaed8 into main Sep 6, 2021
@zeac zeac deleted the 596-fix-camera-issue branch September 6, 2021 08:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🪲 Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Camera twitches if moved during ongoing animation
2 participants