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

Commit 0dc4634c authored by Luca Zuccarini's avatar Luca Zuccarini
Browse files

Remove the temporary bounds workaround from ViewBoundAnimator.

Bug: 221418522
Test: manual and unit tests included
Change-Id: I3219f3c2fd9537b751af098eabe6877da8493c04
parent a830367d
Loading
Loading
Loading
Loading
+12 −27
Original line number Diff line number Diff line
@@ -37,7 +37,6 @@ class ViewHierarchyAnimator {
        private const val DEFAULT_DURATION = 500L
        private val DEFAULT_INTERPOLATOR = Interpolators.STANDARD
        private val DEFAULT_ADDITION_INTERPOLATOR = Interpolators.STANDARD_DECELERATE
        private val DEFAULT_BOUNDS = setOf(Bound.LEFT, Bound.TOP, Bound.RIGHT, Bound.BOTTOM)

        /** The properties used to animate the view bounds. */
        private val PROPERTIES = mapOf(
@@ -61,8 +60,7 @@ class ViewHierarchyAnimator {

        /**
         * Instruct the animator to watch for changes to the layout of [rootView] and its children
         * and animate them. The animation can be limited to a subset of [bounds]. It uses the
         * given [interpolator] and [duration].
         * and animate them. It uses the given [interpolator] and [duration].
         *
         * If a new layout change happens while an animation is already in progress, the animation
         * is updated to continue from the current values to the new end state.
@@ -74,40 +72,31 @@ class ViewHierarchyAnimator {
         *
         * Returns true if the [rootView] is already visible and will be animated, false otherwise.
         * To animate the addition of a view, see [animateAddition].
         *
         * TODO(b/221418522): remove the ability to select which bounds to animate and always
         * animate all of them.
         */
        @JvmOverloads
        fun animate(
            rootView: View,
            bounds: Set<Bound> = DEFAULT_BOUNDS,
            interpolator: Interpolator = DEFAULT_INTERPOLATOR,
            duration: Long = DEFAULT_DURATION
        ): Boolean {
            return animate(rootView, bounds, interpolator, duration, ephemeral = false)
            return animate(rootView, interpolator, duration, ephemeral = false)
        }

        /**
         * Like [animate], but only takes effect on the next layout update, then unregisters itself
         * once the first animation is complete.
         *
         * TODO(b/221418522): remove the ability to select which bounds to animate and always
         * animate all of them.
         */
        @JvmOverloads
        fun animateNextUpdate(
            rootView: View,
            bounds: Set<Bound> = DEFAULT_BOUNDS,
            interpolator: Interpolator = DEFAULT_INTERPOLATOR,
            duration: Long = DEFAULT_DURATION
        ): Boolean {
            return animate(rootView, bounds, interpolator, duration, ephemeral = true)
            return animate(rootView, interpolator, duration, ephemeral = true)
        }

        private fun animate(
            rootView: View,
            bounds: Set<Bound>,
            interpolator: Interpolator,
            duration: Long,
            ephemeral: Boolean
@@ -123,26 +112,24 @@ class ViewHierarchyAnimator {
                return false
            }

            val listener = createUpdateListener(bounds, interpolator, duration, ephemeral)
            val listener = createUpdateListener(interpolator, duration, ephemeral)
            recursivelyAddListener(rootView, listener)
            return true
        }

        /**
         * Returns a new [View.OnLayoutChangeListener] that when called triggers a layout animation
         * for the specified [bounds], using [interpolator] and [duration].
         * using [interpolator] and [duration].
         *
         * If [ephemeral] is true, the listener is unregistered after the first animation. Otherwise
         * it keeps listening for further updates.
         */
        private fun createUpdateListener(
            bounds: Set<Bound>,
            interpolator: Interpolator,
            duration: Long,
            ephemeral: Boolean
        ): View.OnLayoutChangeListener {
            return createListener(
                bounds,
                interpolator,
                duration,
                ephemeral
@@ -224,7 +211,6 @@ class ViewHierarchyAnimator {
            ignorePreviousValues: Boolean
        ): View.OnLayoutChangeListener {
            return createListener(
                DEFAULT_BOUNDS,
                interpolator,
                duration,
                ephemeral = true,
@@ -235,7 +221,7 @@ class ViewHierarchyAnimator {

        /**
         * Returns a new [View.OnLayoutChangeListener] that when called triggers a layout animation
         * for the specified [bounds], using [interpolator] and [duration].
         * using [interpolator] and [duration].
         *
         * If [ephemeral] is true, the listener is unregistered after the first animation. Otherwise
         * it keeps listening for further updates.
@@ -244,7 +230,6 @@ class ViewHierarchyAnimator {
         * [ignorePreviousValues] controls whether the previous values should be taken into account.
         */
        private fun createListener(
            bounds: Set<Bound>,
            interpolator: Interpolator,
            duration: Long,
            ephemeral: Boolean,
@@ -300,10 +285,11 @@ class ViewHierarchyAnimator {
                    )

                    val boundsToAnimate = mutableSetOf<Bound>()
                    bounds.forEach { bound ->
                        if (endValues.getValue(bound) != startValues.getValue(bound)) {
                            boundsToAnimate.add(bound)
                        }
                    if (startValues.getValue(Bound.LEFT) != left) boundsToAnimate.add(Bound.LEFT)
                    if (startValues.getValue(Bound.TOP) != top) boundsToAnimate.add(Bound.TOP)
                    if (startValues.getValue(Bound.RIGHT) != right) boundsToAnimate.add(Bound.RIGHT)
                    if (startValues.getValue(Bound.BOTTOM) != bottom) {
                        boundsToAnimate.add(Bound.BOTTOM)
                    }

                    if (boundsToAnimate.isNotEmpty()) {
@@ -538,8 +524,7 @@ class ViewHierarchyAnimator {
        CENTER, LEFT, TOP_LEFT, TOP, TOP_RIGHT, RIGHT, BOTTOM_RIGHT, BOTTOM, BOTTOM_LEFT
    }

    // TODO(b/221418522): make this private once it can't be passed as an arg anymore.
    enum class Bound(val label: String, val overrideTag: Int) {
    private enum class Bound(val label: String, val overrideTag: Int) {
        LEFT("left", R.id.tag_override_left) {
            override fun setValue(view: View, value: Int) {
                view.left = value
+2 −22
Original line number Diff line number Diff line
@@ -21,7 +21,8 @@ import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper
class ViewHierarchyAnimatorTest : SysuiTestCase() {
class
ViewHierarchyAnimatorTest : SysuiTestCase() {
    companion object {
        private const val TEST_DURATION = 1000L
        private val TEST_INTERPOLATOR = Interpolators.LINEAR
@@ -624,27 +625,6 @@ class ViewHierarchyAnimatorTest : SysuiTestCase() {
        checkBounds(rootView, l = 10, t = 10, r = 70, b = 80)
    }

    @Test
    fun doesNotAnimateExcludedBounds() {
        rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */)

        val success = ViewHierarchyAnimator.animate(
            rootView,
            bounds = setOf(ViewHierarchyAnimator.Bound.LEFT, ViewHierarchyAnimator.Bound.TOP),
            interpolator = TEST_INTERPOLATOR
        )
        // Change all bounds.
        rootView.layout(0 /* l */, 20 /* t */, 70 /* r */, 80 /* b */)

        assertTrue(success)
        assertNotNull(rootView.getTag(R.id.tag_animator))
        advanceAnimation(rootView, 0.5f)
        checkBounds(rootView, l = 5, t = 15, r = 70, b = 80)
        endAnimation(rootView)
        assertNull(rootView.getTag(R.id.tag_animator))
        checkBounds(rootView, l = 0, t = 20, r = 70, b = 80)
    }

    @Test
    fun stopsAnimatingAfterSingleLayout() {
        rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */)