FileDocCategorySizeDatePackage
PopupWindow.javaAPI DocAndroid 1.5 API45738Wed May 06 22:41:56 BST 2009android.widget

PopupWindow

public class PopupWindow extends Object

A popup window that can be used to display an arbitrary view. The popup windows is a floating container that appears on top of the current activity.

see
android.widget.AutoCompleteTextView
see
android.widget.Spinner

Fields Summary
public static final int
INPUT_METHOD_FROM_FOCUSABLE
Mode 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_NEEDED
Mode 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_NEEDED
Mode 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 final android.content.Context
mContext
private final 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 boolean
mTouchable
private boolean
mOutsideTouchable
private boolean
mClippingEnabled
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 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 boolean
mAboveAnchor
private OnDismissListener
mOnDismissListener
private boolean
mIgnoreCheekPress
private int
mAnimationStyle
private static final int[]
ABOVE_ANCHOR_STATE_SET
private WeakReference
mAnchor
private android.view.ViewTreeObserver.OnScrollChangedListener
mOnScrollChangedListener
private int
mAnchorXoff
private int
mAnchorYoff
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 defStyle)

Create a new empty, non focusable popup window of dimension (0,0).

The popup does provide a background.

        mContext = context;
        mWindowManager = (WindowManager)context.getSystemService(
                Context.WINDOW_SERVICE);

        TypedArray a =
            context.obtainStyledAttributes(
                attrs, com.android.internal.R.styleable.PopupWindow, defStyle, 0);

        mBackground = a.getDrawable(R.styleable.PopupWindow_popupBackground);

        // 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 background = (StateListDrawable) mBackground;

            // Find the above-anchor view - this one's easy, it should be labeled as such.
            int aboveAnchorStateIndex = background.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 = background.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 = background.getStateDrawable(aboveAnchorStateIndex);
                mBelowAnchorBackgroundDrawable = background.getStateDrawable(belowAnchorStateIndex);
            } else {
                mBelowAnchorBackgroundDrawable = null;
                mAboveAnchorBackgroundDrawable = null;
            }
        }
        
        a.recycle();
    
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.

param
contentView the popup's content

        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.

param
width the popup's width
param
height the popup's height

        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.

param
contentView the popup's content
param
width the popup's width
param
height the popup's height

        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.

param
contentView the popup's content
param
width the popup's width
param
height the popup's height
param
focusable true if the popup can be focused, false otherwise

        mContext = contentView.getContext();
        mWindowManager = (WindowManager)mContext.getSystemService(
                Context.WINDOW_SERVICE);
        setContentView(contentView);
        setWidth(width);
        setHeight(height);
        setFocusable(focusable);
    
Methods Summary
private intcomputeAnimationResource()

        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 intcomputeFlags(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);
        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;
        }
        return curFlags;
    
private WindowManager.LayoutParamscreatePopupLayout(android.os.IBinder token)

Generate the layout parameters for the popup window.

param
token the window token used to bind the popup's window
return
the layout parameters to pass to the window manager

        // 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.LEFT | 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 = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
        p.token = token;
        p.setTitle("PopupWindow:" + Integer.toHexString(hashCode()));

        return p;
    
public voiddismiss()

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.

see
#showAsDropDown(android.view.View)

        if (isShowing() && mPopupView != null) {
            unregisterForScrollChanged();

            mWindowManager.removeView(mPopupView);
            if (mPopupView != mContentView && mPopupView instanceof ViewGroup) {
                ((ViewGroup) mPopupView).removeView(mContentView);
            }
            mPopupView = null;
            mIsShowing = false;

            if (mOnDismissListener != null) {
                mOnDismissListener.onDismiss();
            }
        }
    
private booleanfindDropDownPosition(android.view.View anchor, WindowManager.LayoutParams p, int xoff, int yoff)

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.

