From c80d0221be6b110922cc4fcb04df8b30aa5b72e8 Mon Sep 17 00:00:00 2001 From: Fengjiang Li Date: Fri, 12 May 2023 16:34:04 -0700 Subject: [PATCH] Fix bug where quickly ending folder animation with back swipe caused icons not clipped to folder 1. Fix a race condition that the new animation is reading stale UI state which should have been reset in previous animation. 2. Don't set clipChildren=true on folder page view during open folder animation Fix: 282158620 Test: open folder and quickly back swipe, verify app icons are still clipped Change-Id: I5f0877fe4157533563df922ba50a6ad540c9ba6e --- .../folder/FolderAnimationManager.java | 58 +++++++++++-------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java index 05ad57acd4..2ce6c785c2 100644 --- a/src/com/android/launcher3/folder/FolderAnimationManager.java +++ b/src/com/android/launcher3/folder/FolderAnimationManager.java @@ -265,23 +265,37 @@ public class FolderAnimationManager { Animator z = getAnimator(mFolder, View.TRANSLATION_Z, -mFolder.getElevation(), 0); play(a, z, mIsOpening ? midDuration : 0, midDuration); - // Store clip variables - CellLayout cellLayout = mContent.getCurrentCellLayout(); - boolean folderClipChildren = mFolder.getClipChildren(); - boolean folderClipToPadding = mFolder.getClipToPadding(); - boolean contentClipChildren = mContent.getClipChildren(); - boolean contentClipToPadding = mContent.getClipToPadding(); - boolean cellLayoutClipChildren = cellLayout.getClipChildren(); - boolean cellLayoutClipPadding = cellLayout.getClipToPadding(); - - mFolder.setClipChildren(false); - mFolder.setClipToPadding(false); - mContent.setClipChildren(false); - mContent.setClipToPadding(false); - cellLayout.setClipChildren(false); - cellLayout.setClipToPadding(false); - + // Store clip variables. + // Because {@link #onAnimationStart} and {@link #onAnimationEnd} callbacks are sent to + // message queue and executed on separate frame, we should save states in + // {@link #onAnimationStart} instead of before creating animator, so that cancelling + // animation A and restarting animation B allows A to reset states in + // {@link #onAnimationEnd} before B reads new UI state from {@link #onAnimationStart}. a.addListener(new AnimatorListenerAdapter() { + private CellLayout mCellLayout; + private boolean mFolderClipToPadding; + private boolean mContentClipChildren; + private boolean mContentClipToPadding; + private boolean mCellLayoutClipChildren; + private boolean mCellLayoutClipPadding; + + @Override + public void onAnimationStart(Animator animator) { + super.onAnimationStart(animator); + mCellLayout = mContent.getCurrentCellLayout(); + mFolderClipToPadding = mFolder.getClipToPadding(); + mContentClipChildren = mContent.getClipChildren(); + mContentClipToPadding = mContent.getClipToPadding(); + mCellLayoutClipChildren = mCellLayout.getClipChildren(); + mCellLayoutClipPadding = mCellLayout.getClipToPadding(); + + mFolder.setClipToPadding(false); + mContent.setClipChildren(false); + mContent.setClipToPadding(false); + mCellLayout.setClipChildren(false); + mCellLayout.setClipToPadding(false); + } + @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); @@ -295,13 +309,11 @@ public class FolderAnimationManager { mFolder.mFooter.setTranslationX(0f); mFolder.mFolderName.setAlpha(1f); - mFolder.setClipChildren(folderClipChildren); - mFolder.setClipToPadding(folderClipToPadding); - mContent.setClipChildren(contentClipChildren); - mContent.setClipToPadding(contentClipToPadding); - cellLayout.setClipChildren(cellLayoutClipChildren); - cellLayout.setClipToPadding(cellLayoutClipPadding); - + mFolder.setClipToPadding(mFolderClipToPadding); + mContent.setClipChildren(mContentClipChildren); + mContent.setClipToPadding(mContentClipToPadding); + mCellLayout.setClipChildren(mCellLayoutClipChildren); + mCellLayout.setClipToPadding(mCellLayoutClipPadding); } });