From c107b0ecdcd4e2f89ae4bec818c3a94f45c3c15e Mon Sep 17 00:00:00 2001 From: Abodunrinwa Toki Date: Thu, 25 Jun 2015 21:33:51 -0700 Subject: Fix FloatingToolbar flicker in reaction to text cursor blink. 1. Reposition the toolbar on predraw only when positioning has changed. 2. Update the toolbar popup's position only if the content rect changed. 3. Fix FloatingToolbarPopup.cancelOverflowAnimations(). The previous implementation wasn't actually cancelling the animation. (1) is enough to fix the bug. But (2) and (3) fix issues in the toolbar directly related to this bug. Bug: 22039189 Change-Id: I84ec793d788f9402a1f8635e68e3344746f6af07 --- .../android/internal/view/FloatingActionMode.java | 16 +++++++- .../android/internal/widget/FloatingToolbar.java | 45 ++++++++++++---------- 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java index 863506b0a63a..c869722abfd4 100644 --- a/core/java/com/android/internal/view/FloatingActionMode.java +++ b/core/java/com/android/internal/view/FloatingActionMode.java @@ -30,6 +30,8 @@ import com.android.internal.util.Preconditions; import com.android.internal.view.menu.MenuBuilder; import com.android.internal.widget.FloatingToolbar; +import java.util.Arrays; + public class FloatingActionMode extends ActionMode { private static final int MAX_HIDE_DURATION = 3000; @@ -42,7 +44,9 @@ public class FloatingActionMode extends ActionMode { private final Rect mContentRectOnWindow; private final Rect mPreviousContentRectOnWindow; private final int[] mViewPosition; + private final int[] mPreviousViewPosition; private final Rect mViewRect; + private final Rect mPreviousViewRect; private final Rect mScreenRect; private final View mOriginatingView; private final int mBottomAllowance; @@ -75,7 +79,9 @@ public class FloatingActionMode extends ActionMode { mContentRectOnWindow = new Rect(); mPreviousContentRectOnWindow = new Rect(); mViewPosition = new int[2]; + mPreviousViewPosition = new int[2]; mViewRect = new Rect(); + mPreviousViewRect = new Rect(); mScreenRect = new Rect(); mOriginatingView = Preconditions.checkNotNull(originatingView); mOriginatingView.getLocationInWindow(mViewPosition); @@ -129,9 +135,17 @@ public class FloatingActionMode extends ActionMode { public void updateViewLocationInWindow() { checkToolbarInitialized(); + mOriginatingView.getLocationInWindow(mViewPosition); mOriginatingView.getGlobalVisibleRect(mViewRect); - repositionToolbar(); + + if (!Arrays.equals(mViewPosition, mPreviousViewPosition) + || !mViewRect.equals(mPreviousViewRect)) { + repositionToolbar(); + mPreviousViewPosition[0] = mViewPosition[0]; + mPreviousViewPosition[1] = mViewPosition[1]; + mPreviousViewRect.set(mViewRect); + } } private void repositionToolbar() { diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java index 32a145c7c1c9..163b8ce746d3 100644 --- a/core/java/com/android/internal/widget/FloatingToolbar.java +++ b/core/java/com/android/internal/widget/FloatingToolbar.java @@ -85,6 +85,7 @@ public final class FloatingToolbar { private final FloatingToolbarPopup mPopup; private final Rect mContentRect = new Rect(); + private final Rect mPreviousContentRect = new Rect(); private Menu mMenu; private List mShowingMenuItems = new ArrayList(); @@ -178,11 +179,13 @@ public final class FloatingToolbar { mPopup.layoutMenuItems(menuItems, mMenuItemClickListener, mSuggestedWidth); mShowingMenuItems = getShowingMenuItemsReferences(menuItems); } - mPopup.updateCoordinates(mContentRect); if (!mPopup.isShowing()) { mPopup.show(mContentRect); + } else if (!mPreviousContentRect.equals(mContentRect)) { + mPopup.updateCoordinates(mContentRect); } mWidthChanged = false; + mPreviousContentRect.set(mContentRect); return this; } @@ -318,24 +321,8 @@ public final class FloatingToolbar { }; private final AnimatorSet mDismissAnimation; private final AnimatorSet mHideAnimation; - private final AnimationSet mOpenOverflowAnimation = new AnimationSet(true) { - @Override - public void cancel() { - if (hasStarted() && !hasEnded()) { - super.cancel(); - setOverflowPanelAsContent(); - } - } - }; - private final AnimationSet mCloseOverflowAnimation = new AnimationSet(true) { - @Override - public void cancel() { - if (hasStarted() && !hasEnded()) { - super.cancel(); - setMainPanelAsContent(); - } - } - }; + private final AnimationSet mOpenOverflowAnimation = new AnimationSet(true); + private final AnimationSet mCloseOverflowAnimation = new AnimationSet(true); private final Runnable mOpenOverflow = new Runnable() { @Override @@ -657,8 +644,24 @@ public final class FloatingToolbar { } private void cancelOverflowAnimations() { - mOpenOverflowAnimation.cancel(); - mCloseOverflowAnimation.cancel(); + if (mOpenOverflowAnimation.hasStarted() + && !mOpenOverflowAnimation.hasEnded()) { + // Remove the animation listener, stop the animation, + // then trigger the lister explicitly so it is not posted + // to the message queue. + mOpenOverflowAnimation.setAnimationListener(null); + mContentContainer.clearAnimation(); + mOnOverflowOpened.onAnimationEnd(null); + } + if (mCloseOverflowAnimation.hasStarted() + && !mCloseOverflowAnimation.hasEnded()) { + // Remove the animation listener, stop the animation, + // then trigger the lister explicitly so it is not posted + // to the message queue. + mCloseOverflowAnimation.setAnimationListener(null); + mContentContainer.clearAnimation(); + mOnOverflowClosed.onAnimationEnd(null); + } } /** -- cgit v1.2.3-59-g8ed1b