param
anchor the view on which the popup window must be anchored
param
p the layout parameters used to display the drop down
return
true if the popup is translated upwards to fit on screen


        anchor.getLocationInWindow(mDrawingLocation);
        p.x = mDrawingLocation[0] + xoff;
        p.y = mDrawingLocation[1] + anchor.getMeasuredHeight() + yoff;
        
        boolean onTop = false;

        p.gravity = Gravity.LEFT | Gravity.TOP;
        
        anchor.getLocationOnScreen(mScreenLocation);
        final Rect displayFrame = new Rect();
        anchor.getWindowVisibleDisplayFrame(displayFrame);
        
        final View root = anchor.getRootView();
        if (p.y + 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
            int scrollX = anchor.getScrollX();
            int scrollY = anchor.getScrollY();
            Rect r = new Rect(scrollX, scrollY,  scrollX + mPopupWidth,
                    scrollY + mPopupHeight + anchor.getMeasuredHeight());
            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] + anchor.getMeasuredHeight() + yoff;
            
            // determine whether there is more space above or below the anchor
            anchor.getLocationOnScreen(mScreenLocation);
            
            onTop = (displayFrame.bottom - mScreenLocation[1] - anchor.getMeasuredHeight() - 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] + anchor.getMeasuredHeight() + yoff;
            }
        }

        p.gravity |= Gravity.DISPLAY_CLIP_VERTICAL;
        
        return onTop;
    
public intgetAnimationStyle()

Return the animation style to use the popup appears and disappears

return
the animation style to use the popup appears and disappears

        return mAnimationStyle;
    
public android.graphics.drawable.DrawablegetBackground()

Return the drawable used as the popup window's background.

return
the background drawable or null

        return mBackground;
    
public android.view.ViewgetContentView()

Return the view used as the content of the popup window.

return
a {@link android.view.View} representing the popup's content
see
#setContentView(android.view.View)

        return mContentView;
    
public intgetHeight()

Return this popup's height MeasureSpec

return
the height MeasureSpec of the popup
see
#setHeight(int)

        return mHeight;
    
