Merge "[Taskbar icons unfold animation issue] Do not take into account initial translation" into sc-v2-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
73ad080072
@@ -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
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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(
|
||||||
height: Int = 100,
|
width: Int = 100,
|
||||||
rotation: Int = ROTATION_0) {
|
height: Int = 100,
|
||||||
|
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)
|
||||||
|
|||||||
Reference in New Issue
Block a user