summaryrefslogtreecommitdiffstats
path: root/core/java/android/widget
diff options
context:
space:
mode:
authorWale Ogunwale <ogunwale@google.com>2014-10-18 16:22:01 -0700
committerWale Ogunwale <ogunwale@google.com>2014-10-21 12:45:53 -0700
commit393b1c1e88cbdd0f65c8f217c495dbbe8de9125d (patch)
tree890ac0f1a0ad574604c3c44c83dbfbe9be1ffb25 /core/java/android/widget
parenta9a550dd8e87b33979670cf856838ba227500547 (diff)
downloadframeworks_base-393b1c1e88cbdd0f65c8f217c495dbbe8de9125d.zip
frameworks_base-393b1c1e88cbdd0f65c8f217c495dbbe8de9125d.tar.gz
frameworks_base-393b1c1e88cbdd0f65c8f217c495dbbe8de9125d.tar.bz2
Fix issue #17789629: PopupWindow overlaps with navigation bar.
The Lollipop release introduced a feature that allowed apps to extend under the navigation bar. This also means any popup window that is anchored to the bottom of its parent window will overlap with the navigation bar if the parent window is extending underneath the navigation bar. This change introduces a new window flag (FLAG_LAYOUT_ATTACHED_IN_DECOR) that allows the app to specify if the popup window should be attached to the decor frame of the parent window thereby avoiding an overlap with the screen decorations. By default the flag is set on SDK version LOLLIPOP_MR1 or greater and cleared on lesser SDK versions. Also, replaced flags FLAG_NEEDS_MENU_KEY and PRIVATE_FLAG_NEEDS_MENU_KEY_SET with needsMenuKey state variable to make room for the new FLAG_LAYOUT_ATTACHED_IN_DECOR flag. Bug: 17789629 Change-Id: I2150e0c6ac688c966c0e8f7e54d42fd20285bea6
Diffstat (limited to 'core/java/android/widget')
-rw-r--r--core/java/android/widget/PopupWindow.java63
1 files changed, 56 insertions, 7 deletions
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 41d3e320..54a7940 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -97,9 +97,11 @@ public class PopupWindow {
private boolean mAllowScrollingAnchorParent = true;
private boolean mLayoutInsetDecor = false;
private boolean mNotTouchModal;
+ private boolean mAttachedInDecor = true;
+ private boolean mAttachedInDecorSet = false;
private OnTouchListener mTouchInterceptor;
-
+
private int mWidthMode;
private int mWidth;
private int mLastWidth;
@@ -316,6 +318,7 @@ public class PopupWindow {
mContext = contentView.getContext();
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
}
+
setContentView(contentView);
setWidth(width);
setHeight(height);
@@ -373,16 +376,16 @@ public class PopupWindow {
public int getAnimationStyle() {
return mAnimationStyle;
}
-
+
/**
- * Set the flag on popup to ignore cheek press eventt; by default this flag
+ * Set the flag on popup to ignore cheek press event; by default this flag
* is set to false
* which means the pop wont ignore cheek press dispatch events.
- *
+ *
* <p>If the popup is showing, calling this method will take effect only
* the next time the popup is shown or through a manual call to one of
* the {@link #update()} methods.</p>
- *
+ *
* @see #update()
*/
public void setIgnoreCheekPress() {
@@ -443,6 +446,19 @@ public class PopupWindow {
if (mWindowManager == null && mContentView != null) {
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
}
+
+ // Setting the default for attachedInDecor based on SDK version here
+ // instead of in the constructor since we might not have the context
+ // object in the constructor. We only want to set default here if the
+ // app hasn't already set the attachedInDecor.
+ if (mContext != null && !mAttachedInDecorSet) {
+ // Attach popup window in decor frame of parent window by default for
+ // {@link Build.VERSION_CODES.LOLLIPOP_MR1} or greater. Keep current
+ // behavior of not attaching to decor frame for older SDKs.
+ setAttachedInDecor(mContext.getApplicationInfo().targetSdkVersion
+ >= Build.VERSION_CODES.LOLLIPOP_MR1);
+ }
+
}
/**
@@ -452,7 +468,7 @@ public class PopupWindow {
public void setTouchInterceptor(OnTouchListener l) {
mTouchInterceptor = l;
}
-
+
/**
* <p>Indicate whether the popup window can grab the focus.</p>
*
@@ -702,6 +718,36 @@ public class PopupWindow {
}
/**
+ * <p>Indicates whether the popup window will be attached in the decor frame of its parent
+ * window.
+ *
+ * @return true if the window will be attached to the decor frame of its parent window.
+ *
+ * @see #setAttachedInDecor(boolean)
+ * @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR
+ */
+ public boolean isAttachedInDecor() {
+ return mAttachedInDecor;
+ }
+
+ /**
+ * <p>This will attach the popup window to the decor frame of the parent window to avoid
+ * overlaping with screen decorations like the navigation bar. Overrides the default behavior of
+ * the flag {@link WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR}.
+ *
+ * <p>By default the flag is set on SDK version {@link Build.VERSION_CODES#LOLLIPOP_MR1} or
+ * greater and cleared on lesser SDK versions.
+ *
+ * @param enabled true if the popup should be attached to the decor frame of its parent window.
+ *
+ * @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR
+ */
+ public void setAttachedInDecor(boolean enabled) {
+ mAttachedInDecor = enabled;
+ mAttachedInDecorSet = true;
+ }
+
+ /**
* Allows the popup window to force the flag
* {@link WindowManager.LayoutParams#FLAG_LAYOUT_INSET_DECOR}, overriding default behavior.
* This will cause the popup to inset its content to account for system windows overlaying
@@ -1140,9 +1186,12 @@ public class PopupWindow {
if (mNotTouchModal) {
curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
}
+ if (mAttachedInDecor) {
+ curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR;
+ }
return curFlags;
}
-
+
private int computeAnimationResource() {
if (mAnimationStyle == -1) {
if (mIsDropdown) {