Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 86817200 authored by Abodunrinwa Toki's avatar Abodunrinwa Toki Committed by Android (Google) Code Review
Browse files

Merge "Support min/max height for FloatingToolbar overflow." into mnc-dev

parents 40bdcb7c ffebf682
Loading
Loading
Loading
Loading
+87 −60
Original line number Diff line number Diff line
@@ -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;
@@ -208,25 +204,6 @@ public final class FloatingToolbar {
        return mPopup.isHidden();
    }

    /**
     * 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.
     */
@@ -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));
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -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>

+1 −0
Original line number Diff line number Diff line
@@ -2256,6 +2256,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" />