public intgetInputMethodMode()
Return the current value in {@link #setInputMethodMode(int)}.

see
#setInputMethodMode(int)

        return mInputMethodMode;
        
    
public intgetMaxAvailableHeight(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.

param
anchor The view on which the popup window must be anchored.
return
The maximum available height for the popup to be completely shown.

        return getMaxAvailableHeight(anchor, 0);
    
public intgetMaxAvailableHeight(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.

param
anchor The view on which the popup window must be anchored.
param
yOffset y offset from the view's bottom edge
return
The maximum available height for the popup to be completely shown.

        final Rect displayFrame = new Rect();
        anchor.getWindowVisibleDisplayFrame(displayFrame);

        final int[] anchorPos = mDrawingLocation;
        anchor.getLocationOnScreen(anchorPos);
        
        final int distanceToBottom = displayFrame.bottom -
                (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 intgetWidth()

Return this popup's width MeasureSpec

return
the width MeasureSpec of the popup
see
#setWidth(int)

        return mWidth;
    
private voidinvokePopup(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.

param
p the layout parameters of the popup's content view

        mWindowManager.addView(mPopupView, p);
    
public booleanisAboveAnchor()
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
True if this popup is showing above the anchor view, false otherwise.

        return mAboveAnchor;
    
public booleanisClippingEnabled()

Indicates whether clipping of the popup window is enabled.

return
true if the clipping is enabled, false otherwise
see
#setClippingEnabled(boolean)

        return mClippingEnabled;
    
public booleanisFocusable()

Indicate whether the popup window can grab the focus.

return
true if the popup is focusable, false otherwise
see
#setFocusable(boolean)

        return mFocusable;
    
public booleanisOutsideTouchable()

Indicates whether the popup window will be informed of touch events outside of its window.

return
true if the popup is outside touchable, false otherwise
see
#setOutsideTouchable(boolean)

        return mOutsideTouchable;
    
public booleanisShowing()

Indicate whether this popup window is showing on screen.

return
true if the popup is showing, false otherwise

        return mIsShowing;
    
public booleanisTouchable()

Indicates whether the popup window receives touch events.

return
true if the popup is touchable, false otherwise
see
#setTouchable(boolean)

        return mTouchable;
    
private voidpreparePopup(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 mnodified to take into account the background's padding.

param
p the layout parameters of the popup's content view

        if (mBackground != null) {
            final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams();
            int height = ViewGroup.LayoutParams.FILL_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.FILL_PARENT, height
            );
            popupViewContainer.setBackgroundDrawable(mBackground);
            popupViewContainer.addView(mContentView, listParams);

            mPopupView = popupViewContainer;
        } else {
            mPopupView = mContentView;
        }
        mPopupWidth = p.width;
        mPopupHeight = p.height;
    
private voidregisterForScrollChanged(android.view.View anchor, int xoff, int yoff)

        unregisterForScrollChanged();

        mAnchor = new WeakReference<View>(anchor);
        ViewTreeObserver vto = anchor.getViewTreeObserver();
        if (vto != null) {
            vto.addOnScrollChangedListener(mOnScrollChangedListener);
        }

        mAnchorXoff = xoff;
        mAnchorYoff = yoff;
    
public voidsetAnimationStyle(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.

param
animationStyle animation style to use when the popup appears and disappears. Set to -1 for the default animation, 0 for no animation, or a resource identifier for an explicit animation.
see
#update()

        mAnimationStyle = animationStyle;
    
public voidsetBackgroundDrawable(android.graphics.drawable.Drawable background)

Change the background drawable for this popup window. The background can be set to null.

param
background the popup's background

        mBackground = background;
    
public voidsetClippingEnabled(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.

param
enabled false if the window should be allowed to extend outside of the screen
see
#isShowing()
see
#isClippingEnabled()
see
#update()

        mClippingEnabled = enabled;
    
public voidsetContentView(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. To apply it while a popup is showing, call

param
contentView the new content for the popup
see
#getContentView()
see
#isShowing()

        if (isShowing()) {
            return;
        }

        mContentView = contentView;
    
public voidsetFocusable(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.

param
focusable true if the popup should grab focus, false otherwise.
see
#isFocusable()
see
#isShowing()
see
#update()

        mFocusable = focusable;
    
public voidsetHeight(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.

param
height the height MeasureSpec of the popup
see
#getHeight()
see
#isShowing()

        mHeight = height;
    
public voidsetIgnoreCheekPress()
Set the flag on popup to ignore cheek press eventt; 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.

see
#update()

        mIgnoreCheekPress = true;
    
public voidsetInputMethodMode(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.

see
#getInputMethodMode()
see
#update()

        mInputMethodMode = mode;
    
public voidsetOnDismissListener(android.widget.PopupWindow$OnDismissListener onDismissListener)
Sets the listener to be called when the window is dismissed.

param
onDismissListener The listener.

        mOnDismissListener = onDismissListener;
    
public voidsetOutsideTouchable(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.

param
touchable true if the popup should receive outside touch events, false otherwise
see
#isOutsideTouchable()
see
#isShowing()
see
#update()

        mOutsideTouchable = touchable;
    
public voidsetTouchInterceptor(android.view.View.OnTouchListener l)
Set a callback for all touch events being dispatched to the popup window.

        mTouchInterceptor = l;
    
public voidsetTouchable(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.

param
touchable true if the popup should receive touch events, false otherwise
see
#isTouchable()
see
#isShowing()
see
#update()

        mTouchable = touchable;
    
public voidsetWidth(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.

param
width the width MeasureSpec of the popup
see
#getWidth()
see
#isShowing()

        mWidth = width;
    
public voidsetWindowLayoutMode(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#FILL_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.

param
widthSpec an explicit width measure spec mode, either {@link ViewGroup.LayoutParams#WRAP_CONTENT}, {@link ViewGroup.LayoutParams#FILL_PARENT}, or 0 to use the absolute width.
param
heightSpec an explicit height measure spec mode, either {@link ViewGroup.LayoutParams#WRAP_CONTENT}, {@link ViewGroup.LayoutParams#FILL_PARENT}, or 0 to use the absolute height.

        mWidthMode = widthSpec;
        mHeightMode = heightSpec;
    
public voidshowAsDropDown(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.

param
anchor the view on which to pin the popup window
see
#dismiss()

        showAsDropDown(anchor, 0, 0);
    
public voidshowAsDropDown(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.

param
anchor the view on which to pin the popup window
see
#dismiss()

        if (isShowing() || mContentView == null) {
            return;
        }

        registerForScrollChanged(anchor, xoff, yoff);

        mIsShowing = true;
        mIsDropdown = true;

        WindowManager.LayoutParams p = createPopupLayout(anchor.getWindowToken());
        preparePopup(p);
        mAboveAnchor = findDropDownPosition(anchor, p, xoff, yoff);

        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.setBackgroundDrawable(mAboveAnchorBackgroundDrawable);
                } else {
                    mPopupView.setBackgroundDrawable(mBelowAnchorBackgroundDrawable);
                }
            } else {
                mPopupView.refreshDrawableState();
            }
        }

        if (mHeightMode < 0) p.height = mLastHeight = mHeightMode;
        if (mWidthMode < 0) p.width = mLastWidth = mWidthMode;

        p.windowAnimations = computeAnimationResource();

        invokePopup(p);
    
public voidshowAtLocation(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.

param
parent a parent view to get the {@link android.view.View#getWindowToken()} token from
param
gravity the gravity which controls the placement of the popup window
param
x the popup's x location offset
param
y the popup's y location offset

        if (isShowing() || mContentView == null) {
            return;
        }

        unregisterForScrollChanged();

        mIsShowing = true;
        mIsDropdown = false;

        WindowManager.LayoutParams p = createPopupLayout(parent.getWindowToken());
        p.windowAnimations = computeAnimationResource();
       
        preparePopup(p);
        if (gravity == Gravity.NO_GRAVITY) {
            gravity = Gravity.TOP | Gravity.LEFT;
        }
        p.gravity = gravity;
        p.x = x;
        p.y = y;
        invokePopup(p);
    
private voidunregisterForScrollChanged()

        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 voidupdate()
Updates the state of the popup window, if it is currently being displayed, from the currently set state. This include: {@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) {
            mWindowManager.updateViewLayout(mPopupView, p);
        }
    
public voidupdate(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()}.

param
x the new x location
param
y the new y location
param
width the new width, can be -1 to ignore
param
height the new height, can be -1 to ignore

        update(x, y, width, height, false);
    
public voidupdate(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()}.

param
x the new x location
param
y the new y location
param
width the new width, can be -1 to ignore
param
height the new height, can be -1 to ignore
param
force reposition the window even if the specified position already seems to correspond to the LayoutParams

        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) {
            mWindowManager.updateViewLayout(mPopupView, p);
        }
    
public voidupdate(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()}.

param
anchor the popup's anchor view
param
width the new width, can be -1 to ignore
param
height the new height, can be -1 to ignore

        update(anchor, false, 0, 0, true, width, height);
    
public voidupdate(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.

param
anchor the popup's anchor view
param
xoff x offset from the view's left edge
param
yoff y offset from the view's bottom edge
param
width the new width, can be -1 to ignore
param
height the new height, can be -1 to ignore

        update(anchor, true, xoff, yoff, true, width, height);
    
private voidupdate(android.view.View anchor, boolean updateLocation, int xoff, int yoff, boolean updateDimension, int width, int height)


        if (!isShowing() || mContentView == null) {
            return;
        }

        WeakReference<View> oldAnchor = mAnchor;
        if (oldAnchor == null || oldAnchor.get() != anchor ||
                (updateLocation && (mAnchorXoff != xoff || mAnchorYoff != yoff))) {
            registerForScrollChanged(anchor, xoff, yoff);
        }

        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;
            }
        }

        if (updateLocation) {
            mAboveAnchor = findDropDownPosition(anchor, p, xoff, yoff);
        } else {
            mAboveAnchor = findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff);            
        }

        update(p.x, p.y, width, height);