Loading core/java/android/widget/ListPopupWindow.java +9 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ public class ListPopupWindow implements ShowableListMenu { private int mDropDownWindowLayoutType = WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL; private boolean mDropDownVerticalOffsetSet; private boolean mIsAnimatedFromAnchor = true; private boolean mOverlapAnchor; private int mDropDownGravity = Gravity.NO_GRAVITY; Loading Loading @@ -672,6 +673,7 @@ public class ListPopupWindow implements ShowableListMenu { mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch && !mDropDownAlwaysVisible); mPopup.setTouchInterceptor(mTouchInterceptor); mPopup.setEpicenterBounds(mEpicenterBounds); mPopup.setOverlapAnchor(mOverlapAnchor); mPopup.showAsDropDown(getAnchorView(), mDropDownHorizontalOffset, mDropDownVerticalOffset, mDropDownGravity); mDropDownList.setSelection(ListView.INVALID_POSITION); Loading Loading @@ -1245,6 +1247,13 @@ public class ListPopupWindow implements ShowableListMenu { return listContent + otherHeights; } /** * @hide */ public void setOverlapAnchor(boolean overlap) { mOverlapAnchor = overlap; } private class PopupDataSetObserver extends DataSetObserver { @Override public void onChanged() { Loading core/java/android/widget/PopupWindow.java +33 −8 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ import android.view.ViewTreeObserver.OnScrollChangedListener; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.view.WindowManager.LayoutParams.SoftInputModeFlags; import android.view.WindowManagerGlobal; import com.android.internal.R; Loading Loading @@ -137,6 +138,7 @@ public class PopupWindow { private final int[] mTmpDrawingLocation = new int[2]; private final int[] mTmpScreenLocation = new int[2]; private final int[] mTmpAppLocation = new int[2]; private final Rect mTempRect = new Rect(); private Context mContext; Loading Loading @@ -242,6 +244,9 @@ public class PopupWindow { private final OnScrollChangedListener mOnScrollChangedListener = this::alignToAnchor; private final View.OnLayoutChangeListener mOnLayoutChangeListener = (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> alignToAnchor(); private int mAnchorXoff; private int mAnchorYoff; private int mAnchoredGravity; Loading Loading @@ -1238,7 +1243,8 @@ public class PopupWindow { mIsShowing = true; mIsDropdown = true; final WindowManager.LayoutParams p = createPopupLayoutParams(anchor.getWindowToken()); final WindowManager.LayoutParams p = createPopupLayoutParams(anchor.getApplicationWindowToken()); preparePopup(p); final boolean aboveAnchor = findDropDownPosition(anchor, p, xoff, yoff, Loading Loading @@ -1547,13 +1553,21 @@ public class PopupWindow { } // Initially, align to the bottom-left corner of the anchor plus offsets. final int[] appScreenLocation = mTmpAppLocation; final View appRootView = getAppRootView(anchor); appRootView.getLocationOnScreen(appScreenLocation); final int[] screenLocation = mTmpScreenLocation; anchor.getLocationOnScreen(screenLocation); final int[] drawingLocation = mTmpDrawingLocation; anchor.getLocationInWindow(drawingLocation); drawingLocation[0] = screenLocation[0] - appScreenLocation[0]; drawingLocation[1] = screenLocation[1] - appScreenLocation[1]; outParams.x = drawingLocation[0] + xOffset; outParams.y = drawingLocation[1] + anchorHeight + yOffset; final Rect displayFrame = new Rect(); anchor.getWindowVisibleDisplayFrame(displayFrame); appRootView.getWindowVisibleDisplayFrame(displayFrame); if (width == MATCH_PARENT) { width = displayFrame.right - displayFrame.left; } Loading @@ -1574,9 +1588,6 @@ public class PopupWindow { outParams.x -= width - anchorWidth; } final int[] screenLocation = mTmpScreenLocation; anchor.getLocationOnScreen(screenLocation); // First, attempt to fit the popup vertically without resizing. final boolean fitsVertical = tryFitVertical(outParams, yOffset, height, anchorHeight, drawingLocation[1], screenLocation[1], displayFrame.top, Loading @@ -1595,7 +1606,9 @@ public class PopupWindow { scrollY + height + anchorHeight + yOffset); if (allowScroll && anchor.requestRectangleOnScreen(r, true)) { // Reset for the new anchor position. anchor.getLocationInWindow(drawingLocation); anchor.getLocationOnScreen(screenLocation); drawingLocation[0] = screenLocation[0] - appScreenLocation[0]; drawingLocation[1] = screenLocation[1] - appScreenLocation[1]; outParams.x = drawingLocation[0] + xOffset; outParams.y = drawingLocation[1] + anchorHeight + yOffset; Loading Loading @@ -1793,7 +1806,8 @@ public class PopupWindow { Rect displayFrame = null; final Rect visibleDisplayFrame = new Rect(); anchor.getWindowVisibleDisplayFrame(visibleDisplayFrame); final View appView = getAppRootView(anchor); appView.getWindowVisibleDisplayFrame(visibleDisplayFrame); if (ignoreBottomDecorations) { // In the ignore bottom decorations case we want to // still respect all other decorations so we use the inset visible Loading Loading @@ -2240,6 +2254,7 @@ public class PopupWindow { final View anchorRoot = mAnchorRoot != null ? mAnchorRoot.get() : null; if (anchorRoot != null) { anchorRoot.removeOnAttachStateChangeListener(mOnAnchorRootDetachedListener); anchorRoot.removeOnLayoutChangeListener(mOnLayoutChangeListener); } mAnchor = null; Loading @@ -2258,6 +2273,7 @@ public class PopupWindow { final View anchorRoot = anchor.getRootView(); anchorRoot.addOnAttachStateChangeListener(mOnAnchorRootDetachedListener); anchorRoot.addOnLayoutChangeListener(mOnLayoutChangeListener); mAnchor = new WeakReference<>(anchor); mAnchorRoot = new WeakReference<>(anchorRoot); Loading @@ -2281,6 +2297,15 @@ public class PopupWindow { } } private View getAppRootView(View anchor) { final View appWindowView = WindowManagerGlobal.getInstance().getWindowView( anchor.getApplicationWindowToken()); if (appWindowView != null) { return appWindowView; } return anchor.getRootView(); } private class PopupDecorView extends FrameLayout { private TransitionListenerAdapter mPendingExitListener; Loading core/java/com/android/internal/view/menu/CascadingMenuPopup.java +10 −21 Original line number Diff line number Diff line Loading @@ -381,6 +381,7 @@ final class CascadingMenuPopup extends MenuPopup implements MenuPresenter, OnKey if (parentView != null) { // This menu is a cascading submenu anchored to a parent view. popupWindow.setAnchorView(parentView); popupWindow.setTouchModal(false); popupWindow.setEnterTransition(null); Loading @@ -388,42 +389,30 @@ final class CascadingMenuPopup extends MenuPopup implements MenuPresenter, OnKey final boolean showOnRight = nextMenuPosition == HORIZ_POSITION_RIGHT; mLastPosition = nextMenuPosition; // 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(); 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 // Compute 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; if ((mDropDownGravity & Gravity.RIGHT) == Gravity.RIGHT) { if (showOnRight) { x = parentOffsetLeft + menuWidth; x = menuWidth; } else { x = parentOffsetLeft - parentView.getWidth(); x = -parentView.getWidth(); } } else { if (showOnRight) { x = parentOffsetLeft + parentView.getWidth(); x = parentView.getWidth(); } else { x = parentOffsetLeft - menuWidth; x = -menuWidth; } } popupWindow.setHorizontalOffset(x); // Use the same vertical offset as the parent item. popupWindow.setVerticalOffset(parentOffsetTop); // Align with the top edge of the parent view (or the bottom edge when the submenu is // flipped vertically). popupWindow.setOverlapAnchor(true); popupWindow.setVerticalOffset(0); } else { if (mHasXOffset) { popupWindow.setHorizontalOffset(mXOffset); Loading Loading
core/java/android/widget/ListPopupWindow.java +9 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ public class ListPopupWindow implements ShowableListMenu { private int mDropDownWindowLayoutType = WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL; private boolean mDropDownVerticalOffsetSet; private boolean mIsAnimatedFromAnchor = true; private boolean mOverlapAnchor; private int mDropDownGravity = Gravity.NO_GRAVITY; Loading Loading @@ -672,6 +673,7 @@ public class ListPopupWindow implements ShowableListMenu { mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch && !mDropDownAlwaysVisible); mPopup.setTouchInterceptor(mTouchInterceptor); mPopup.setEpicenterBounds(mEpicenterBounds); mPopup.setOverlapAnchor(mOverlapAnchor); mPopup.showAsDropDown(getAnchorView(), mDropDownHorizontalOffset, mDropDownVerticalOffset, mDropDownGravity); mDropDownList.setSelection(ListView.INVALID_POSITION); Loading Loading @@ -1245,6 +1247,13 @@ public class ListPopupWindow implements ShowableListMenu { return listContent + otherHeights; } /** * @hide */ public void setOverlapAnchor(boolean overlap) { mOverlapAnchor = overlap; } private class PopupDataSetObserver extends DataSetObserver { @Override public void onChanged() { Loading
core/java/android/widget/PopupWindow.java +33 −8 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ import android.view.ViewTreeObserver.OnScrollChangedListener; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.view.WindowManager.LayoutParams.SoftInputModeFlags; import android.view.WindowManagerGlobal; import com.android.internal.R; Loading Loading @@ -137,6 +138,7 @@ public class PopupWindow { private final int[] mTmpDrawingLocation = new int[2]; private final int[] mTmpScreenLocation = new int[2]; private final int[] mTmpAppLocation = new int[2]; private final Rect mTempRect = new Rect(); private Context mContext; Loading Loading @@ -242,6 +244,9 @@ public class PopupWindow { private final OnScrollChangedListener mOnScrollChangedListener = this::alignToAnchor; private final View.OnLayoutChangeListener mOnLayoutChangeListener = (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> alignToAnchor(); private int mAnchorXoff; private int mAnchorYoff; private int mAnchoredGravity; Loading Loading @@ -1238,7 +1243,8 @@ public class PopupWindow { mIsShowing = true; mIsDropdown = true; final WindowManager.LayoutParams p = createPopupLayoutParams(anchor.getWindowToken()); final WindowManager.LayoutParams p = createPopupLayoutParams(anchor.getApplicationWindowToken()); preparePopup(p); final boolean aboveAnchor = findDropDownPosition(anchor, p, xoff, yoff, Loading Loading @@ -1547,13 +1553,21 @@ public class PopupWindow { } // Initially, align to the bottom-left corner of the anchor plus offsets. final int[] appScreenLocation = mTmpAppLocation; final View appRootView = getAppRootView(anchor); appRootView.getLocationOnScreen(appScreenLocation); final int[] screenLocation = mTmpScreenLocation; anchor.getLocationOnScreen(screenLocation); final int[] drawingLocation = mTmpDrawingLocation; anchor.getLocationInWindow(drawingLocation); drawingLocation[0] = screenLocation[0] - appScreenLocation[0]; drawingLocation[1] = screenLocation[1] - appScreenLocation[1]; outParams.x = drawingLocation[0] + xOffset; outParams.y = drawingLocation[1] + anchorHeight + yOffset; final Rect displayFrame = new Rect(); anchor.getWindowVisibleDisplayFrame(displayFrame); appRootView.getWindowVisibleDisplayFrame(displayFrame); if (width == MATCH_PARENT) { width = displayFrame.right - displayFrame.left; } Loading @@ -1574,9 +1588,6 @@ public class PopupWindow { outParams.x -= width - anchorWidth; } final int[] screenLocation = mTmpScreenLocation; anchor.getLocationOnScreen(screenLocation); // First, attempt to fit the popup vertically without resizing. final boolean fitsVertical = tryFitVertical(outParams, yOffset, height, anchorHeight, drawingLocation[1], screenLocation[1], displayFrame.top, Loading @@ -1595,7 +1606,9 @@ public class PopupWindow { scrollY + height + anchorHeight + yOffset); if (allowScroll && anchor.requestRectangleOnScreen(r, true)) { // Reset for the new anchor position. anchor.getLocationInWindow(drawingLocation); anchor.getLocationOnScreen(screenLocation); drawingLocation[0] = screenLocation[0] - appScreenLocation[0]; drawingLocation[1] = screenLocation[1] - appScreenLocation[1]; outParams.x = drawingLocation[0] + xOffset; outParams.y = drawingLocation[1] + anchorHeight + yOffset; Loading Loading @@ -1793,7 +1806,8 @@ public class PopupWindow { Rect displayFrame = null; final Rect visibleDisplayFrame = new Rect(); anchor.getWindowVisibleDisplayFrame(visibleDisplayFrame); final View appView = getAppRootView(anchor); appView.getWindowVisibleDisplayFrame(visibleDisplayFrame); if (ignoreBottomDecorations) { // In the ignore bottom decorations case we want to // still respect all other decorations so we use the inset visible Loading Loading @@ -2240,6 +2254,7 @@ public class PopupWindow { final View anchorRoot = mAnchorRoot != null ? mAnchorRoot.get() : null; if (anchorRoot != null) { anchorRoot.removeOnAttachStateChangeListener(mOnAnchorRootDetachedListener); anchorRoot.removeOnLayoutChangeListener(mOnLayoutChangeListener); } mAnchor = null; Loading @@ -2258,6 +2273,7 @@ public class PopupWindow { final View anchorRoot = anchor.getRootView(); anchorRoot.addOnAttachStateChangeListener(mOnAnchorRootDetachedListener); anchorRoot.addOnLayoutChangeListener(mOnLayoutChangeListener); mAnchor = new WeakReference<>(anchor); mAnchorRoot = new WeakReference<>(anchorRoot); Loading @@ -2281,6 +2297,15 @@ public class PopupWindow { } } private View getAppRootView(View anchor) { final View appWindowView = WindowManagerGlobal.getInstance().getWindowView( anchor.getApplicationWindowToken()); if (appWindowView != null) { return appWindowView; } return anchor.getRootView(); } private class PopupDecorView extends FrameLayout { private TransitionListenerAdapter mPendingExitListener; Loading
core/java/com/android/internal/view/menu/CascadingMenuPopup.java +10 −21 Original line number Diff line number Diff line Loading @@ -381,6 +381,7 @@ final class CascadingMenuPopup extends MenuPopup implements MenuPresenter, OnKey if (parentView != null) { // This menu is a cascading submenu anchored to a parent view. popupWindow.setAnchorView(parentView); popupWindow.setTouchModal(false); popupWindow.setEnterTransition(null); Loading @@ -388,42 +389,30 @@ final class CascadingMenuPopup extends MenuPopup implements MenuPresenter, OnKey final boolean showOnRight = nextMenuPosition == HORIZ_POSITION_RIGHT; mLastPosition = nextMenuPosition; // 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(); 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 // Compute 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; if ((mDropDownGravity & Gravity.RIGHT) == Gravity.RIGHT) { if (showOnRight) { x = parentOffsetLeft + menuWidth; x = menuWidth; } else { x = parentOffsetLeft - parentView.getWidth(); x = -parentView.getWidth(); } } else { if (showOnRight) { x = parentOffsetLeft + parentView.getWidth(); x = parentView.getWidth(); } else { x = parentOffsetLeft - menuWidth; x = -menuWidth; } } popupWindow.setHorizontalOffset(x); // Use the same vertical offset as the parent item. popupWindow.setVerticalOffset(parentOffsetTop); // Align with the top edge of the parent view (or the bottom edge when the submenu is // flipped vertically). popupWindow.setOverlapAnchor(true); popupWindow.setVerticalOffset(0); } else { if (mHasXOffset) { popupWindow.setHorizontalOffset(mXOffset); Loading