Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f82ed95f authored by Robin Lee's avatar Robin Lee
Browse files

AnimatedBoundsLayoutListener jump-cuts rotations

This OnLayoutChangeListener animates smoothly between old and new
onscreen bounds of the View, but this only works well if its frame of
reference is not changing underneath it. When the parent bounds are
changing due to rotation, resize, or translation, detect that and
leave the View bounds alone.

Test: manual (open Internet settings, rotate screen 3x)
Flag: EXEMPT bugfix
Fix: 267689502
Change-Id: I383bd6a94128bc3542a914040b1dafe259058b27
parent 6d3ea7d0
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -1057,6 +1057,7 @@ private class AnimatedDialog(
        }

        private var lastBounds: Rect? = null
        private var lastParentBounds: Rect? = null
        private var currentAnimator: ValueAnimator? = null

        override fun onLayoutChange(
@@ -1070,6 +1071,11 @@ private class AnimatedDialog(
            oldRight: Int,
            oldBottom: Int,
        ) {
            val oldParentBounds = lastParentBounds
            (view.parent as ViewGroup)?.let { p ->
                lastParentBounds = Rect(p.left, p.top, p.right, p.bottom)
            }

            // Don't animate if bounds didn't actually change.
            if (left == oldLeft && top == oldTop && right == oldRight && bottom == oldBottom) {
                // Make sure that we that the last bounds set by the animator were not overridden.
@@ -1092,9 +1098,16 @@ private class AnimatedDialog(
            val startRight = bounds.right
            val startBottom = bounds.bottom

            currentAnimator?.removeAllListeners()
            currentAnimator?.cancel()
            currentAnimator = null

            // When bounds changed only because parent's bounds also changed, don't animate.
            if (lastParentBounds != oldParentBounds && oldParentBounds != null) {
                lastBounds?.set(left, top, right, bottom)
                return
            }

            val animator =
                ValueAnimator.ofFloat(0f, 1f).apply {
                    duration = ANIMATION_DURATION