Merge "Include INVISIBLE views in animations by the ViewHierarchyAnimator." into tm-qpr-dev am: ee42be33d3

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19180930

Change-Id: I61036a22efc51f5cb1463cd9151a93ac89c340d4
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Luca Zuccarini
2022-07-14 15:27:36 +00:00
committed by Automerger Merge Worker
2 changed files with 28 additions and 32 deletions

View File

@@ -106,7 +106,7 @@ class ViewHierarchyAnimator {
ephemeral: Boolean ephemeral: Boolean
): Boolean { ): Boolean {
if ( if (
!isVisible( !occupiesSpace(
rootView.visibility, rootView.visibility,
rootView.left, rootView.left,
rootView.top, rootView.top,
@@ -177,7 +177,7 @@ class ViewHierarchyAnimator {
fadeInInterpolator: Interpolator = DEFAULT_FADE_IN_INTERPOLATOR fadeInInterpolator: Interpolator = DEFAULT_FADE_IN_INTERPOLATOR
): Boolean { ): Boolean {
if ( if (
isVisible( occupiesSpace(
rootView.visibility, rootView.visibility,
rootView.left, rootView.left,
rootView.top, rootView.top,
@@ -295,7 +295,7 @@ class ViewHierarchyAnimator {
(view.getTag(R.id.tag_animator) as? ObjectAnimator)?.cancel() (view.getTag(R.id.tag_animator) as? ObjectAnimator)?.cancel()
if (!isVisible(view.visibility, left, top, right, bottom)) { if (!occupiesSpace(view.visibility, left, top, right, bottom)) {
setBound(view, Bound.LEFT, left) setBound(view, Bound.LEFT, left)
setBound(view, Bound.TOP, top) setBound(view, Bound.TOP, top)
setBound(view, Bound.RIGHT, right) setBound(view, Bound.RIGHT, right)
@@ -362,7 +362,7 @@ class ViewHierarchyAnimator {
duration: Long = DEFAULT_DURATION duration: Long = DEFAULT_DURATION
): Boolean { ): Boolean {
if ( if (
!isVisible( !occupiesSpace(
rootView.visibility, rootView.visibility,
rootView.left, rootView.left,
rootView.top, rootView.top,
@@ -530,17 +530,17 @@ class ViewHierarchyAnimator {
} }
/** /**
* Returns whether the given [visibility] and bounds are consistent with a view being * Returns whether the given [visibility] and bounds are consistent with a view being a
* currently visible on screen. * contributing part of the hierarchy.
*/ */
private fun isVisible( private fun occupiesSpace(
visibility: Int, visibility: Int,
left: Int, left: Int,
top: Int, top: Int,
right: Int, right: Int,
bottom: Int bottom: Int
): Boolean { ): Boolean {
return visibility == View.VISIBLE && left != right && top != bottom return visibility != View.GONE && left != right && top != bottom
} }
/** /**

View File

@@ -206,6 +206,25 @@ ViewHierarchyAnimatorTest : SysuiTestCase() {
checkBounds(rootView.getChildAt(1), l = 95, t = 0, r = 190, b = 100) checkBounds(rootView.getChildAt(1), l = 95, t = 0, r = 190, b = 100)
} }
@Test
fun animatesInvisibleViews() {
rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */)
rootView.visibility = View.INVISIBLE
val success = ViewHierarchyAnimator.animate(rootView)
// Change all bounds.
rootView.layout(0 /* l */, 15 /* t */, 70 /* r */, 80 /* b */)
assertTrue(success)
assertNotNull(rootView.getTag(R.id.tag_animator))
// The initial values should be those of the previous layout.
checkBounds(rootView, l = 10, t = 10, r = 50, b = 50)
endAnimation(rootView)
assertNull(rootView.getTag(R.id.tag_animator))
// The end values should be those of the latest layout.
checkBounds(rootView, l = 0, t = 15, r = 70, b = 80)
}
@Test @Test
fun animatesAppearingViewsFromStartToEnd() { fun animatesAppearingViewsFromStartToEnd() {
// Starting GONE. // Starting GONE.
@@ -222,20 +241,6 @@ ViewHierarchyAnimatorTest : SysuiTestCase() {
assertNull(rootView.getTag(R.id.tag_animator)) assertNull(rootView.getTag(R.id.tag_animator))
checkBounds(rootView, l = 0, t = 100, r = 100, b = 200) checkBounds(rootView, l = 0, t = 100, r = 100, b = 200)
// Starting INVISIBLE.
rootView.visibility = View.INVISIBLE
rootView.layout(0 /* l */, 50 /* t */, 50 /* r */, 100 /* b */)
success = ViewHierarchyAnimator.animateAddition(rootView)
rootView.visibility = View.VISIBLE
rootView.layout(0 /* l */, 100 /* t */, 100 /* r */, 200 /* b */)
assertTrue(success)
assertNotNull(rootView.getTag(R.id.tag_animator))
checkBounds(rootView, l = 50, t = 150, r = 50, b = 150)
endAnimation(rootView)
assertNull(rootView.getTag(R.id.tag_animator))
checkBounds(rootView, l = 0, t = 100, r = 100, b = 200)
// Starting with nothing. // Starting with nothing.
rootView.layout(0 /* l */, 0 /* t */, 0 /* r */, 0 /* b */) rootView.layout(0 /* l */, 0 /* t */, 0 /* r */, 0 /* b */)
success = ViewHierarchyAnimator.animateAddition(rootView) success = ViewHierarchyAnimator.animateAddition(rootView)
@@ -937,7 +942,7 @@ ViewHierarchyAnimatorTest : SysuiTestCase() {
} }
@Test @Test
fun doesNotAnimateInvisibleViews() { fun doesNotAnimateGoneViews() {
rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */) rootView.layout(10 /* l */, 10 /* t */, 50 /* r */, 50 /* b */)
// GONE // GONE
@@ -948,15 +953,6 @@ ViewHierarchyAnimatorTest : SysuiTestCase() {
assertFalse(success) assertFalse(success)
assertNull(rootView.getTag(R.id.tag_animator)) assertNull(rootView.getTag(R.id.tag_animator))
checkBounds(rootView, l = 0, t = 15, r = 55, b = 80) checkBounds(rootView, l = 0, t = 15, r = 55, b = 80)
// INVISIBLE.
rootView.visibility = View.INVISIBLE
success = ViewHierarchyAnimator.animate(rootView)
rootView.layout(0 /* l */, 20 /* t */, 10 /* r */, 50 /* b */)
assertFalse(success)
assertNull(rootView.getTag(R.id.tag_animator))
checkBounds(rootView, l = 0, t = 20, r = 10, b = 50)
} }
@Test @Test