summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/view/FloatingActionMode.java78
-rw-r--r--core/java/com/android/internal/widget/FloatingToolbar.java87
2 files changed, 91 insertions, 74 deletions
diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java
index ef2fef0e4d68..41628d048752 100644
--- a/core/java/com/android/internal/view/FloatingActionMode.java
+++ b/core/java/com/android/internal/view/FloatingActionMode.java
@@ -41,13 +41,13 @@ public class FloatingActionMode extends ActionMode {
private final ActionMode.Callback2 mCallback;
private final MenuBuilder mMenu;
private final Rect mContentRect;
- private final Rect mContentRectOnWindow;
- private final Rect mPreviousContentRectOnWindow;
- private final int[] mViewPosition;
- private final int[] mPreviousViewPosition;
- private final int[] mRootViewPosition;
- private final Rect mViewRect;
- private final Rect mPreviousViewRect;
+ private final Rect mContentRectOnScreen;
+ private final Rect mPreviousContentRectOnScreen;
+ private final int[] mViewPositionOnScreen;
+ private final int[] mPreviousViewPositionOnScreen;
+ private final int[] mRootViewPositionOnScreen;
+ private final Rect mViewRectOnScreen;
+ private final Rect mPreviousViewRectOnScreen;
private final Rect mScreenRect;
private final View mOriginatingView;
private final int mBottomAllowance;
@@ -77,16 +77,16 @@ public class FloatingActionMode extends ActionMode {
MenuItem.SHOW_AS_ACTION_IF_ROOM);
setType(ActionMode.TYPE_FLOATING);
mContentRect = new Rect();
- mContentRectOnWindow = new Rect();
- mPreviousContentRectOnWindow = new Rect();
- mViewPosition = new int[2];
- mPreviousViewPosition = new int[2];
- mRootViewPosition = new int[2];
- mViewRect = new Rect();
- mPreviousViewRect = new Rect();
+ mContentRectOnScreen = new Rect();
+ mPreviousContentRectOnScreen = new Rect();
+ mViewPositionOnScreen = new int[2];
+ mPreviousViewPositionOnScreen = new int[2];
+ mRootViewPositionOnScreen = new int[2];
+ mViewRectOnScreen = new Rect();
+ mPreviousViewRectOnScreen = new Rect();
mScreenRect = new Rect();
mOriginatingView = Preconditions.checkNotNull(originatingView);
- mOriginatingView.getLocationInWindow(mViewPosition);
+ mOriginatingView.getLocationOnScreen(mViewPositionOnScreen);
// Allow the content rect to overshoot a little bit beyond the
// bottom view bound if necessary.
mBottomAllowance = context.getResources()
@@ -138,52 +138,53 @@ public class FloatingActionMode extends ActionMode {
public void updateViewLocationInWindow() {
checkToolbarInitialized();
- mOriginatingView.getLocationInWindow(mViewPosition);
- mOriginatingView.getRootView().getLocationInWindow(mRootViewPosition);
- mOriginatingView.getGlobalVisibleRect(mViewRect);
- mViewRect.offset(mRootViewPosition[0], mRootViewPosition[1]);
+ mOriginatingView.getLocationOnScreen(mViewPositionOnScreen);
+ mOriginatingView.getRootView().getLocationOnScreen(mRootViewPositionOnScreen);
+ mOriginatingView.getGlobalVisibleRect(mViewRectOnScreen);
+ mViewRectOnScreen.offset(mRootViewPositionOnScreen[0], mRootViewPositionOnScreen[1]);
- if (!Arrays.equals(mViewPosition, mPreviousViewPosition)
- || !mViewRect.equals(mPreviousViewRect)) {
+ if (!Arrays.equals(mViewPositionOnScreen, mPreviousViewPositionOnScreen)
+ || !mViewRectOnScreen.equals(mPreviousViewRectOnScreen)) {
repositionToolbar();
- mPreviousViewPosition[0] = mViewPosition[0];
- mPreviousViewPosition[1] = mViewPosition[1];
- mPreviousViewRect.set(mViewRect);
+ mPreviousViewPositionOnScreen[0] = mViewPositionOnScreen[0];
+ mPreviousViewPositionOnScreen[1] = mViewPositionOnScreen[1];
+ mPreviousViewRectOnScreen.set(mViewRectOnScreen);
}
}
private void repositionToolbar() {
checkToolbarInitialized();
- mContentRectOnWindow.set(mContentRect);
- mContentRectOnWindow.offset(mViewPosition[0], mViewPosition[1]);
+ mContentRectOnScreen.set(mContentRect);
+ mContentRectOnScreen.offset(mViewPositionOnScreen[0], mViewPositionOnScreen[1]);
if (isContentRectWithinBounds()) {
mFloatingToolbarVisibilityHelper.setOutOfBounds(false);
// Make sure that content rect is not out of the view's visible bounds.
- mContentRectOnWindow.set(
- Math.max(mContentRectOnWindow.left, mViewRect.left),
- Math.max(mContentRectOnWindow.top, mViewRect.top),
- Math.min(mContentRectOnWindow.right, mViewRect.right),
- Math.min(mContentRectOnWindow.bottom, mViewRect.bottom + mBottomAllowance));
-
- if (!mContentRectOnWindow.equals(mPreviousContentRectOnWindow)) {
+ mContentRectOnScreen.set(
+ Math.max(mContentRectOnScreen.left, mViewRectOnScreen.left),
+ Math.max(mContentRectOnScreen.top, mViewRectOnScreen.top),
+ Math.min(mContentRectOnScreen.right, mViewRectOnScreen.right),
+ Math.min(mContentRectOnScreen.bottom,
+ mViewRectOnScreen.bottom + mBottomAllowance));
+
+ if (!mContentRectOnScreen.equals(mPreviousContentRectOnScreen)) {
// Content rect is moving.
mOriginatingView.removeCallbacks(mMovingOff);
mFloatingToolbarVisibilityHelper.setMoving(true);
mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
mOriginatingView.postDelayed(mMovingOff, MOVING_HIDE_DELAY);
- mFloatingToolbar.setContentRect(mContentRectOnWindow);
+ mFloatingToolbar.setContentRect(mContentRectOnScreen);
mFloatingToolbar.updateLayout();
}
} else {
mFloatingToolbarVisibilityHelper.setOutOfBounds(true);
mFloatingToolbarVisibilityHelper.updateToolbarVisibility();
- mContentRectOnWindow.setEmpty();
+ mContentRectOnScreen.setEmpty();
}
- mPreviousContentRectOnWindow.set(mContentRectOnWindow);
+ mPreviousContentRectOnScreen.set(mContentRectOnScreen);
}
private boolean isContentRectWithinBounds() {
@@ -193,8 +194,8 @@ public class FloatingActionMode extends ActionMode {
mContext.getResources().getDisplayMetrics().widthPixels,
mContext.getResources().getDisplayMetrics().heightPixels);
- return Rect.intersects(mContentRectOnWindow, mScreenRect)
- && Rect.intersects(mContentRectOnWindow, mViewRect);
+ return Rect.intersects(mContentRectOnScreen, mScreenRect)
+ && Rect.intersects(mContentRectOnScreen, mViewRectOnScreen);
}
@Override
@@ -269,7 +270,6 @@ public class FloatingActionMode extends ActionMode {
mOriginatingView.removeCallbacks(mHideOff);
}
-
/**
* A helper for showing/hiding the floating toolbar depending on certain states.
*/
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index a6e80345fb8a..b3f688bbbd04 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -285,6 +285,7 @@ public final class FloatingToolbar {
private final Context mContext;
private final View mParent;
+ private final int[] mParentPositionOnScreen = new int[2];
private final PopupWindow mPopupWindow;
private final ViewGroup mContentContainer;
private final int mMarginHorizontal;
@@ -337,8 +338,8 @@ public final class FloatingToolbar {
}
};
- private final Rect mViewPort = new Rect();
- private final Point mCoords = new Point();
+ private final Rect mViewPortOnScreen = new Rect();
+ private final Point mCoordsOnScreen = new Point();
private final Rect mTmpRect = new Rect();
private final Region mTouchableRegion = new Region();
@@ -428,8 +429,8 @@ 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(Rect contentRect) {
- Preconditions.checkNotNull(contentRect);
+ public void show(Rect contentRectOnScreen) {
+ Preconditions.checkNotNull(contentRectOnScreen);
if (isShowing()) {
return;
@@ -447,9 +448,15 @@ public final class FloatingToolbar {
// The "show" animation will make this visible.
mContentContainer.setAlpha(0);
}
- refreshCoordinatesAndOverflowDirection(contentRect);
+ refreshCoordinatesAndOverflowDirection(contentRectOnScreen);
preparePopupContent();
- mPopupWindow.showAtLocation(mParent, Gravity.NO_GRAVITY, mCoords.x, mCoords.y);
+ // We need to specify the offset relative to mParent.
+ // TODO: Consider to use PopupWindow.setLayoutInScreenEnabled(true) so that we can
+ // specify the popup poision in screen coordinates.
+ mParent.getLocationOnScreen(mParentPositionOnScreen);
+ final int relativeX = mCoordsOnScreen.x - mParentPositionOnScreen[0];
+ final int relativeY = mCoordsOnScreen.y - mParentPositionOnScreen[1];
+ mPopupWindow.showAtLocation(mParent, Gravity.NO_GRAVITY, relativeX, relativeY);
setTouchableSurfaceInsetsComputer();
runShowAnimation();
}
@@ -502,17 +509,23 @@ 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(Rect contentRect) {
- Preconditions.checkNotNull(contentRect);
+ public void updateCoordinates(Rect contentRectOnScreen) {
+ Preconditions.checkNotNull(contentRectOnScreen);
if (!isShowing() || !mPopupWindow.isShowing()) {
return;
}
cancelOverflowAnimations();
- refreshCoordinatesAndOverflowDirection(contentRect);
+ refreshCoordinatesAndOverflowDirection(contentRectOnScreen);
preparePopupContent();
- mPopupWindow.update(mCoords.x, mCoords.y, getWidth(), getHeight());
+ // We need to specify the offset relative to mParent.
+ // TODO: Consider to use PopupWindow.setLayoutInScreenEnabled(true) so that we can
+ // specify the popup poision in screen coordinates.
+ mParent.getLocationOnScreen(mParentPositionOnScreen);
+ final int relativeX = mCoordsOnScreen.x - mParentPositionOnScreen[0];
+ final int relativeY = mCoordsOnScreen.y - mParentPositionOnScreen[1];
+ mPopupWindow.update(relativeX, relativeY, getWidth(), getHeight());
}
/**
@@ -536,47 +549,47 @@ public final class FloatingToolbar {
return mContext;
}
- private void refreshCoordinatesAndOverflowDirection(Rect contentRect) {
+ private void refreshCoordinatesAndOverflowDirection(Rect contentRectOnScreen) {
refreshViewPort();
- int x = contentRect.centerX() - getWidth() / 2;
+ int x = contentRectOnScreen.centerX() - getWidth() / 2;
// Update x so that the toolbar isn't rendered behind the nav bar in landscape.
- x = Math.max(0, Math.min(x, mViewPort.right - getWidth()));
+ x = Math.max(0, Math.min(x, mViewPortOnScreen.right - getWidth()));
int y;
- int availableHeightAboveContent = contentRect.top - mViewPort.top;
- int availableHeightBelowContent = mViewPort.bottom - contentRect.bottom;
+ int availableHeightAboveContent = contentRectOnScreen.top - mViewPortOnScreen.top;
+ int availableHeightBelowContent = mViewPortOnScreen.bottom - contentRectOnScreen.bottom;
if (mOverflowPanel == null) { // There is no overflow.
if (availableHeightAboveContent >= getToolbarHeightWithVerticalMargin()) {
// There is enough space at the top of the content.
- y = contentRect.top - getToolbarHeightWithVerticalMargin();
+ y = contentRectOnScreen.top - getToolbarHeightWithVerticalMargin();
} else if (availableHeightBelowContent >= getToolbarHeightWithVerticalMargin()) {
// There is enough space at the bottom of the content.
- y = contentRect.bottom;
+ y = contentRectOnScreen.bottom;
} else if (availableHeightBelowContent >= getEstimatedToolbarHeight(mContext)) {
// Just enough space to fit the toolbar with no vertical margins.
- y = contentRect.bottom - mMarginVertical;
+ y = contentRectOnScreen.bottom - mMarginVertical;
} else {
// Not enough space. Prefer to position as high as possible.
y = Math.max(
- mViewPort.top,
- contentRect.top - getToolbarHeightWithVerticalMargin());
+ mViewPortOnScreen.top,
+ contentRectOnScreen.top - getToolbarHeightWithVerticalMargin());
}
} else { // There is an overflow.
int margin = 2 * mMarginVertical;
int minimumOverflowHeightWithMargin = mOverflowPanel.getMinimumHeight() + margin;
- int availableHeightThroughContentDown =
- mViewPort.bottom - contentRect.top + getToolbarHeightWithVerticalMargin();
- int availableHeightThroughContentUp =
- contentRect.bottom - mViewPort.top + getToolbarHeightWithVerticalMargin();
+ int availableHeightThroughContentDown = mViewPortOnScreen.bottom -
+ contentRectOnScreen.top + getToolbarHeightWithVerticalMargin();
+ int availableHeightThroughContentUp = contentRectOnScreen.bottom -
+ mViewPortOnScreen.top + getToolbarHeightWithVerticalMargin();
if (availableHeightAboveContent >= minimumOverflowHeightWithMargin) {
// There is enough space at the top of the content rect for the overflow.
// Position above and open upwards.
updateOverflowHeight(availableHeightAboveContent - margin);
- y = contentRect.top - getHeight();
+ y = contentRectOnScreen.top - getHeight();
mOverflowDirection = OVERFLOW_DIRECTION_UP;
} else if (availableHeightAboveContent >= getToolbarHeightWithVerticalMargin()
&& availableHeightThroughContentDown >= minimumOverflowHeightWithMargin) {
@@ -584,33 +597,34 @@ public final class FloatingToolbar {
// but not the overflow.
// Position above but open downwards.
updateOverflowHeight(availableHeightThroughContentDown - margin);
- y = contentRect.top - getToolbarHeightWithVerticalMargin();
+ y = contentRectOnScreen.top - getToolbarHeightWithVerticalMargin();
mOverflowDirection = OVERFLOW_DIRECTION_DOWN;
} else if (availableHeightBelowContent >= minimumOverflowHeightWithMargin) {
// There is enough space at the bottom of the content rect for the overflow.
// Position below and open downwards.
updateOverflowHeight(availableHeightBelowContent - margin);
- y = contentRect.bottom;
+ y = contentRectOnScreen.bottom;
mOverflowDirection = OVERFLOW_DIRECTION_DOWN;
} else if (availableHeightBelowContent >= getToolbarHeightWithVerticalMargin()
- && mViewPort.height() >= minimumOverflowHeightWithMargin) {
+ && mViewPortOnScreen.height() >= minimumOverflowHeightWithMargin) {
// There is enough space at the bottom of the content rect for the main panel
// but not the overflow.
// Position below but open upwards.
updateOverflowHeight(availableHeightThroughContentUp - margin);
- y = contentRect.bottom + getToolbarHeightWithVerticalMargin() - getHeight();
+ y = contentRectOnScreen.bottom + getToolbarHeightWithVerticalMargin() -
+ getHeight();
mOverflowDirection = OVERFLOW_DIRECTION_UP;
} else {
// Not enough space.
// Position at the top of the view port and open downwards.
- updateOverflowHeight(mViewPort.height() - margin);
- y = mViewPort.top;
+ updateOverflowHeight(mViewPortOnScreen.height() - margin);
+ y = mViewPortOnScreen.top;
mOverflowDirection = OVERFLOW_DIRECTION_DOWN;
}
mOverflowPanel.setOverflowDirection(mOverflowDirection);
}
- mCoords.set(x, y);
+ mCoordsOnScreen.set(x, y);
}
private int getToolbarHeightWithVerticalMargin() {
@@ -913,18 +927,18 @@ public final class FloatingToolbar {
private void refreshViewPort() {
- mParent.getWindowVisibleDisplayFrame(mViewPort);
+ mParent.getWindowVisibleDisplayFrame(mViewPortOnScreen);
}
private boolean viewPortHasChanged() {
mParent.getWindowVisibleDisplayFrame(mTmpRect);
- return !mTmpRect.equals(mViewPort);
+ return !mTmpRect.equals(mViewPortOnScreen);
}
private int getToolbarWidth(int suggestedWidth) {
int width = suggestedWidth;
refreshViewPort();
- int maximumWidth = mViewPort.width() - 2 * mParent.getResources()
+ int maximumWidth = mViewPortOnScreen.width() - 2 * mParent.getResources()
.getDimensionPixelSize(R.dimen.floating_toolbar_horizontal_margin);
if (width <= 0) {
width = mParent.getResources()
@@ -1443,6 +1457,9 @@ public final class FloatingToolbar {
private static PopupWindow createPopupWindow(View content) {
ViewGroup popupContentHolder = new LinearLayout(content.getContext());
PopupWindow popupWindow = new PopupWindow(popupContentHolder);
+ // TODO: Use .setLayoutInScreenEnabled(true) instead of .setClippingEnabled(false)
+ // unless FLAG_LAYOUT_IN_SCREEN has any unintentional side-effects.
+ popupWindow.setClippingEnabled(false);
popupWindow.setWindowLayoutType(
WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL);
popupWindow.setAnimationStyle(0);