PopupWindowpublic class PopupWindow extends Object A popup window that can be used to display an arbitrary view. The popup
window is a floating container that appears on top of the current
activity. |
Fields Summary |
---|
public static final int | INPUT_METHOD_FROM_FOCUSABLEMode for {@link #setInputMethodMode(int)}: the requirements for the
input method should be based on the focusability of the popup. That is
if it is focusable than it needs to work with the input method, else
it doesn't. | public static final int | INPUT_METHOD_NEEDEDMode for {@link #setInputMethodMode(int)}: this popup always needs to
work with an input method, regardless of whether it is focusable. This
means that it will always be displayed so that the user can also operate
the input method while it is shown. | public static final int | INPUT_METHOD_NOT_NEEDEDMode for {@link #setInputMethodMode(int)}: this popup never needs to
work with an input method, regardless of whether it is focusable. This
means that it will always be displayed to use as much space on the
screen as needed, regardless of whether this covers the input method. | private static final int | DEFAULT_ANCHORED_GRAVITY | private android.content.Context | mContext | private android.view.WindowManager | mWindowManager | private boolean | mIsShowing | private boolean | mIsDropdown | private android.view.View | mContentView | private android.view.View | mPopupView | private boolean | mFocusable | private int | mInputMethodMode | private int | mSoftInputMode | private boolean | mTouchable | private boolean | mOutsideTouchable | private boolean | mClippingEnabled | private int | mSplitTouchEnabled | private boolean | mLayoutInScreen | private boolean | mClipToScreen | private boolean | mAllowScrollingAnchorParent | private boolean | mLayoutInsetDecor | private boolean | mNotTouchModal | private boolean | mAttachedInDecor | private boolean | mAttachedInDecorSet | private android.view.View.OnTouchListener | mTouchInterceptor | private int | mWidthMode | private int | mWidth | private int | mLastWidth | private int | mHeightMode | private int | mHeight | private int | mLastHeight | private int | mPopupWidth | private int | mPopupHeight | private float | mElevation | private int[] | mDrawingLocation | private int[] | mScreenLocation | private android.graphics.Rect | mTempRect | private android.graphics.drawable.Drawable | mBackground | private android.graphics.drawable.Drawable | mAboveAnchorBackgroundDrawable | private android.graphics.drawable.Drawable | mBelowAnchorBackgroundDrawable | private int | mAnchorRelativeX | private int | mAnchorRelativeY | private boolean | mAboveAnchor | private int | mWindowLayoutType | private OnDismissListener | mOnDismissListener | private boolean | mIgnoreCheekPress | private int | mAnimationStyle | private static final int[] | ABOVE_ANCHOR_STATE_SET | private WeakReference | mAnchor | private final android.view.ViewTreeObserver.OnScrollChangedListener | mOnScrollChangedListener | private int | mAnchorXoff | private int | mAnchorYoff | private int | mAnchoredGravity | private boolean | mOverlapAnchor | private boolean | mPopupViewInitialLayoutDirectionInherited |
Constructors Summary |
---|
public PopupWindow(android.content.Context context)Create a new empty, non focusable popup window of dimension (0,0).
The popup does provide a background.
this(context, null);
| public PopupWindow(android.content.Context context, android.util.AttributeSet attrs)Create a new empty, non focusable popup window of dimension (0,0).
The popup does provide a background.
this(context, attrs, com.android.internal.R.attr.popupWindowStyle);
| public PopupWindow(android.content.Context context, android.util.AttributeSet attrs, int defStyleAttr)Create a new empty, non focusable popup window of dimension (0,0).
The popup does provide a background.
this(context, attrs, defStyleAttr, 0);
| public PopupWindow(android.content.Context context, android.util.AttributeSet attrs, int defStyleAttr, int defStyleRes)Create a new, empty, non focusable popup window of dimension (0,0).
The popup does not provide a background.
mContext = context;
mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.PopupWindow, defStyleAttr, defStyleRes);
final Drawable bg = a.getDrawable(R.styleable.PopupWindow_popupBackground);
mElevation = a.getDimension(R.styleable.PopupWindow_popupElevation, 0);
mOverlapAnchor = a.getBoolean(R.styleable.PopupWindow_overlapAnchor, false);
final int animStyle = a.getResourceId(R.styleable.PopupWindow_popupAnimationStyle, -1);
mAnimationStyle = animStyle == R.style.Animation_PopupWindow ? -1 : animStyle;
a.recycle();
setBackgroundDrawable(bg);
| public PopupWindow()Create a new empty, non focusable popup window of dimension (0,0).
The popup does not provide any background. This should be handled
by the content view.
this(null, 0, 0);
| public PopupWindow(android.view.View contentView)Create a new non focusable popup window which can display the
contentView. The dimension of the window are (0,0).
The popup does not provide any background. This should be handled
by the content view.
this(contentView, 0, 0);
| public PopupWindow(int width, int height)Create a new empty, non focusable popup window. The dimension of the
window must be passed to this constructor.
The popup does not provide any background. This should be handled
by the content view.
this(null, width, height);
| public PopupWindow(android.view.View contentView, int width, int height)Create a new non focusable popup window which can display the
contentView. The dimension of the window must be passed to
this constructor.
The popup does not provide any background. This should be handled
by the content view.
this(contentView, width, height, false);
| public PopupWindow(android.view.View contentView, int width, int height, boolean focusable)Create a new popup window which can display the contentView.
The dimension of the window must be passed to this constructor.
The popup does not provide any background. This should be handled
by the content view.
if (contentView != null) {
mContext = contentView.getContext();
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
}
setContentView(contentView);
setWidth(width);
setHeight(height);
setFocusable(focusable);
|
Methods Summary |
---|
private int | computeAnimationResource()
if (mAnimationStyle == -1) {
if (mIsDropdown) {
return mAboveAnchor
? com.android.internal.R.style.Animation_DropDownUp
: com.android.internal.R.style.Animation_DropDownDown;
}
return 0;
}
return mAnimationStyle;
| private int | computeFlags(int curFlags)
curFlags &= ~(
WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES |
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
WindowManager.LayoutParams.FLAG_SPLIT_TOUCH);
if(mIgnoreCheekPress) {
curFlags |= WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES;
}
if (!mFocusable) {
curFlags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
if (mInputMethodMode == INPUT_METHOD_NEEDED) {
curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
}
} else if (mInputMethodMode == INPUT_METHOD_NOT_NEEDED) {
curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
}
if (!mTouchable) {
curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
}
if (mOutsideTouchable) {
curFlags |= WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
}
if (!mClippingEnabled) {
curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
}
if (isSplitTouchEnabled()) {
curFlags |= WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
}
if (mLayoutInScreen) {
curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
}
if (mLayoutInsetDecor) {
curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
}
if (mNotTouchModal) {
curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
}
if (mAttachedInDecor) {
curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR;
}
return curFlags;
| private WindowManager.LayoutParams | createPopupLayout(android.os.IBinder token)Generate the layout parameters for the popup window.
// generates the layout parameters for the drop down
// we want a fixed size view located at the bottom left of the anchor
WindowManager.LayoutParams p = new WindowManager.LayoutParams();
// these gravity settings put the view at the top left corner of the
// screen. The view is then positioned to the appropriate location
// by setting the x and y offsets to match the anchor's bottom
// left corner
p.gravity = Gravity.START | Gravity.TOP;
p.width = mLastWidth = mWidth;
p.height = mLastHeight = mHeight;
if (mBackground != null) {
p.format = mBackground.getOpacity();
} else {
p.format = PixelFormat.TRANSLUCENT;
}
p.flags = computeFlags(p.flags);
p.type = mWindowLayoutType;
p.token = token;
p.softInputMode = mSoftInputMode;
p.setTitle("PopupWindow:" + Integer.toHexString(hashCode()));
return p;
| public void | dismiss()Dispose of the popup window. This method can be invoked only after
{@link #showAsDropDown(android.view.View)} has been executed. Failing that, calling
this method will have no effect.
if (isShowing() && mPopupView != null) {
mIsShowing = false;
unregisterForScrollChanged();
try {
mWindowManager.removeViewImmediate(mPopupView);
} finally {
if (mPopupView != mContentView && mPopupView instanceof ViewGroup) {
((ViewGroup) mPopupView).removeView(mContentView);
}
mPopupView = null;
if (mOnDismissListener != null) {
mOnDismissListener.onDismiss();
}
}
}
| private boolean | findDropDownPosition(android.view.View anchor, WindowManager.LayoutParams p, int xoff, int yoff, int gravity)Positions the popup window on screen. When the popup window is too tall
to fit under the anchor, a parent scroll view is seeked and scrolled up
to reclaim space. If scrolling is not possible or not enough, the popup
window gets moved on top of the anchor.
The height must have been set on the layout parameters prior to calling
this method.
final int anchorHeight = anchor.getHeight();
final int anchorWidth = anchor.getWidth();
if (mOverlapAnchor) {
yoff -= anchorHeight;
}
anchor.getLocationInWindow(mDrawingLocation);
p.x = mDrawingLocation[0] + xoff;
p.y = mDrawingLocation[1] + anchorHeight + yoff;
final int hgrav = Gravity.getAbsoluteGravity(gravity, anchor.getLayoutDirection())
& Gravity.HORIZONTAL_GRAVITY_MASK;
if (hgrav == Gravity.RIGHT) {
// Flip the location to align the right sides of the popup and
// anchor instead of left.
p.x -= mPopupWidth - anchorWidth;
}
boolean onTop = false;
p.gravity = Gravity.LEFT | Gravity.TOP;
anchor.getLocationOnScreen(mScreenLocation);
final Rect displayFrame = new Rect();
anchor.getWindowVisibleDisplayFrame(displayFrame);
final int screenY = mScreenLocation[1] + anchorHeight + yoff;
final View root = anchor.getRootView();
if (screenY + mPopupHeight > displayFrame.bottom
|| p.x + mPopupWidth - root.getWidth() > 0) {
// If the drop down disappears at the bottom of the screen, we try
// to scroll a parent scrollview or move the drop down back up on
// top of the edit box.
if (mAllowScrollingAnchorParent) {
final int scrollX = anchor.getScrollX();
final int scrollY = anchor.getScrollY();
final Rect r = new Rect(scrollX, scrollY, scrollX + mPopupWidth + xoff,
scrollY + mPopupHeight + anchorHeight + yoff);
anchor.requestRectangleOnScreen(r, true);
}
// Now we re-evaluate the space available, and decide from that
// whether the pop-up will go above or below the anchor.
anchor.getLocationInWindow(mDrawingLocation);
p.x = mDrawingLocation[0] + xoff;
p.y = mDrawingLocation[1] + anchorHeight + yoff;
// Preserve the gravity adjustment.
if (hgrav == Gravity.RIGHT) {
p.x -= mPopupWidth - anchorWidth;
}
// Determine whether there is more space above or below the anchor.
anchor.getLocationOnScreen(mScreenLocation);
onTop = (displayFrame.bottom - mScreenLocation[1] - anchorHeight - yoff) <
(mScreenLocation[1] - yoff - displayFrame.top);
if (onTop) {
p.gravity = Gravity.LEFT | Gravity.BOTTOM;
p.y = root.getHeight() - mDrawingLocation[1] + yoff;
} else {
p.y = mDrawingLocation[1] + anchorHeight + yoff;
}
}
if (mClipToScreen) {
final int displayFrameWidth = displayFrame.right - displayFrame.left;
final int right = p.x + p.width;
if (right > displayFrameWidth) {
p.x -= right - displayFrameWidth;
}
if (p.x < displayFrame.left) {
p.x = displayFrame.left;
p.width = Math.min(p.width, displayFrameWidth);
}
if (onTop) {
final int popupTop = mScreenLocation[1] + yoff - mPopupHeight;
if (popupTop < 0) {
p.y += popupTop;
}
} else {
p.y = Math.max(p.y, displayFrame.top);
}
}
p.gravity |= Gravity.DISPLAY_CLIP_VERTICAL;
// Compute the position of the anchor relative to the popup.
mAnchorRelativeX = mDrawingLocation[0] - p.x + anchorHeight / 2;
mAnchorRelativeY = mDrawingLocation[1] - p.y + anchorWidth / 2;
return onTop;
| public int | getAnimationStyle()Return the animation style to use the popup appears and disappears
return mAnimationStyle;
| public android.graphics.drawable.Drawable | getBackground()Return the drawable used as the popup window's background.
return mBackground;
| public android.view.View | getContentView()Return the view used as the content of the popup window.
return mContentView;
| public float | getElevation()
return mElevation;
| public int | getHeight()Return this popup's height MeasureSpec
return mHeight;
| public int | getInputMethodMode()Return the current value in {@link #setInputMethodMode(int)}.
return mInputMethodMode;
| public int | getMaxAvailableHeight(android.view.View anchor)Returns the maximum height that is available for the popup to be
completely shown. It is recommended that this height be the maximum for
the popup's height, otherwise it is possible that the popup will be
clipped.
return getMaxAvailableHeight(anchor, 0);
| public int | getMaxAvailableHeight(android.view.View anchor, int yOffset)Returns the maximum height that is available for the popup to be
completely shown. It is recommended that this height be the maximum for
the popup's height, otherwise it is possible that the popup will be
clipped.
return getMaxAvailableHeight(anchor, yOffset, false);
| public int | getMaxAvailableHeight(android.view.View anchor, int yOffset, boolean ignoreBottomDecorations)Returns the maximum height that is available for the popup to be
completely shown, optionally ignoring any bottom decorations such as
the input method. It is recommended that this height be the maximum for
the popup's height, otherwise it is possible that the popup will be
clipped.
final Rect displayFrame = new Rect();
anchor.getWindowVisibleDisplayFrame(displayFrame);
final int[] anchorPos = mDrawingLocation;
anchor.getLocationOnScreen(anchorPos);
int bottomEdge = displayFrame.bottom;
if (ignoreBottomDecorations) {
Resources res = anchor.getContext().getResources();
bottomEdge = res.getDisplayMetrics().heightPixels;
}
final int distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset;
final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset;
// anchorPos[1] is distance from anchor to top of screen
int returnedHeight = Math.max(distanceToBottom, distanceToTop);
if (mBackground != null) {
mBackground.getPadding(mTempRect);
returnedHeight -= mTempRect.top + mTempRect.bottom;
}
return returnedHeight;
| public int | getSoftInputMode()Returns the current value in {@link #setSoftInputMode(int)}.
return mSoftInputMode;
| public int | getWidth()Return this popup's width MeasureSpec
return mWidth;
| public int | getWindowLayoutType()
return mWindowLayoutType;
| private void | invokePopup(WindowManager.LayoutParams p)Invoke the popup window by adding the content view to the window
manager.
The content view must be non-null when this method is invoked.
if (mContext != null) {
p.packageName = mContext.getPackageName();
}
mPopupView.setFitsSystemWindows(mLayoutInsetDecor);
setLayoutDirectionFromAnchor();
mWindowManager.addView(mPopupView, p);
| public boolean | isAboveAnchor()Indicates whether the popup is showing above (the y coordinate of the popup's bottom
is less than the y coordinate of the anchor) or below the anchor view (the y coordinate
of the popup is greater than y coordinate of the anchor's bottom).
The value returned
by this method is meaningful only after {@link #showAsDropDown(android.view.View)}
or {@link #showAsDropDown(android.view.View, int, int)} was invoked.
return mAboveAnchor;
| public boolean | isAttachedInDecor()Indicates whether the popup window will be attached in the decor frame of its parent
window.
return mAttachedInDecor;
| public boolean | isClippingEnabled()Indicates whether clipping of the popup window is enabled.
return mClippingEnabled;
| public boolean | isFocusable()Indicate whether the popup window can grab the focus.
return mFocusable;
| public boolean | isLayoutInScreenEnabled()Indicates whether the popup window will be forced into using absolute screen coordinates
for positioning.
return mLayoutInScreen;
| public boolean | isOutsideTouchable()Indicates whether the popup window will be informed of touch events
outside of its window.
return mOutsideTouchable;
| public boolean | isShowing()Indicate whether this popup window is showing on screen.
return mIsShowing;
| public boolean | isSplitTouchEnabled()Indicates whether the popup window supports splitting touches.
if (mSplitTouchEnabled < 0 && mContext != null) {
return mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB;
}
return mSplitTouchEnabled == 1;
| public boolean | isTouchable()Indicates whether the popup window receives touch events.
return mTouchable;
| private void | preparePopup(WindowManager.LayoutParams p)Prepare the popup by embedding in into a new ViewGroup if the
background drawable is not null. If embedding is required, the layout
parameters' height is modified to take into account the background's
padding.
if (mContentView == null || mContext == null || mWindowManager == null) {
throw new IllegalStateException("You must specify a valid content view by "
+ "calling setContentView() before attempting to show the popup.");
}
if (mBackground != null) {
final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams();
int height = ViewGroup.LayoutParams.MATCH_PARENT;
if (layoutParams != null &&
layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
height = ViewGroup.LayoutParams.WRAP_CONTENT;
}
// when a background is available, we embed the content view
// within another view that owns the background drawable
PopupViewContainer popupViewContainer = new PopupViewContainer(mContext);
PopupViewContainer.LayoutParams listParams = new PopupViewContainer.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, height
);
popupViewContainer.setBackground(mBackground);
popupViewContainer.addView(mContentView, listParams);
mPopupView = popupViewContainer;
} else {
mPopupView = mContentView;
}
mPopupView.setElevation(mElevation);
mPopupViewInitialLayoutDirectionInherited =
(mPopupView.getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT);
mPopupWidth = p.width;
mPopupHeight = p.height;
| private void | registerForScrollChanged(android.view.View anchor, int xoff, int yoff, int gravity)
unregisterForScrollChanged();
mAnchor = new WeakReference<View>(anchor);
ViewTreeObserver vto = anchor.getViewTreeObserver();
if (vto != null) {
vto.addOnScrollChangedListener(mOnScrollChangedListener);
}
mAnchorXoff = xoff;
mAnchorYoff = yoff;
mAnchoredGravity = gravity;
| void | setAllowScrollingAnchorParent(boolean enabled)Allow PopupWindow to scroll the anchor's parent to provide more room
for the popup. Enabled by default.
mAllowScrollingAnchorParent = enabled;
| public void | setAnimationStyle(int animationStyle)Change the animation style resource for this popup.
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.
mAnimationStyle = animationStyle;
| public void | setAttachedInDecor(boolean enabled)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}.
By default the flag is set on SDK version {@link Build.VERSION_CODES#LOLLIPOP_MR1} or
greater and cleared on lesser SDK versions.
mAttachedInDecor = enabled;
mAttachedInDecorSet = true;
| public void | setBackgroundDrawable(android.graphics.drawable.Drawable background)Specifies the background drawable for this popup window. The background
can be set to {@code null}.
mBackground = background;
// If this is a StateListDrawable, try to find and store the drawable to be
// used when the drop-down is placed above its anchor view, and the one to be
// used when the drop-down is placed below its anchor view. We extract
// the drawables ourselves to work around a problem with using refreshDrawableState
// that it will take into account the padding of all drawables specified in a
// StateListDrawable, thus adding superfluous padding to drop-down views.
//
// We assume a StateListDrawable will have a drawable for ABOVE_ANCHOR_STATE_SET and
// at least one other drawable, intended for the 'below-anchor state'.
if (mBackground instanceof StateListDrawable) {
StateListDrawable stateList = (StateListDrawable) mBackground;
// Find the above-anchor view - this one's easy, it should be labeled as such.
int aboveAnchorStateIndex = stateList.getStateDrawableIndex(ABOVE_ANCHOR_STATE_SET);
// Now, for the below-anchor view, look for any other drawable specified in the
// StateListDrawable which is not for the above-anchor state and use that.
int count = stateList.getStateCount();
int belowAnchorStateIndex = -1;
for (int i = 0; i < count; i++) {
if (i != aboveAnchorStateIndex) {
belowAnchorStateIndex = i;
break;
}
}
// Store the drawables we found, if we found them. Otherwise, set them both
// to null so that we'll just use refreshDrawableState.
if (aboveAnchorStateIndex != -1 && belowAnchorStateIndex != -1) {
mAboveAnchorBackgroundDrawable = stateList.getStateDrawable(aboveAnchorStateIndex);
mBelowAnchorBackgroundDrawable = stateList.getStateDrawable(belowAnchorStateIndex);
} else {
mBelowAnchorBackgroundDrawable = null;
mAboveAnchorBackgroundDrawable = null;
}
}
| public void | setClipToScreenEnabled(boolean enabled)Clip this popup window to the screen, but not to the containing window.
mClipToScreen = enabled;
setClippingEnabled(!enabled);
| public void | setClippingEnabled(boolean enabled)Allows the popup window to extend beyond the bounds of the screen. By default the
window is clipped to the screen boundaries. Setting this to false will allow windows to be
accurately positioned.
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.
mClippingEnabled = enabled;
| public void | setContentView(android.view.View contentView)Change the popup's content. The content is represented by an instance
of {@link android.view.View}.
This method has no effect if called when the popup is showing.
if (isShowing()) {
return;
}
mContentView = contentView;
if (mContext == null && mContentView != null) {
mContext = mContentView.getContext();
}
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);
}
| public void | setElevation(float elevation)Specifies the elevation for this popup window.
mElevation = elevation;
| public void | setFocusable(boolean focusable)Changes the focusability of the popup window. When focusable, the
window will grab the focus from the current focused widget if the popup
contains a focusable {@link android.view.View}. By default a popup
window is not focusable.
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.
mFocusable = focusable;
| public void | setHeight(int height)Change the popup's height MeasureSpec
If the popup is showing, calling this method will take effect only
the next time the popup is shown.
mHeight = height;
| public void | setIgnoreCheekPress()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.
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.
mIgnoreCheekPress = true;
| public void | setInputMethodMode(int mode)Control how the popup operates with an input method: one of
{@link #INPUT_METHOD_FROM_FOCUSABLE}, {@link #INPUT_METHOD_NEEDED},
or {@link #INPUT_METHOD_NOT_NEEDED}.
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.
mInputMethodMode = mode;
| private void | setLayoutDirectionFromAnchor()
if (mAnchor != null) {
View anchor = mAnchor.get();
if (anchor != null && mPopupViewInitialLayoutDirectionInherited) {
mPopupView.setLayoutDirection(anchor.getLayoutDirection());
}
}
| public void | setLayoutInScreenEnabled(boolean enabled)Allows the popup window to force the flag
{@link WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN}, overriding default behavior.
This will cause the popup to be positioned in absolute screen coordinates.
mLayoutInScreen = enabled;
| public void | setLayoutInsetDecor(boolean enabled)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
the screen, such as the status bar.
This will often be combined with {@link #setLayoutInScreenEnabled(boolean)}.
mLayoutInsetDecor = enabled;
| public void | setOnDismissListener(android.widget.PopupWindow$OnDismissListener onDismissListener)Sets the listener to be called when the window is dismissed.
mOnDismissListener = onDismissListener;
| public void | setOutsideTouchable(boolean touchable)Controls whether the pop-up will be informed of touch events outside
of its window. This only makes sense for pop-ups that are touchable
but not focusable, which means touches outside of the window will
be delivered to the window behind. The default is false.
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.
mOutsideTouchable = touchable;
| public void | setSoftInputMode(int mode)Sets the operating mode for the soft input area.
mSoftInputMode = mode;
| public void | setSplitTouchEnabled(boolean enabled)Allows the popup window to split touches across other windows that also
support split touch. When this flag is false, the first pointer
that goes down determines the window to which all subsequent touches
go until all pointers go up. When this flag is true, each pointer
(not necessarily the first) that goes down determines the window
to which all subsequent touches of that pointer will go until that
pointer goes up thereby enabling touches with multiple pointers
to be split across multiple windows.
mSplitTouchEnabled = enabled ? 1 : 0;
| public void | setTouchInterceptor(android.view.View.OnTouchListener l)Set a callback for all touch events being dispatched to the popup
window.
mTouchInterceptor = l;
| public void | setTouchModal(boolean touchModal)Set whether this window is touch modal or if outside touches will be sent to
other windows behind it.
mNotTouchModal = !touchModal;
| public void | setTouchable(boolean touchable)Changes the touchability of the popup window. When touchable, the
window will receive touch events, otherwise touch events will go to the
window below it. By default the window is touchable.
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.
mTouchable = touchable;
| public void | setWidth(int width)Change the popup's width MeasureSpec
If the popup is showing, calling this method will take effect only
the next time the popup is shown.
mWidth = width;
| public void | setWindowLayoutMode(int widthSpec, int heightSpec)Change the width and height measure specs that are given to the
window manager by the popup. By default these are 0, meaning that
the current width or height is requested as an explicit size from
the window manager. You can supply
{@link ViewGroup.LayoutParams#WRAP_CONTENT} or
{@link ViewGroup.LayoutParams#MATCH_PARENT} to have that measure
spec supplied instead, replacing the absolute width and height that
has been set in the popup.
If the popup is showing, calling this method will take effect only
the next time the popup is shown.
mWidthMode = widthSpec;
mHeightMode = heightSpec;
| public void | setWindowLayoutType(int layoutType)Set the layout type for this window. Should be one of the TYPE constants defined in
{@link WindowManager.LayoutParams}.
mWindowLayoutType = layoutType;
| public void | showAsDropDown(android.view.View anchor)Display the content view in a popup window anchored to the bottom-left
corner of the anchor view. If there is not enough room on screen to show
the popup in its entirety, this method tries to find a parent scroll
view to scroll. If no parent scroll view can be scrolled, the bottom-left
corner of the popup is pinned at the top left corner of the anchor view.
showAsDropDown(anchor, 0, 0);
| public void | showAsDropDown(android.view.View anchor, int xoff, int yoff)Display the content view in a popup window anchored to the bottom-left
corner of the anchor view offset by the specified x and y coordinates.
If there is not enough room on screen to show
the popup in its entirety, this method tries to find a parent scroll
view to scroll. If no parent scroll view can be scrolled, the bottom-left
corner of the popup is pinned at the top left corner of the anchor view.
If the view later scrolls to move anchor to a different
location, the popup will be moved correspondingly.
showAsDropDown(anchor, xoff, yoff, DEFAULT_ANCHORED_GRAVITY);
| public void | showAsDropDown(android.view.View anchor, int xoff, int yoff, int gravity)Display the content view in a popup window anchored to the bottom-left
corner of the anchor view offset by the specified x and y coordinates.
If there is not enough room on screen to show
the popup in its entirety, this method tries to find a parent scroll
view to scroll. If no parent scroll view can be scrolled, the bottom-left
corner of the popup is pinned at the top left corner of the anchor view.
If the view later scrolls to move anchor to a different
location, the popup will be moved correspondingly.
if (isShowing() || mContentView == null) {
return;
}
registerForScrollChanged(anchor, xoff, yoff, gravity);
mIsShowing = true;
mIsDropdown = true;
WindowManager.LayoutParams p = createPopupLayout(anchor.getWindowToken());
preparePopup(p);
updateAboveAnchor(findDropDownPosition(anchor, p, xoff, yoff, gravity));
if (mHeightMode < 0) p.height = mLastHeight = mHeightMode;
if (mWidthMode < 0) p.width = mLastWidth = mWidthMode;
p.windowAnimations = computeAnimationResource();
invokePopup(p);
| public void | showAtLocation(android.view.View parent, int gravity, int x, int y)
Display the content view in a popup window at the specified location. If the popup window
cannot fit on screen, it will be clipped. See {@link android.view.WindowManager.LayoutParams}
for more information on how gravity and the x and y parameters are related. Specifying
a gravity of {@link android.view.Gravity#NO_GRAVITY} is similar to specifying
Gravity.LEFT | Gravity.TOP .
showAtLocation(parent.getWindowToken(), gravity, x, y);
| public void | showAtLocation(android.os.IBinder token, int gravity, int x, int y)Display the content view in a popup window at the specified location.
if (isShowing() || mContentView == null) {
return;
}
unregisterForScrollChanged();
mIsShowing = true;
mIsDropdown = false;
WindowManager.LayoutParams p = createPopupLayout(token);
p.windowAnimations = computeAnimationResource();
preparePopup(p);
if (gravity == Gravity.NO_GRAVITY) {
gravity = Gravity.TOP | Gravity.START;
}
p.gravity = gravity;
p.x = x;
p.y = y;
if (mHeightMode < 0) p.height = mLastHeight = mHeightMode;
if (mWidthMode < 0) p.width = mLastWidth = mWidthMode;
invokePopup(p);
| private void | unregisterForScrollChanged()
WeakReference<View> anchorRef = mAnchor;
View anchor = null;
if (anchorRef != null) {
anchor = anchorRef.get();
}
if (anchor != null) {
ViewTreeObserver vto = anchor.getViewTreeObserver();
vto.removeOnScrollChangedListener(mOnScrollChangedListener);
}
mAnchor = null;
| public void | update()Updates the state of the popup window, if it is currently being displayed,
from the currently set state. This includes:
{@link #setClippingEnabled(boolean)}, {@link #setFocusable(boolean)},
{@link #setIgnoreCheekPress()}, {@link #setInputMethodMode(int)},
{@link #setTouchable(boolean)}, and {@link #setAnimationStyle(int)}.
if (!isShowing() || mContentView == null) {
return;
}
WindowManager.LayoutParams p = (WindowManager.LayoutParams)
mPopupView.getLayoutParams();
boolean update = false;
final int newAnim = computeAnimationResource();
if (newAnim != p.windowAnimations) {
p.windowAnimations = newAnim;
update = true;
}
final int newFlags = computeFlags(p.flags);
if (newFlags != p.flags) {
p.flags = newFlags;
update = true;
}
if (update) {
setLayoutDirectionFromAnchor();
mWindowManager.updateViewLayout(mPopupView, p);
}
| public void | update(int width, int height)Updates the dimension of the popup window. Calling this function
also updates the window with the current popup state as described
for {@link #update()}.
WindowManager.LayoutParams p = (WindowManager.LayoutParams)
mPopupView.getLayoutParams();
update(p.x, p.y, width, height, false);
| public void | update(int x, int y, int width, int height)Updates the position and the dimension of the popup window. Width and
height can be set to -1 to update location only. Calling this function
also updates the window with the current popup state as
described for {@link #update()}.
update(x, y, width, height, false);
| public void | update(int x, int y, int width, int height, boolean force)Updates the position and the dimension of the popup window. Width and
height can be set to -1 to update location only. Calling this function
also updates the window with the current popup state as
described for {@link #update()}.
if (width != -1) {
mLastWidth = width;
setWidth(width);
}
if (height != -1) {
mLastHeight = height;
setHeight(height);
}
if (!isShowing() || mContentView == null) {
return;
}
WindowManager.LayoutParams p = (WindowManager.LayoutParams) mPopupView.getLayoutParams();
boolean update = force;
final int finalWidth = mWidthMode < 0 ? mWidthMode : mLastWidth;
if (width != -1 && p.width != finalWidth) {
p.width = mLastWidth = finalWidth;
update = true;
}
final int finalHeight = mHeightMode < 0 ? mHeightMode : mLastHeight;
if (height != -1 && p.height != finalHeight) {
p.height = mLastHeight = finalHeight;
update = true;
}
if (p.x != x) {
p.x = x;
update = true;
}
if (p.y != y) {
p.y = y;
update = true;
}
final int newAnim = computeAnimationResource();
if (newAnim != p.windowAnimations) {
p.windowAnimations = newAnim;
update = true;
}
final int newFlags = computeFlags(p.flags);
if (newFlags != p.flags) {
p.flags = newFlags;
update = true;
}
if (update) {
setLayoutDirectionFromAnchor();
mWindowManager.updateViewLayout(mPopupView, p);
}
| public void | update(android.view.View anchor, int width, int height)Updates the position and the dimension of the popup window. Calling this
function also updates the window with the current popup state as described
for {@link #update()}.
update(anchor, false, 0, 0, true, width, height, mAnchoredGravity);
| public void | update(android.view.View anchor, int xoff, int yoff, int width, int height)Updates the position and the dimension of the popup window. Width and
height can be set to -1 to update location only. Calling this function
also updates the window with the current popup state as
described for {@link #update()}.
If the view later scrolls to move anchor to a different
location, the popup will be moved correspondingly.
update(anchor, true, xoff, yoff, true, width, height, mAnchoredGravity);
| private void | update(android.view.View anchor, boolean updateLocation, int xoff, int yoff, boolean updateDimension, int width, int height, int gravity)
if (!isShowing() || mContentView == null) {
return;
}
WeakReference<View> oldAnchor = mAnchor;
final boolean needsUpdate = updateLocation
&& (mAnchorXoff != xoff || mAnchorYoff != yoff);
if (oldAnchor == null || oldAnchor.get() != anchor || (needsUpdate && !mIsDropdown)) {
registerForScrollChanged(anchor, xoff, yoff, gravity);
} else if (needsUpdate) {
// No need to register again if this is a DropDown, showAsDropDown already did.
mAnchorXoff = xoff;
mAnchorYoff = yoff;
mAnchoredGravity = gravity;
}
WindowManager.LayoutParams p = (WindowManager.LayoutParams) mPopupView.getLayoutParams();
if (updateDimension) {
if (width == -1) {
width = mPopupWidth;
} else {
mPopupWidth = width;
}
if (height == -1) {
height = mPopupHeight;
} else {
mPopupHeight = height;
}
}
int x = p.x;
int y = p.y;
if (updateLocation) {
updateAboveAnchor(findDropDownPosition(anchor, p, xoff, yoff, gravity));
} else {
updateAboveAnchor(findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff,
mAnchoredGravity));
}
update(p.x, p.y, width, height, x != p.x || y != p.y);
| private void | updateAboveAnchor(boolean aboveAnchor)
if (aboveAnchor != mAboveAnchor) {
mAboveAnchor = aboveAnchor;
if (mBackground != null) {
// If the background drawable provided was a StateListDrawable with above-anchor
// and below-anchor states, use those. Otherwise rely on refreshDrawableState to
// do the job.
if (mAboveAnchorBackgroundDrawable != null) {
if (mAboveAnchor) {
mPopupView.setBackground(mAboveAnchorBackgroundDrawable);
} else {
mPopupView.setBackground(mBelowAnchorBackgroundDrawable);
}
} else {
mPopupView.refreshDrawableState();
}
}
}
|
|