From 41ac866961f5aef3db234dd69951f472b5042123 Mon Sep 17 00:00:00 2001 From: Vladislav Kaznacheev Date: Fri, 24 Feb 2017 17:52:53 -0800 Subject: [PATCH] More accurate cascading submenu position The current submenu positioning logic is based on the assumption that the parent menu was displayed at the exact offset which was passed to the framework. The actual parent menu position could have been adjusted to fit the screen. Bug: 35767083 Test: manual Change-Id: Ib72eb7808ebf894c526d2c44c6116ee72542fd03 --- .../view/menu/CascadingMenuPopup.java | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/core/java/com/android/internal/view/menu/CascadingMenuPopup.java b/core/java/com/android/internal/view/menu/CascadingMenuPopup.java index 69e974c672d06..1de0af6f31dfa 100644 --- a/core/java/com/android/internal/view/menu/CascadingMenuPopup.java +++ b/core/java/com/android/internal/view/menu/CascadingMenuPopup.java @@ -388,14 +388,22 @@ final class CascadingMenuPopup extends MenuPopup implements MenuPresenter, OnKey final boolean showOnRight = nextMenuPosition == HORIZ_POSITION_RIGHT; mLastPosition = nextMenuPosition; - final int[] tempLocation = new int[2]; + // A popup anchored to mAnchorView with (0,0) offset would be shown at this position. + final int[] offsetOrigin = new int[2]; + mAnchorView.getLocationOnScreen(offsetOrigin); + offsetOrigin[1] += mAnchorView.getHeight(); - // This popup menu will be positioned relative to the top-left edge - // of the view representing its parent menu. - parentView.getLocationInWindow(tempLocation); - final int parentOffsetLeft = parentInfo.window.getHorizontalOffset() + tempLocation[0]; - final int parentOffsetTop = parentInfo.window.getVerticalOffset() + tempLocation[1]; + final int[] parentViewScreenLocation = new int[2]; + parentView.getLocationOnScreen(parentViewScreenLocation); + // Translate the parent view location into the offset coordinate space. + // If used as horizontal/vertical offsets, these values would position the submenu + // at the exact same position as the parent item. + final int parentOffsetLeft = parentViewScreenLocation[0] - offsetOrigin[0]; + final int parentOffsetTop = parentViewScreenLocation[1] - offsetOrigin[1]; + + // Adjust the horizontal offset to display the submenu to the right or to the left + // of the parent item. // By now, mDropDownGravity is the resolved absolute gravity, so // this should work in both LTR and RTL. final int x; @@ -412,11 +420,10 @@ final class CascadingMenuPopup extends MenuPopup implements MenuPresenter, OnKey x = parentOffsetLeft - menuWidth; } } - popupWindow.setHorizontalOffset(x); - final int y = parentOffsetTop; - popupWindow.setVerticalOffset(y); + // Use the same vertical offset as the parent item. + popupWindow.setVerticalOffset(parentOffsetTop); } else { if (mHasXOffset) { popupWindow.setHorizontalOffset(mXOffset);