From a874e30959c9a19275ff3ce47ba6deda1955d094 Mon Sep 17 00:00:00 2001 From: Abodunrinwa Toki Date: Fri, 29 Jan 2016 15:43:04 +0000 Subject: [PATCH] FloatingToolbar: Fix orientation change handling. Orientation change handling was done using a config change listener but it is not a sufficient trigger for when the toolbar needs to be resized. It is called before the layout has changed. A better trigger for resizing the toolbar will be on layout change. At this time, we get an accurate measurement of the drawing area. Bug: 21816857 Change-Id: Ia4d752f12b64b64256c1c41d5ede5d2e29a4f408 --- .../internal/widget/FloatingToolbar.java | 78 +++++++++++-------- 1 file changed, 45 insertions(+), 33 deletions(-) diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java index 3a004690d2cbf..4143eb586c1cd 100644 --- a/core/java/com/android/internal/widget/FloatingToolbar.java +++ b/core/java/com/android/internal/widget/FloatingToolbar.java @@ -90,6 +90,7 @@ public final class FloatingToolbar { }; private final Context mContext; + private final Window mWindow; private final FloatingToolbarPopup mPopup; private final Rect mContentRect = new Rect(); @@ -102,26 +103,31 @@ public final class FloatingToolbar { private int mSuggestedWidth; private boolean mWidthChanged = true; - private final ComponentCallbacks mOrientationChangeHandler = new ComponentCallbacks() { + private final OnLayoutChangeListener mOrientationChangeHandler = new OnLayoutChangeListener() { + + private final Rect mNewRect = new Rect(); + private final Rect mOldRect = new Rect(); + @Override - public void onConfigurationChanged(Configuration newConfig) { - if (mPopup.isShowing() && mPopup.viewPortHasChanged()) { + public void onLayoutChange( + View view, + int newLeft, int newRight, int newTop, int newBottom, + int oldLeft, int oldRight, int oldTop, int oldBottom) { + mNewRect.set(newLeft, newRight, newTop, newBottom); + mOldRect.set(oldLeft, oldRight, oldTop, oldBottom); + if (mPopup.isShowing() && !mNewRect.equals(mOldRect)) { mWidthChanged = true; updateLayout(); } } - - @Override - public void onLowMemory() {} }; /** * Initializes a floating toolbar. */ public FloatingToolbar(Context context, Window window) { - Preconditions.checkNotNull(context); - Preconditions.checkNotNull(window); - mContext = applyDefaultTheme(context); + mContext = applyDefaultTheme(Preconditions.checkNotNull(context)); + mWindow = Preconditions.checkNotNull(window); mPopup = new FloatingToolbarPopup(mContext, window.getDecorView()); } @@ -179,21 +185,8 @@ public final class FloatingToolbar { * Shows this floating toolbar. */ public FloatingToolbar show() { - mContext.unregisterComponentCallbacks(mOrientationChangeHandler); - mContext.registerComponentCallbacks(mOrientationChangeHandler); - List menuItems = getVisibleAndEnabledMenuItems(mMenu); - if (!isCurrentlyShowing(menuItems) || mWidthChanged) { - mPopup.dismiss(); - mPopup.layoutMenuItems(menuItems, mMenuItemClickListener, mSuggestedWidth); - mShowingMenuItems = getShowingMenuItemsReferences(menuItems); - } - if (!mPopup.isShowing()) { - mPopup.show(mContentRect); - } else if (!mPreviousContentRect.equals(mContentRect)) { - mPopup.updateCoordinates(mContentRect); - } - mWidthChanged = false; - mPreviousContentRect.set(mContentRect); + registerOrientationHandler(); + doShow(); return this; } @@ -203,8 +196,7 @@ public final class FloatingToolbar { */ public FloatingToolbar updateLayout() { if (mPopup.isShowing()) { - // show() performs all the logic we need here. - show(); + doShow(); } return this; } @@ -213,7 +205,7 @@ public final class FloatingToolbar { * Dismisses this floating toolbar. */ public void dismiss() { - mContext.unregisterComponentCallbacks(mOrientationChangeHandler); + unregisterOrientationHandler(); mPopup.dismiss(); } @@ -239,6 +231,22 @@ public final class FloatingToolbar { return mPopup.isHidden(); } + private void doShow() { + List menuItems = getVisibleAndEnabledMenuItems(mMenu); + if (!isCurrentlyShowing(menuItems) || mWidthChanged) { + mPopup.dismiss(); + mPopup.layoutMenuItems(menuItems, mMenuItemClickListener, mSuggestedWidth); + mShowingMenuItems = getShowingMenuItemsReferences(menuItems); + } + if (!mPopup.isShowing()) { + mPopup.show(mContentRect); + } else if (!mPreviousContentRect.equals(mContentRect)) { + mPopup.updateCoordinates(mContentRect); + } + mWidthChanged = false; + mPreviousContentRect.set(mContentRect); + } + /** * Returns true if this floating toolbar is currently showing the specified menu items. */ @@ -278,6 +286,15 @@ public final class FloatingToolbar { return references; } + private void registerOrientationHandler() { + unregisterOrientationHandler() + mWindow.getDecorView.addOnLayoutChangeListener(mOrientationChangeHandler); + } + + private void unregisterOrientationHandler() { + mWindow.getDecorView.removeOnLayoutChangeListener(mOrientationChangeHandler); + } + /** * A popup window used by the floating toolbar. @@ -1009,11 +1026,6 @@ public final class FloatingToolbar { mParent.getWindowVisibleDisplayFrame(mViewPortOnScreen); } - private boolean viewPortHasChanged() { - mParent.getWindowVisibleDisplayFrame(mTmpRect); - return !mTmpRect.equals(mViewPortOnScreen); - } - private int getAdjustedToolbarWidth(int suggestedWidth) { int width = suggestedWidth; refreshViewPort(); @@ -1658,4 +1670,4 @@ public final class FloatingToolbar { a.recycle(); return new ContextThemeWrapper(originalContext, themeId); } -} \ No newline at end of file +}