Merge "Support min/max height for FloatingToolbar overflow." into mnc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
8681720055
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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" />
|
||||
|
||||
|
||||
Reference in New Issue
Block a user