diff options
| -rw-r--r-- | core/java/com/android/internal/widget/FloatingToolbar.java | 147 | ||||
| -rw-r--r-- | core/res/res/values/dimens.xml | 3 | ||||
| -rwxr-xr-x | core/res/res/values/symbols.xml | 1 |
3 files changed, 90 insertions, 61 deletions
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java index f98fbfc5c77a..03973be2c675 100644 --- a/core/java/com/android/internal/widget/FloatingToolbar.java +++ b/core/java/com/android/internal/widget/FloatingToolbar.java @@ -79,7 +79,6 @@ public final class FloatingToolbar { private final FloatingToolbarPopup mPopup; private final Rect mContentRect = new Rect(); - private final Point mCoordinates = new Point(); private Menu mMenu; private List<CharSequence> mShowingTitles = new ArrayList<CharSequence>(); @@ -87,7 +86,6 @@ public final class FloatingToolbar { private int mSuggestedWidth; private boolean mWidthChanged = true; - private int mOverflowDirection; /** * Initializes a floating toolbar. @@ -157,11 +155,9 @@ public final class FloatingToolbar { mPopup.layoutMenuItems(menuItems, mMenuItemClickListener, mSuggestedWidth); mShowingTitles = getMenuItemTitles(menuItems); } - refreshCoordinates(); - mPopup.setOverflowDirection(mOverflowDirection); - mPopup.updateCoordinates(mCoordinates.x, mCoordinates.y); + mPopup.updateCoordinates(mContentRect); if (!mPopup.isShowing()) { - mPopup.show(mCoordinates.x, mCoordinates.y); + mPopup.show(mContentRect); } mWidthChanged = false; return this; @@ -209,25 +205,6 @@ public final class FloatingToolbar { } /** - * Refreshes {@link #mCoordinates} with values based on {@link #mContentRect}. - */ - private void refreshCoordinates() { - int x = mContentRect.centerX() - mPopup.getWidth() / 2; - int y; - if (mContentRect.top > mPopup.getHeight()) { - y = mContentRect.top - mPopup.getHeight(); - mOverflowDirection = FloatingToolbarPopup.OVERFLOW_DIRECTION_UP; - } else if (mContentRect.top > mPopup.getToolbarHeightWithVerticalMargin()) { - y = mContentRect.top - mPopup.getToolbarHeightWithVerticalMargin(); - mOverflowDirection = FloatingToolbarPopup.OVERFLOW_DIRECTION_DOWN; - } else { - y = mContentRect.bottom; - mOverflowDirection = FloatingToolbarPopup.OVERFLOW_DIRECTION_DOWN; - } - mCoordinates.set(x, y); - } - - /** * Returns true if this floating toolbar is currently showing the specified menu items. */ private boolean isCurrentlyShowing(List<MenuItem> menuItems) { @@ -345,6 +322,8 @@ public final class FloatingToolbar { } }; + private final Point mCoords = new Point(); + private final Region mTouchableRegion = new Region(); private final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsComputer = new ViewTreeObserver.OnComputeInternalInsetsListener() { @@ -404,6 +383,8 @@ public final class FloatingToolbar { */ public void layoutMenuItems(List<MenuItem> menuItems, MenuItem.OnMenuItemClickListener menuItemClickListener, int suggestedWidth) { + Preconditions.checkNotNull(menuItems); + mContentContainer.removeAllViews(); if (mMainPanel == null) { mMainPanel = new FloatingToolbarMainPanel(mParent.getContext(), mOpenOverflow); @@ -426,7 +407,9 @@ public final class FloatingToolbar { * Shows this popup at the specified coordinates. * The specified coordinates may be adjusted to make sure the popup is entirely on-screen. */ - public void show(int x, int y) { + public void show(Rect contentRect) { + Preconditions.checkNotNull(contentRect); + if (isShowing()) { return; } @@ -435,6 +418,7 @@ public final class FloatingToolbar { mDismissed = false; cancelDismissAndHideAnimations(); cancelOverflowAnimations(); + // Make sure a panel is set as the content. if (mContentContainer.getChildCount() == 0) { setMainPanelAsContent(); @@ -442,8 +426,10 @@ public final class FloatingToolbar { // The "show" animation will make this visible. mContentContainer.setAlpha(0); } + updateOverflowHeight(contentRect.top - (mMarginVertical * 2)); + refreshCoordinatesAndOverflowDirection(contentRect); preparePopupContent(); - mPopupWindow.showAtLocation(mParent, Gravity.NO_GRAVITY, x, y); + mPopupWindow.showAtLocation(mParent, Gravity.NO_GRAVITY, mCoords.x, mCoords.y); setTouchableSurfaceInsetsComputer(); runShowAnimation(); } @@ -496,27 +482,17 @@ public final class FloatingToolbar { * The specified coordinates may be adjusted to make sure the popup is entirely on-screen. * This is a no-op if this popup is not showing. */ - public void updateCoordinates(int x, int y) { + public void updateCoordinates(Rect contentRect) { + Preconditions.checkNotNull(contentRect); + if (!isShowing() || !mPopupWindow.isShowing()) { return; } cancelOverflowAnimations(); + refreshCoordinatesAndOverflowDirection(contentRect); preparePopupContent(); - mPopupWindow.update(x, y, getWidth(), getHeight()); - } - - /** - * Sets the direction in which the overflow will open. i.e. up or down. - * - * @param overflowDirection Either {@link #OVERFLOW_DIRECTION_UP} - * or {@link #OVERFLOW_DIRECTION_DOWN}. - */ - public void setOverflowDirection(int overflowDirection) { - mOverflowDirection = overflowDirection; - if (mOverflowPanel != null) { - mOverflowPanel.setOverflowDirection(mOverflowDirection); - } + mPopupWindow.update(mCoords.x, mCoords.y, getWidth(), getHeight()); } /** @@ -540,7 +516,26 @@ public final class FloatingToolbar { return mContentContainer.getContext(); } - int getToolbarHeightWithVerticalMargin() { + private void refreshCoordinatesAndOverflowDirection(Rect contentRect) { + int x = contentRect.centerX() - getWidth() / 2; + int y; + if (contentRect.top > getHeight()) { + y = contentRect.top - getHeight(); + mOverflowDirection = FloatingToolbarPopup.OVERFLOW_DIRECTION_UP; + } else if (contentRect.top > getToolbarHeightWithVerticalMargin()) { + y = contentRect.top - getToolbarHeightWithVerticalMargin(); + mOverflowDirection = FloatingToolbarPopup.OVERFLOW_DIRECTION_DOWN; + } else { + y = contentRect.bottom; + mOverflowDirection = FloatingToolbarPopup.OVERFLOW_DIRECTION_DOWN; + } + mCoords.set(x, y); + if (mOverflowPanel != null) { + mOverflowPanel.setOverflowDirection(mOverflowDirection); + } + } + + private int getToolbarHeightWithVerticalMargin() { return getEstimatedToolbarHeight(mParent.getContext()) + mMarginVertical * 2; } @@ -693,16 +688,24 @@ public final class FloatingToolbar { } // Reset position. - if (mMainPanel != null - && mContentContainer.getChildAt(0) == mMainPanel.getView()) { + if (isMainPanelContent()) { positionMainPanel(); } - if (mOverflowPanel != null - && mContentContainer.getChildAt(0) == mOverflowPanel.getView()) { + if (isOverflowPanelContent()) { positionOverflowPanel(); } } + private boolean isMainPanelContent() { + return mMainPanel != null + && mContentContainer.getChildAt(0) == mMainPanel.getView(); + } + + private boolean isOverflowPanelContent() { + return mOverflowPanel != null + && mContentContainer.getChildAt(0) == mOverflowPanel.getView(); + } + /** * Sets the current content to be the main view panel. */ @@ -765,6 +768,25 @@ public final class FloatingToolbar { setContentAreaAsTouchableSurface(); } + private void updateOverflowHeight(int height) { + if (mOverflowPanel != null) { + mOverflowPanel.setSuggestedHeight(height); + + // Re-measure the popup and it's contents. + boolean mainPanelContent = isMainPanelContent(); + boolean overflowPanelContent = isOverflowPanelContent(); + mContentContainer.removeAllViews(); // required to update popup size. + updatePopupSize(); + // Reset the appropriate content. + if (mainPanelContent) { + setMainPanelAsContent(); + } + if (overflowPanelContent) { + setOverflowPanelAsContent(); + } + } + } + private void updatePopupSize() { int width = 0; int height = 0; @@ -864,6 +886,8 @@ public final class FloatingToolbar { * @return The menu items that are not included in this main panel. */ public List<MenuItem> layoutMenuItems(List<MenuItem> menuItems, int suggestedWidth) { + Preconditions.checkNotNull(menuItems); + final int toolbarWidth = getAdjustedToolbarWidth(mContext, suggestedWidth) // Reserve space for the "open overflow" button. - getEstimatedOpenOverflowButtonWidth(mContext); @@ -972,6 +996,7 @@ public final class FloatingToolbar { private MenuItem.OnMenuItemClickListener mOnMenuItemClickListener; private int mOverflowWidth = 0; + private int mSuggestedHeight; /** * Initializes a floating toolbar popup overflow view panel. @@ -981,6 +1006,7 @@ public final class FloatingToolbar { */ public FloatingToolbarOverflowPanel(Context context, Runnable closeOverflow) { mCloseOverflow = Preconditions.checkNotNull(closeOverflow); + mSuggestedHeight = getScreenHeight(context); mContentView = new LinearLayout(context); mContentView.setOrientation(LinearLayout.VERTICAL); @@ -1043,6 +1069,11 @@ public final class FloatingToolbar { mContentView.addView(mBackButtonContainer, index); } + public void setSuggestedHeight(int height) { + mSuggestedHeight = height; + setListViewHeight(); + } + /** * Returns the content view of the overflow. */ @@ -1074,9 +1105,17 @@ public final class FloatingToolbar { int itemHeight = getEstimatedToolbarHeight(mContentView.getContext()); int height = mListView.getAdapter().getCount() * itemHeight; int maxHeight = mContentView.getContext().getResources(). + getDimensionPixelSize(R.dimen.floating_toolbar_maximum_overflow_height); + int minHeight = mContentView.getContext().getResources(). getDimensionPixelSize(R.dimen.floating_toolbar_minimum_overflow_height); + int availableHeight = mSuggestedHeight - (mSuggestedHeight % itemHeight) + - itemHeight; // reserve space for the back button. ViewGroup.LayoutParams params = mListView.getLayoutParams(); - params.height = Math.min(height, maxHeight); + if (availableHeight >= minHeight) { + params.height = Math.min(Math.min(availableHeight, maxHeight), height); + } else { + params.height = Math.min(maxHeight, height); + } mListView.setLayoutParams(params); } @@ -1271,16 +1310,4 @@ public final class FloatingToolbar { private static int getScreenHeight(Context context) { return context.getResources().getDisplayMetrics().heightPixels; } - - /** - * Returns value, restricted to the range min->max (inclusive). - * If maximum is less than minimum, the result is undefined. - * - * @param value The value to clamp. - * @param minimum The minimum value in the range. - * @param maximum The maximum value in the range. Must not be less than minimum. - */ - private static int clamp(int value, int minimum, int maximum) { - return Math.max(minimum, Math.min(value, maximum)); - } } diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 84747f13cbb4..813591b5b78b 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -392,7 +392,8 @@ <dimen name="floating_toolbar_text_size">14sp</dimen> <dimen name="floating_toolbar_menu_button_minimum_width">48dp</dimen> <dimen name="floating_toolbar_preferred_width">328dp</dimen> - <dimen name="floating_toolbar_minimum_overflow_height">144dp</dimen> + <dimen name="floating_toolbar_minimum_overflow_height">96dp</dimen> + <dimen name="floating_toolbar_maximum_overflow_height">192dp</dimen> <dimen name="floating_toolbar_horizontal_margin">16dp</dimen> <dimen name="floating_toolbar_vertical_margin">8dp</dimen> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 8f949e1265f8..89a871b8aa61 100755 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2243,6 +2243,7 @@ <java-symbol type="dimen" name="floating_toolbar_menu_button_minimum_width" /> <java-symbol type="dimen" name="floating_toolbar_preferred_width" /> <java-symbol type="dimen" name="floating_toolbar_minimum_overflow_height" /> + <java-symbol type="dimen" name="floating_toolbar_maximum_overflow_height" /> <java-symbol type="dimen" name="floating_toolbar_horizontal_margin" /> <java-symbol type="dimen" name="floating_toolbar_vertical_margin" /> |