Merge "Support min/max height for FloatingToolbar overflow." into mnc-dev
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index f98fbfc..03973be 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -79,7 +79,6 @@
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 @@
private int mSuggestedWidth;
private boolean mWidthChanged = true;
- private int mOverflowDirection;
/**
* Initializes a floating toolbar.
@@ -157,11 +155,9 @@
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 @@
}
/**
- * 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 @@
}
};
+ 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 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 @@
* 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 @@
mDismissed = false;
cancelDismissAndHideAnimations();
cancelOverflowAnimations();
+
// Make sure a panel is set as the content.
if (mContentContainer.getChildCount() == 0) {
setMainPanelAsContent();
@@ -442,8 +426,10 @@
// 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 @@
* 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 @@
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 @@
}
// 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 @@
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 @@
* @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 @@
private MenuItem.OnMenuItemClickListener mOnMenuItemClickListener;
private int mOverflowWidth = 0;
+ private int mSuggestedHeight;
/**
* Initializes a floating toolbar popup overflow view panel.
@@ -981,6 +1006,7 @@
*/
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 @@
mContentView.addView(mBackButtonContainer, index);
}
+ public void setSuggestedHeight(int height) {
+ mSuggestedHeight = height;
+ setListViewHeight();
+ }
+
/**
* Returns the content view of the overflow.
*/
@@ -1074,9 +1105,17 @@
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 @@
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 84747f1..813591b 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 0d306c6..64e3964 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -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" />