Loading core/java/android/widget/PopupWindow.java +49 −41 Original line number Original line Diff line number Diff line Loading @@ -1499,8 +1499,8 @@ public class PopupWindow { * * * @param anchor the view on which the popup window must be anchored * @param anchor the view on which the popup window must be anchored * @param outParams the layout parameters used to display the drop down * @param outParams the layout parameters used to display the drop down * @param xOffset horizontal offset used to adjust for background padding * @param xOffset absolute horizontal offset from the top of the anchor * @param yOffset vertical offset used to adjust for background padding * @param yOffset absolute vertical offset from the top of the anchor * @param gravity horizontal gravity specifying popup alignment * @param gravity horizontal gravity specifying popup alignment * @return true if the popup is translated upwards to fit on screen * @return true if the popup is translated upwards to fit on screen */ */ Loading @@ -1512,19 +1512,21 @@ public class PopupWindow { yOffset -= anchorHeight; yOffset -= anchorHeight; } } // Initially, align to the bottom-left corner of the anchor plus offsets. final int[] drawingLocation = mTmpDrawingLocation; final int[] drawingLocation = mTmpDrawingLocation; anchor.getLocationInWindow(drawingLocation); anchor.getLocationInWindow(drawingLocation); outParams.x = drawingLocation[0] + xOffset; outParams.x = drawingLocation[0] + xOffset; outParams.y = drawingLocation[1] + anchorHeight + yOffset; outParams.y = drawingLocation[1] + anchorHeight + yOffset; // If we need to adjust for gravity RIGHT, align to the bottom-right // corner of the anchor (still accounting for offsets). final int hgrav = Gravity.getAbsoluteGravity(gravity, anchor.getLayoutDirection()) final int hgrav = Gravity.getAbsoluteGravity(gravity, anchor.getLayoutDirection()) & Gravity.HORIZONTAL_GRAVITY_MASK; & Gravity.HORIZONTAL_GRAVITY_MASK; if (hgrav == Gravity.RIGHT) { if (hgrav == Gravity.RIGHT) { // Flip the location to align the right sides of the popup and // anchor instead of left. outParams.x -= width - anchorWidth; outParams.x -= width - anchorWidth; } } // Let the window manager know to align the top to y. outParams.gravity = Gravity.LEFT | Gravity.TOP; outParams.gravity = Gravity.LEFT | Gravity.TOP; final int[] screenLocation = mTmpScreenLocation; final int[] screenLocation = mTmpScreenLocation; Loading @@ -1533,14 +1535,15 @@ public class PopupWindow { final Rect displayFrame = new Rect(); final Rect displayFrame = new Rect(); anchor.getWindowVisibleDisplayFrame(displayFrame); anchor.getWindowVisibleDisplayFrame(displayFrame); final boolean onTop; boolean onTop = false; final int screenY = screenLocation[1] + anchorHeight + yOffset; final View root = anchor.getRootView(); final View root = anchor.getRootView(); if (screenY + height > displayFrame.bottom final int screenY = screenLocation[1] + anchorHeight + yOffset; || outParams.x + width - root.getWidth() > 0) { final boolean tooFarDown = screenY + height > displayFrame.bottom; // If the drop down disappears at the bottom of the screen, we try final boolean tooFarRight = outParams.x + width > root.getWidth(); // to scroll a parent scrollview or move the drop down back up on if (tooFarDown || tooFarRight) { // top of the edit box. // If the popup extends beyond the visible area, try to scroll the // parent so that it is fully visible. if (mAllowScrollingAnchorParent) { if (mAllowScrollingAnchorParent) { final int scrollX = anchor.getScrollX(); final int scrollX = anchor.getScrollX(); final int scrollY = anchor.getScrollY(); final int scrollY = anchor.getScrollY(); Loading @@ -1549,8 +1552,7 @@ public class PopupWindow { anchor.requestRectangleOnScreen(r, true); anchor.requestRectangleOnScreen(r, true); } } // Now we re-evaluate the space available, and decide from that // Update for the new anchor position. // whether the pop-up will go above or below the anchor. anchor.getLocationInWindow(drawingLocation); anchor.getLocationInWindow(drawingLocation); outParams.x = drawingLocation[0] + xOffset; outParams.x = drawingLocation[0] + xOffset; outParams.y = drawingLocation[1] + anchorHeight + yOffset; outParams.y = drawingLocation[1] + anchorHeight + yOffset; Loading @@ -1560,25 +1562,30 @@ public class PopupWindow { outParams.x -= width - anchorWidth; outParams.x -= width - anchorWidth; } } // Determine whether there is more space above or below the anchor. final int newScreenY = screenLocation[1] + anchorHeight + yOffset; final boolean stillTooFarDown = newScreenY + height > displayFrame.bottom; if (stillTooFarDown) { // If the popup is still too far down, re-evaluate the space // available and decide whether the pop-up will go above or // below the anchor. anchor.getLocationOnScreen(screenLocation); anchor.getLocationOnScreen(screenLocation); final int spaceBelow = displayFrame.bottom - screenLocation[1] - anchorHeight - yOffset; final int spaceAbove = screenLocation[1] - yOffset - displayFrame.top; onTop = spaceBelow < spaceAbove; if (!mOverlapAnchor) { final int below = displayFrame.bottom - screenLocation[1] - anchorHeight - yOffset; final int above = screenLocation[1] - displayFrame.top + yOffset; onTop = above > below; if (onTop) { if (onTop) { outParams.gravity = Gravity.LEFT | Gravity.BOTTOM; // Move everything up. outParams.y = root.getHeight() - drawingLocation[1] + yOffset; if (mOverlapAnchor) { } else { yOffset += anchorHeight; outParams.y = drawingLocation[1] + anchorHeight + yOffset; } outParams.y = drawingLocation[1] - height + yOffset; } } } } } else { onTop = false; } } if (mClipToScreen) { if (mClipToScreen) { // Use screen coordinates for comparison against display frame. final int winOffsetX = screenLocation[0] - drawingLocation[0]; final int winOffsetX = screenLocation[0] - drawingLocation[0]; final int winOffsetY = screenLocation[1] - drawingLocation[1]; final int winOffsetY = screenLocation[1] - drawingLocation[1]; outParams.x += winOffsetX; outParams.x += winOffsetX; Loading @@ -1586,30 +1593,32 @@ public class PopupWindow { final int right = outParams.x + width; final int right = outParams.x + width; if (right > displayFrame.right) { if (right > displayFrame.right) { // The popup is too far right, move it back in. outParams.x -= right - displayFrame.right; outParams.x -= right - displayFrame.right; } } if (outParams.x < displayFrame.left) { if (outParams.x < displayFrame.left) { // The popup is too far left, move it back in and clip if it's // still too large. outParams.x = displayFrame.left; outParams.x = displayFrame.left; final int displayFrameWidth = displayFrame.right - displayFrame.left; final int displayFrameWidth = displayFrame.width(); width = Math.min(width, displayFrameWidth); width = Math.min(width, displayFrameWidth); } } if (mOverlapAnchor) { final int bottom = outParams.y + height; final int bottom = outParams.y + width; if (bottom > displayFrame.bottom) { if (bottom > displayFrame.bottom) { // The popup is too far down, move it back in. outParams.y -= bottom - displayFrame.bottom; outParams.y -= bottom - displayFrame.bottom; } } } else { if (onTop) { if (outParams.y < displayFrame.top) { final int popupTop = screenLocation[1] + yOffset - height; // The popup is too far up, move it back in and clip if if (popupTop < 0) { // it's still too large. outParams.y += popupTop; outParams.y = displayFrame.top; } } else { final int displayFrameHeight = displayFrame.height(); outParams.y = Math.max(outParams.y, displayFrame.top); height = Math.min(height, displayFrameHeight); } } } outParams.x -= winOffsetX; outParams.x -= winOffsetX; Loading @@ -1618,7 +1627,6 @@ public class PopupWindow { outParams.width = width; outParams.width = width; outParams.height = height; outParams.height = height; outParams.gravity |= Gravity.DISPLAY_CLIP_VERTICAL; return onTop; return onTop; } } Loading Loading
core/java/android/widget/PopupWindow.java +49 −41 Original line number Original line Diff line number Diff line Loading @@ -1499,8 +1499,8 @@ public class PopupWindow { * * * @param anchor the view on which the popup window must be anchored * @param anchor the view on which the popup window must be anchored * @param outParams the layout parameters used to display the drop down * @param outParams the layout parameters used to display the drop down * @param xOffset horizontal offset used to adjust for background padding * @param xOffset absolute horizontal offset from the top of the anchor * @param yOffset vertical offset used to adjust for background padding * @param yOffset absolute vertical offset from the top of the anchor * @param gravity horizontal gravity specifying popup alignment * @param gravity horizontal gravity specifying popup alignment * @return true if the popup is translated upwards to fit on screen * @return true if the popup is translated upwards to fit on screen */ */ Loading @@ -1512,19 +1512,21 @@ public class PopupWindow { yOffset -= anchorHeight; yOffset -= anchorHeight; } } // Initially, align to the bottom-left corner of the anchor plus offsets. final int[] drawingLocation = mTmpDrawingLocation; final int[] drawingLocation = mTmpDrawingLocation; anchor.getLocationInWindow(drawingLocation); anchor.getLocationInWindow(drawingLocation); outParams.x = drawingLocation[0] + xOffset; outParams.x = drawingLocation[0] + xOffset; outParams.y = drawingLocation[1] + anchorHeight + yOffset; outParams.y = drawingLocation[1] + anchorHeight + yOffset; // If we need to adjust for gravity RIGHT, align to the bottom-right // corner of the anchor (still accounting for offsets). final int hgrav = Gravity.getAbsoluteGravity(gravity, anchor.getLayoutDirection()) final int hgrav = Gravity.getAbsoluteGravity(gravity, anchor.getLayoutDirection()) & Gravity.HORIZONTAL_GRAVITY_MASK; & Gravity.HORIZONTAL_GRAVITY_MASK; if (hgrav == Gravity.RIGHT) { if (hgrav == Gravity.RIGHT) { // Flip the location to align the right sides of the popup and // anchor instead of left. outParams.x -= width - anchorWidth; outParams.x -= width - anchorWidth; } } // Let the window manager know to align the top to y. outParams.gravity = Gravity.LEFT | Gravity.TOP; outParams.gravity = Gravity.LEFT | Gravity.TOP; final int[] screenLocation = mTmpScreenLocation; final int[] screenLocation = mTmpScreenLocation; Loading @@ -1533,14 +1535,15 @@ public class PopupWindow { final Rect displayFrame = new Rect(); final Rect displayFrame = new Rect(); anchor.getWindowVisibleDisplayFrame(displayFrame); anchor.getWindowVisibleDisplayFrame(displayFrame); final boolean onTop; boolean onTop = false; final int screenY = screenLocation[1] + anchorHeight + yOffset; final View root = anchor.getRootView(); final View root = anchor.getRootView(); if (screenY + height > displayFrame.bottom final int screenY = screenLocation[1] + anchorHeight + yOffset; || outParams.x + width - root.getWidth() > 0) { final boolean tooFarDown = screenY + height > displayFrame.bottom; // If the drop down disappears at the bottom of the screen, we try final boolean tooFarRight = outParams.x + width > root.getWidth(); // to scroll a parent scrollview or move the drop down back up on if (tooFarDown || tooFarRight) { // top of the edit box. // If the popup extends beyond the visible area, try to scroll the // parent so that it is fully visible. if (mAllowScrollingAnchorParent) { if (mAllowScrollingAnchorParent) { final int scrollX = anchor.getScrollX(); final int scrollX = anchor.getScrollX(); final int scrollY = anchor.getScrollY(); final int scrollY = anchor.getScrollY(); Loading @@ -1549,8 +1552,7 @@ public class PopupWindow { anchor.requestRectangleOnScreen(r, true); anchor.requestRectangleOnScreen(r, true); } } // Now we re-evaluate the space available, and decide from that // Update for the new anchor position. // whether the pop-up will go above or below the anchor. anchor.getLocationInWindow(drawingLocation); anchor.getLocationInWindow(drawingLocation); outParams.x = drawingLocation[0] + xOffset; outParams.x = drawingLocation[0] + xOffset; outParams.y = drawingLocation[1] + anchorHeight + yOffset; outParams.y = drawingLocation[1] + anchorHeight + yOffset; Loading @@ -1560,25 +1562,30 @@ public class PopupWindow { outParams.x -= width - anchorWidth; outParams.x -= width - anchorWidth; } } // Determine whether there is more space above or below the anchor. final int newScreenY = screenLocation[1] + anchorHeight + yOffset; final boolean stillTooFarDown = newScreenY + height > displayFrame.bottom; if (stillTooFarDown) { // If the popup is still too far down, re-evaluate the space // available and decide whether the pop-up will go above or // below the anchor. anchor.getLocationOnScreen(screenLocation); anchor.getLocationOnScreen(screenLocation); final int spaceBelow = displayFrame.bottom - screenLocation[1] - anchorHeight - yOffset; final int spaceAbove = screenLocation[1] - yOffset - displayFrame.top; onTop = spaceBelow < spaceAbove; if (!mOverlapAnchor) { final int below = displayFrame.bottom - screenLocation[1] - anchorHeight - yOffset; final int above = screenLocation[1] - displayFrame.top + yOffset; onTop = above > below; if (onTop) { if (onTop) { outParams.gravity = Gravity.LEFT | Gravity.BOTTOM; // Move everything up. outParams.y = root.getHeight() - drawingLocation[1] + yOffset; if (mOverlapAnchor) { } else { yOffset += anchorHeight; outParams.y = drawingLocation[1] + anchorHeight + yOffset; } outParams.y = drawingLocation[1] - height + yOffset; } } } } } else { onTop = false; } } if (mClipToScreen) { if (mClipToScreen) { // Use screen coordinates for comparison against display frame. final int winOffsetX = screenLocation[0] - drawingLocation[0]; final int winOffsetX = screenLocation[0] - drawingLocation[0]; final int winOffsetY = screenLocation[1] - drawingLocation[1]; final int winOffsetY = screenLocation[1] - drawingLocation[1]; outParams.x += winOffsetX; outParams.x += winOffsetX; Loading @@ -1586,30 +1593,32 @@ public class PopupWindow { final int right = outParams.x + width; final int right = outParams.x + width; if (right > displayFrame.right) { if (right > displayFrame.right) { // The popup is too far right, move it back in. outParams.x -= right - displayFrame.right; outParams.x -= right - displayFrame.right; } } if (outParams.x < displayFrame.left) { if (outParams.x < displayFrame.left) { // The popup is too far left, move it back in and clip if it's // still too large. outParams.x = displayFrame.left; outParams.x = displayFrame.left; final int displayFrameWidth = displayFrame.right - displayFrame.left; final int displayFrameWidth = displayFrame.width(); width = Math.min(width, displayFrameWidth); width = Math.min(width, displayFrameWidth); } } if (mOverlapAnchor) { final int bottom = outParams.y + height; final int bottom = outParams.y + width; if (bottom > displayFrame.bottom) { if (bottom > displayFrame.bottom) { // The popup is too far down, move it back in. outParams.y -= bottom - displayFrame.bottom; outParams.y -= bottom - displayFrame.bottom; } } } else { if (onTop) { if (outParams.y < displayFrame.top) { final int popupTop = screenLocation[1] + yOffset - height; // The popup is too far up, move it back in and clip if if (popupTop < 0) { // it's still too large. outParams.y += popupTop; outParams.y = displayFrame.top; } } else { final int displayFrameHeight = displayFrame.height(); outParams.y = Math.max(outParams.y, displayFrame.top); height = Math.min(height, displayFrameHeight); } } } outParams.x -= winOffsetX; outParams.x -= winOffsetX; Loading @@ -1618,7 +1627,6 @@ public class PopupWindow { outParams.width = width; outParams.width = width; outParams.height = height; outParams.height = height; outParams.gravity |= Gravity.DISPLAY_CLIP_VERTICAL; return onTop; return onTop; } } Loading