Merge "[Taskbar icons unfold animation issue] Do not take into account initial translation" into sc-v2-dev

This commit is contained in:
Nick Chameyev
2021-09-10 12:25:17 +00:00
committed by Android (Google) Code Review
2 changed files with 70 additions and 39 deletions

View File

@@ -16,7 +16,6 @@
package com.android.systemui.shared.animation package com.android.systemui.shared.animation
import android.graphics.Point import android.graphics.Point
import android.util.MathUtils.lerp
import android.view.Surface import android.view.Surface
import android.view.View import android.view.View
import android.view.WindowManager import android.view.WindowManager
@@ -27,7 +26,7 @@ import java.lang.ref.WeakReference
* Creates an animation where all registered views are moved into their final location * Creates an animation where all registered views are moved into their final location
* by moving from the center of the screen to the sides * by moving from the center of the screen to the sides
*/ */
class UnfoldMoveFromCenterAnimator( class UnfoldMoveFromCenterAnimator @JvmOverloads constructor(
private val windowManager: WindowManager, private val windowManager: WindowManager,
/** /**
* Allows to set custom translation applier * Allows to set custom translation applier
@@ -36,14 +35,13 @@ class UnfoldMoveFromCenterAnimator(
* using custom methods instead of [View.setTranslationX] or * using custom methods instead of [View.setTranslationX] or
* [View.setTranslationY] * [View.setTranslationY]
*/ */
var translationApplier: TranslationApplier = object : TranslationApplier {} private val translationApplier: TranslationApplier = object : TranslationApplier {},
) : UnfoldTransitionProgressProvider.TransitionProgressListener { ) : UnfoldTransitionProgressProvider.TransitionProgressListener {
private val screenSize = Point() private val screenSize = Point()
private var isVerticalFold = false private var isVerticalFold = false
private val animatedViews: MutableList<AnimatedView> = arrayListOf() private val animatedViews: MutableList<AnimatedView> = arrayListOf()
private val tmpArray = IntArray(2)
/** /**
* Updates display properties in order to calculate the initial position for the views * Updates display properties in order to calculate the initial position for the views
@@ -82,45 +80,52 @@ class UnfoldMoveFromCenterAnimator(
it.view.get()?.let { view -> it.view.get()?.let { view ->
translationApplier.apply( translationApplier.apply(
view = view, view = view,
x = lerp(it.startTranslationX, it.finishTranslationX, progress), x = it.startTranslationX * (1 - progress),
y = lerp(it.startTranslationY, it.finishTranslationY, progress) y = it.startTranslationY * (1 - progress)
) )
} }
} }
} }
private fun createAnimatedView(view: View): AnimatedView { private fun createAnimatedView(view: View): AnimatedView {
val viewLocation = tmpArray val viewCenter = getViewCenter(view)
view.getLocationOnScreen(viewLocation) val viewCenterX = viewCenter.x
val viewCenterY = viewCenter.y
val viewX = viewLocation[0].toFloat() val translationX: Float
val viewY = viewLocation[1].toFloat() val translationY: Float
val viewCenterX = viewX + view.width / 2
val viewCenterY = viewY + view.height / 2
val translationXDiff: Float
val translationYDiff: Float
if (isVerticalFold) { if (isVerticalFold) {
val distanceFromScreenCenterToViewCenter = screenSize.x / 2 - viewCenterX val distanceFromScreenCenterToViewCenter = screenSize.x / 2 - viewCenterX
translationXDiff = distanceFromScreenCenterToViewCenter * TRANSLATION_PERCENTAGE translationX = distanceFromScreenCenterToViewCenter * TRANSLATION_PERCENTAGE
translationYDiff = 0f translationY = 0f
} else { } else {
val distanceFromScreenCenterToViewCenter = screenSize.y / 2 - viewCenterY val distanceFromScreenCenterToViewCenter = screenSize.y / 2 - viewCenterY
translationXDiff = 0f translationX = 0f
translationYDiff = distanceFromScreenCenterToViewCenter * TRANSLATION_PERCENTAGE translationY = distanceFromScreenCenterToViewCenter * TRANSLATION_PERCENTAGE
} }
return AnimatedView( return AnimatedView(
view = WeakReference(view), view = WeakReference(view),
startTranslationX = view.translationX + translationXDiff, startTranslationX = translationX,
startTranslationY = view.translationY + translationYDiff, startTranslationY = translationY
finishTranslationX = view.translationX,
finishTranslationY = view.translationY
) )
} }
private fun getViewCenter(view: View): Point {
val viewLocation = IntArray(2)
view.getLocationOnScreen(viewLocation)
val viewX = viewLocation[0]
val viewY = viewLocation[1]
val outPoint = Point()
outPoint.x = viewX + view.width / 2
outPoint.y = viewY + view.height / 2
return outPoint
}
/** /**
* Interface that allows to use custom logic to apply translation to view * Interface that allows to use custom logic to apply translation to view
*/ */
@@ -137,9 +142,7 @@ class UnfoldMoveFromCenterAnimator(
private class AnimatedView( private class AnimatedView(
val view: WeakReference<View>, val view: WeakReference<View>,
val startTranslationX: Float, val startTranslationX: Float,
val startTranslationY: Float, val startTranslationY: Float
val finishTranslationX: Float,
val finishTranslationY: Float
) )
} }

View File

@@ -56,45 +56,71 @@ class UnfoldMoveFromCenterAnimatorTest : SysuiTestCase() {
@Test @Test
fun testRegisterViewOnTheLeftOfVerticalFold_halfProgress_viewTranslatedToTheRight() { fun testRegisterViewOnTheLeftOfVerticalFold_halfProgress_viewTranslatedToTheRight() {
givenScreen(width = 100, height = 100, rotation = ROTATION_0) givenScreen(width = 100, height = 100, rotation = ROTATION_0)
val view = createView(x = 20) val view = createView(x = 20, width = 10, height = 10)
animator.registerViewForAnimation(view) animator.registerViewForAnimation(view)
animator.onTransitionStarted() animator.onTransitionStarted()
animator.onTransitionProgress(0.5f) animator.onTransitionProgress(0.5f)
// Positive translationX -> translated to the right // Positive translationX -> translated to the right
assertThat(view.translationX).isWithin(0.1f).of(3.75f) // 10x10 view center is 25px from the center,
// When progress is 0.5 it should be translated at:
// 25 * 0.3 * (1 - 0.5) = 3.75px
assertThat(view.translationX).isWithin(0.01f).of(3.75f)
} }
@Test @Test
fun testRegisterViewOnTheLeftOfVerticalFold_zeroProgress_viewTranslatedToTheRight() { fun testRegisterViewOnTheLeftOfVerticalFold_zeroProgress_viewTranslatedToTheRight() {
givenScreen(width = 100, height = 100, rotation = ROTATION_0) givenScreen(width = 100, height = 100, rotation = ROTATION_0)
val view = createView(x = 20) val view = createView(x = 20, width = 10, height = 10)
animator.registerViewForAnimation(view) animator.registerViewForAnimation(view)
animator.onTransitionStarted() animator.onTransitionStarted()
animator.onTransitionProgress(0f) animator.onTransitionProgress(0f)
// Positive translationX -> translated to the right // Positive translationX -> translated to the right
assertThat(view.translationX).isWithin(0.1f).of(7.5f) // 10x10 view center is 25px from the center,
// When progress is 0 it should be translated at:
// 25 * 0.3 * (1 - 0) = 7.5px
assertThat(view.translationX).isWithin(0.01f).of(7.5f)
} }
@Test @Test
fun testRegisterViewOnTheLeftOfVerticalFold_fullProgress_viewTranslatedToTheOriginalPosition() { fun testRegisterViewOnTheLeftOfVerticalFold_fullProgress_viewTranslatedToTheOriginalPosition() {
givenScreen(width = 100, height = 100, rotation = ROTATION_0) givenScreen(width = 100, height = 100, rotation = ROTATION_0)
val view = createView(x = 20) val view = createView(x = 20, width = 10, height = 10)
animator.registerViewForAnimation(view) animator.registerViewForAnimation(view)
animator.onTransitionStarted() animator.onTransitionStarted()
animator.onTransitionProgress(1f) animator.onTransitionProgress(1f)
// Positive translationX -> translated to the right
// 10x10 view center is 25px from the center,
// When progress is 1 it should be translated at:
// 25 * 0.3 * 0 = 0px
assertThat(view.translationX).isEqualTo(0f) assertThat(view.translationX).isEqualTo(0f)
} }
@Test
fun testViewOnTheLeftOfVerticalFoldWithTranslation_halfProgress_viewTranslatedToTheRight() {
givenScreen(width = 100, height = 100, rotation = ROTATION_0)
val view = createView(x = 20, width = 10, height = 10, translationX = 100f)
animator.registerViewForAnimation(view)
animator.onTransitionStarted()
animator.onTransitionProgress(0.5f)
// Positive translationX -> translated to the right, original translation is ignored
// 10x10 view center is 25px from the center,
// When progress is 0.5 it should be translated at:
// 25 * 0.3 * (1 - 0.5) = 3.75px
assertThat(view.translationX).isWithin(0.01f).of(3.75f)
}
@Test @Test
fun testRegisterViewAndUnregister_halfProgress_viewIsNotUpdated() { fun testRegisterViewAndUnregister_halfProgress_viewIsNotUpdated() {
givenScreen(width = 100, height = 100, rotation = ROTATION_0) givenScreen(width = 100, height = 100, rotation = ROTATION_0)
val view = createView(x = 20) val view = createView(x = 20, width = 10, height = 10)
animator.registerViewForAnimation(view) animator.registerViewForAnimation(view)
animator.onTransitionStarted() animator.onTransitionStarted()
animator.clearRegisteredViews() animator.clearRegisteredViews()
@@ -107,7 +133,7 @@ class UnfoldMoveFromCenterAnimatorTest : SysuiTestCase() {
@Test @Test
fun testRegisterViewUpdateProgressAndUnregister_halfProgress_viewIsNotUpdated() { fun testRegisterViewUpdateProgressAndUnregister_halfProgress_viewIsNotUpdated() {
givenScreen(width = 100, height = 100, rotation = ROTATION_0) givenScreen(width = 100, height = 100, rotation = ROTATION_0)
val view = createView(x = 20) val view = createView(x = 20, width = 10, height = 10)
animator.registerViewForAnimation(view) animator.registerViewForAnimation(view)
animator.onTransitionStarted() animator.onTransitionStarted()
animator.onTransitionProgress(0.2f) animator.onTransitionProgress(0.2f)
@@ -121,14 +147,14 @@ class UnfoldMoveFromCenterAnimatorTest : SysuiTestCase() {
@Test @Test
fun testRegisterViewOnTheTopOfHorizontalFold_halfProgress_viewTranslatedToTheBottom() { fun testRegisterViewOnTheTopOfHorizontalFold_halfProgress_viewTranslatedToTheBottom() {
givenScreen(width = 100, height = 100, rotation = ROTATION_90) givenScreen(width = 100, height = 100, rotation = ROTATION_90)
val view = createView(y = 20) val view = createView(y = 20, width = 10, height = 10)
animator.registerViewForAnimation(view) animator.registerViewForAnimation(view)
animator.onTransitionStarted() animator.onTransitionStarted()
animator.onTransitionProgress(0.5f) animator.onTransitionProgress(0.5f)
// Positive translationY -> translated to the bottom // Positive translationY -> translated to the bottom
assertThat(view.translationY).isWithin(0.1f).of(3.75f) assertThat(view.translationY).isWithin(0.01f).of(3.75f)
} }
private fun createView( private fun createView(
@@ -156,9 +182,11 @@ class UnfoldMoveFromCenterAnimatorTest : SysuiTestCase() {
} }
} }
private fun givenScreen(width: Int = 100, private fun givenScreen(
width: Int = 100,
height: Int = 100, height: Int = 100,
rotation: Int = ROTATION_0) { rotation: Int = ROTATION_0
) {
val display = mock(Display::class.java) val display = mock(Display::class.java)
whenever(display.getSize(any())).thenAnswer { whenever(display.getSize(any())).thenAnswer {
val size = (it.arguments[0] as Point) val size = (it.arguments[0] as Point)