From 972ab4f8588c365cf9c06e1f22b30a96fb0a06fc Mon Sep 17 00:00:00 2001 From: Abodunrinwa Toki Date: Wed, 17 Jun 2015 18:04:23 +0100 Subject: [PATCH] Fix FloatingToolbar flickers. This is fixed by avoiding calling toolbar.show() in PhoneWindow. FloatingActionMode coordinates whether or not the toolbar should be visible. PhoneWindow differs to it. This CL also adds a new API: ActionMode#onWindowFocusChanged(boolean) Bug: 21617792 Change-Id: Ic49ce1000ce9c782d0f9e17e3d024d462c7b758b --- api/current.txt | 1 + api/system-current.txt | 1 + core/java/android/view/ActionMode.java | 10 ++++++++++ .../com/android/internal/policy/PhoneWindow.java | 14 ++++++-------- .../internal/view/FloatingActionMode.java | 16 +++++++++++++++- 5 files changed, 33 insertions(+), 9 deletions(-) diff --git a/api/current.txt b/api/current.txt index 7c22e4e7826d5..4d2b6efd1c0cc 100644 --- a/api/current.txt +++ b/api/current.txt @@ -34574,6 +34574,7 @@ package android.view { method public abstract void invalidate(); method public void invalidateContentRect(); method public boolean isTitleOptional(); + method public void onWindowFocusChanged(boolean); method public abstract void setCustomView(android.view.View); method public abstract void setSubtitle(java.lang.CharSequence); method public abstract void setSubtitle(int); diff --git a/api/system-current.txt b/api/system-current.txt index 67d3635ab6de0..3f610dc3c54d7 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -36862,6 +36862,7 @@ package android.view { method public abstract void invalidate(); method public void invalidateContentRect(); method public boolean isTitleOptional(); + method public void onWindowFocusChanged(boolean); method public abstract void setCustomView(android.view.View); method public abstract void setSubtitle(java.lang.CharSequence); method public abstract void setSubtitle(int); diff --git a/core/java/android/view/ActionMode.java b/core/java/android/view/ActionMode.java index 80dcecce8bc22..ea979c8b4621e 100644 --- a/core/java/android/view/ActionMode.java +++ b/core/java/android/view/ActionMode.java @@ -260,6 +260,16 @@ public abstract class ActionMode { */ public abstract MenuInflater getMenuInflater(); + /** + * Called when the window containing the view that started this action mode gains or loses + * focus. + * + * @param hasWindowFocus True if the window containing the view that started this action mode + * now has focus, false otherwise. + * + */ + public void onWindowFocusChanged(boolean hasWindowFocus) {} + /** * Returns whether the UI presenting this action mode can take focus or not. * This is used by internal components within the framework that would otherwise diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index 66f6079b47e9c..15ed5bd0b539f 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -3223,12 +3223,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { cb.onWindowFocusChanged(hasWindowFocus); } - if (mFloatingToolbar != null) { - if (hasWindowFocus) { - mFloatingToolbar.show(); - } else { - mFloatingToolbar.dismiss(); - } + if (mPrimaryActionMode != null) { + mPrimaryActionMode.onWindowFocusChanged(hasWindowFocus); + } + if (mFloatingActionMode != null) { + mFloatingActionMode.onWindowFocusChanged(hasWindowFocus); } } @@ -3441,8 +3440,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { mFloatingActionMode = mode; mFloatingToolbar = new FloatingToolbar(mContext, PhoneWindow.this); ((FloatingActionMode) mFloatingActionMode).setFloatingToolbar(mFloatingToolbar); - mFloatingActionMode.invalidate(); - mFloatingToolbar.show(); + mFloatingActionMode.invalidate(); // Will show the floating toolbar if necessary. mFloatingActionModeOriginatingView.getViewTreeObserver() .addOnPreDrawListener(mFloatingToolbarPreDrawListener); } diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java index 784b256728ca6..863506b0a63a2 100644 --- a/core/java/com/android/internal/view/FloatingActionMode.java +++ b/core/java/com/android/internal/view/FloatingActionMode.java @@ -196,6 +196,13 @@ public class FloatingActionMode extends ActionMode { } } + @Override + public void onWindowFocusChanged(boolean hasWindowFocus) { + checkToolbarInitialized(); + mFloatingToolbarVisibilityHelper.setWindowFocused(hasWindowFocus); + mFloatingToolbarVisibilityHelper.updateToolbarVisibility(); + } + @Override public void finish() { checkToolbarInitialized(); @@ -237,6 +244,7 @@ public class FloatingActionMode extends ActionMode { } private void reset() { + mFloatingToolbar.dismiss(); mFloatingToolbarVisibilityHelper.deactivate(); mOriginatingView.removeCallbacks(mMovingOff); mOriginatingView.removeCallbacks(mHideOff); @@ -253,6 +261,7 @@ public class FloatingActionMode extends ActionMode { private boolean mHideRequested; private boolean mMoving; private boolean mOutOfBounds; + private boolean mWindowFocused = true; private boolean mActive; @@ -264,6 +273,7 @@ public class FloatingActionMode extends ActionMode { mHideRequested = false; mMoving = false; mOutOfBounds = false; + mWindowFocused = true; mActive = true; } @@ -285,12 +295,16 @@ public class FloatingActionMode extends ActionMode { mOutOfBounds = outOfBounds; } + public void setWindowFocused(boolean windowFocused) { + mWindowFocused = windowFocused; + } + public void updateToolbarVisibility() { if (!mActive) { return; } - if (mHideRequested || mMoving || mOutOfBounds) { + if (mHideRequested || mMoving || mOutOfBounds || !mWindowFocused) { mToolbar.hide(); } else { mToolbar.show();