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

View File

@@ -56,45 +56,71 @@ class UnfoldMoveFromCenterAnimatorTest : SysuiTestCase() {
@Test
fun testRegisterViewOnTheLeftOfVerticalFold_halfProgress_viewTranslatedToTheRight() {
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.onTransitionStarted()
animator.onTransitionProgress(0.5f)
// 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
fun testRegisterViewOnTheLeftOfVerticalFold_zeroProgress_viewTranslatedToTheRight() {
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.onTransitionStarted()
animator.onTransitionProgress(0f)
// 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
fun testRegisterViewOnTheLeftOfVerticalFold_fullProgress_viewTranslatedToTheOriginalPosition() {
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.onTransitionStarted()
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)
}
@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
fun testRegisterViewAndUnregister_halfProgress_viewIsNotUpdated() {
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.onTransitionStarted()
animator.clearRegisteredViews()
@@ -107,7 +133,7 @@ class UnfoldMoveFromCenterAnimatorTest : SysuiTestCase() {
@Test
fun testRegisterViewUpdateProgressAndUnregister_halfProgress_viewIsNotUpdated() {
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.onTransitionStarted()
animator.onTransitionProgress(0.2f)
@@ -121,14 +147,14 @@ class UnfoldMoveFromCenterAnimatorTest : SysuiTestCase() {
@Test
fun testRegisterViewOnTheTopOfHorizontalFold_halfProgress_viewTranslatedToTheBottom() {
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.onTransitionStarted()
animator.onTransitionProgress(0.5f)
// 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(
@@ -156,9 +182,11 @@ class UnfoldMoveFromCenterAnimatorTest : SysuiTestCase() {
}
}
private fun givenScreen(width: Int = 100,
height: Int = 100,
rotation: Int = ROTATION_0) {
private fun givenScreen(
width: Int = 100,
height: Int = 100,
rotation: Int = ROTATION_0
) {
val display = mock(Display::class.java)
whenever(display.getSize(any())).thenAnswer {
val size = (it.arguments[0] as Point)