PopupWindow.java revision c39a6e0c51e182338deb8b63d07933b585134929
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.R;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyEvent;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.MotionEvent;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.WindowManager;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Gravity;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewGroup;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewTreeObserver;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewTreeObserver.OnScrollChangedListener;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View.OnTouchListener;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PixelFormat;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.Drawable;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.StateListDrawable;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.ref.WeakReference;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>A popup window that can be used to display an arbitrary view. The popup
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * windows is a floating container that appears on top of the current
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * activity.</p>
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.widget.AutoCompleteTextView
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.widget.Spinner
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class PopupWindow {
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Mode for {@link #setInputMethodMode(int): the requirements for the
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * input method should be based on the focusability of the popup.  That is
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if it is focusable than it needs to work with the input method, else
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * it doesn't.
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int INPUT_METHOD_FROM_FOCUSABLE = 0;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Mode for {@link #setInputMethodMode(int): this popup always needs to
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * work with an input method, regardless of whether it is focusable.  This
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * means that it will always be displayed so that the user can also operate
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the input method while it is shown.
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int INPUT_METHOD_NEEDED = 1;
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Mode for {@link #setInputMethodMode(int): this popup never needs to
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * work with an input method, regardless of whether it is focusable.  This
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * means that it will always be displayed to use as much space on the
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * screen as needed, regardless of whether this covers the input method.
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int INPUT_METHOD_NOT_NEEDED = 2;
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final Context mContext;
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final WindowManager mWindowManager;
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mIsShowing;
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mIsDropdown;
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private View mContentView;
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private View mPopupView;
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mFocusable;
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mInputMethodMode = INPUT_METHOD_FROM_FOCUSABLE;
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mTouchable = true;
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mOutsideTouchable = false;
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mClippingEnabled = true;
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private OnTouchListener mTouchInterceptor;
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mWidthMode;
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mWidth;
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mLastWidth;
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mHeightMode;
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mHeight;
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mLastHeight;
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mPopupWidth;
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mPopupHeight;
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int[] mDrawingLocation = new int[2];
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int[] mScreenLocation = new int[2];
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Rect mTempRect = new Rect();
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mBackground;
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mAboveAnchorBackgroundDrawable;
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mBelowAnchorBackgroundDrawable;
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mAboveAnchor;
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private OnDismissListener mOnDismissListener;
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mIgnoreCheekPress = false;
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mAnimationStyle = -1;
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int[] ABOVE_ANCHOR_STATE_SET = new int[] {
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        com.android.internal.R.attr.state_above_anchor
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private WeakReference<View> mAnchor;
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private OnScrollChangedListener mOnScrollChangedListener =
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        new OnScrollChangedListener() {
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public void onScrollChanged() {
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                View anchor = mAnchor.get();
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (anchor != null && mPopupView != null) {
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    WindowManager.LayoutParams p = (WindowManager.LayoutParams)
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            mPopupView.getLayoutParams();
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mAboveAnchor = findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff);
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    update(p.x, p.y, -1, -1, true);
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        };
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mAnchorXoff, mAnchorYoff;
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window of dimension (0,0).</p>
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does provide a background.</p>
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(Context context) {
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(context, null);
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window of dimension (0,0).</p>
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does provide a background.</p>
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(Context context, AttributeSet attrs) {
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(context, attrs, com.android.internal.R.attr.popupWindowStyle);
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window of dimension (0,0).</p>
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does provide a background.</p>
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(Context context, AttributeSet attrs, int defStyle) {
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext = context;
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWindowManager = (WindowManager)context.getSystemService(
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Context.WINDOW_SERVICE);
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TypedArray a =
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            context.obtainStyledAttributes(
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attrs, com.android.internal.R.styleable.PopupWindow, defStyle, 0);
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBackground = a.getDrawable(R.styleable.PopupWindow_popupBackground);
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If this is a StateListDrawable, try to find and store the drawable to be
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // used when the drop-down is placed above its anchor view, and the one to be
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // used when the drop-down is placed below its anchor view. We extract
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // the drawables ourselves to work around a problem with using refreshDrawableState
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // that it will take into account the padding of all drawables specified in a
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // StateListDrawable, thus adding superfluous padding to drop-down views.
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // We assume a StateListDrawable will have a drawable for ABOVE_ANCHOR_STATE_SET and
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // at least one other drawable, intended for the 'below-anchor state'.
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBackground instanceof StateListDrawable) {
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            StateListDrawable background = (StateListDrawable) mBackground;
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Find the above-anchor view - this one's easy, it should be labeled as such.
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int aboveAnchorStateIndex = background.getStateDrawableIndex(ABOVE_ANCHOR_STATE_SET);
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Now, for the below-anchor view, look for any other drawable specified in the
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // StateListDrawable which is not for the above-anchor state and use that.
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int count = background.getStateCount();
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int belowAnchorStateIndex = -1;
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = 0; i < count; i++) {
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (i != aboveAnchorStateIndex) {
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    belowAnchorStateIndex = i;
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Store the drawables we found, if we found them. Otherwise, set them both
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // to null so that we'll just use refreshDrawableState.
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (aboveAnchorStateIndex != -1 && belowAnchorStateIndex != -1) {
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mAboveAnchorBackgroundDrawable = background.getStateDrawable(aboveAnchorStateIndex);
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mBelowAnchorBackgroundDrawable = background.getStateDrawable(belowAnchorStateIndex);
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mBelowAnchorBackgroundDrawable = null;
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mAboveAnchorBackgroundDrawable = null;
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        a.recycle();
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window of dimension (0,0).</p>
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow() {
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(null, 0, 0);
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new non focusable popup window which can display the
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <tt>contentView</tt>. The dimension of the window are (0,0).</p>
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param contentView the popup's content
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(View contentView) {
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(contentView, 0, 0);
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window. The dimension of the
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window must be passed to this constructor.</p>
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width the popup's width
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height the popup's height
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(int width, int height) {
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(null, width, height);
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new non focusable popup window which can display the
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <tt>contentView</tt>. The dimension of the window must be passed to
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this constructor.</p>
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param contentView the popup's content
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width the popup's width
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height the popup's height
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(View contentView, int width, int height) {
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(contentView, width, height, false);
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new popup window which can display the <tt>contentView</tt>.
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The dimension of the window must be passed to this constructor.</p>
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param contentView the popup's content
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width the popup's width
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height the popup's height
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param focusable true if the popup can be focused, false otherwise
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(View contentView, int width, int height,
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean focusable) {
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext = contentView.getContext();
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWindowManager = (WindowManager)mContext.getSystemService(
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Context.WINDOW_SERVICE);
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setContentView(contentView);
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setWidth(width);
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setHeight(height);
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setFocusable(focusable);
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Return the drawable used as the popup window's background.</p>
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the background drawable or null
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Drawable getBackground() {
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mBackground;
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Change the background drawable for this popup window. The background
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * can be set to null.</p>
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param background the popup's background
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setBackgroundDrawable(Drawable background) {
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBackground = background;
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Return the animation style to use the popup appears and disappears</p>
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the animation style to use the popup appears and disappears
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getAnimationStyle() {
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mAnimationStyle;
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set the flag on popup to ignore cheek press eventt; by default this flag
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is set to false
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * which means the pop wont ignore cheek press dispatch events.
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setIgnoreCheekPress() {
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIgnoreCheekPress = true;
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Change the animation style resource for this popup.</p>
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param animationStyle animation style to use when the popup appears
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *      and disappears.  Set to -1 for the default animation, 0 for no
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *      animation, or a resource identifier for an explicit animation.
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setAnimationStyle(int animationStyle) {
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAnimationStyle = animationStyle;
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Return the view used as the content of the popup window.</p>
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a {@link android.view.View} representing the popup's content
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setContentView(android.view.View)
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View getContentView() {
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mContentView;
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Change the popup's content. The content is represented by an instance
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of {@link android.view.View}.</p>
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>This method has no effect if called when the popup is showing.  To
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * apply it while a popup is showing, call </p>
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param contentView the new content for the popup
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getContentView()
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isShowing()
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setContentView(View contentView) {
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isShowing()) {
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContentView = contentView;
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set a callback for all touch events being dispatched to the popup
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window.
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setTouchInterceptor(OnTouchListener l) {
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTouchInterceptor = l;
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicate whether the popup window can grab the focus.</p>
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is focusable, false otherwise
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setFocusable(boolean)
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isFocusable() {
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mFocusable;
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Changes the focusability of the popup window. When focusable, the
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window will grab the focus from the current focused widget if the popup
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * contains a focusable {@link android.view.View}.  By default a popup
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window is not focusable.</p>
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param focusable true if the popup should grab focus, false otherwise.
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isFocusable()
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isShowing()
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setFocusable(boolean focusable) {
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFocusable = focusable;
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the current value in {@link #setInputMethodMode(int)}.
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setInputMethodMode(int)
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getInputMethodMode() {
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mInputMethodMode;
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Control how the popup operates with an input method: one of
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #INPUT_METHOD_FROM_FOCUSABLE}, {@link #INPUT_METHOD_NEEDED},
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or {@link #INPUT_METHOD_NOT_NEEDED}.
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getInputMethodMode()
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setInputMethodMode(int mode) {
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputMethodMode = mode;
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicates whether the popup window receives touch events.</p>
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is touchable, false otherwise
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setTouchable(boolean)
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isTouchable() {
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mTouchable;
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Changes the touchability of the popup window. When touchable, the
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window will receive touch events, otherwise touch events will go to the
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window below it. By default the window is touchable.</p>
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param touchable true if the popup should receive touch events, false otherwise
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isTouchable()
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isShowing()
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setTouchable(boolean touchable) {
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTouchable = touchable;
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicates whether the popup window will be informed of touch events
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * outside of its window.</p>
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is outside touchable, false otherwise
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setOutsideTouchable(boolean)
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isOutsideTouchable() {
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mOutsideTouchable;
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Controls whether the pop-up will be informed of touch events outside
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of its window.  This only makes sense for pop-ups that are touchable
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * but not focusable, which means touches outside of the window will
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be delivered to the window behind.  The default is false.</p>
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param touchable true if the popup should receive outside
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * touch events, false otherwise
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isOutsideTouchable()
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isShowing()
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setOutsideTouchable(boolean touchable) {
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOutsideTouchable = touchable;
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicates whether clipping of the popup window is enabled.</p>
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the clipping is enabled, false otherwise
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setClippingEnabled(boolean)
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isClippingEnabled() {
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mClippingEnabled;
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Allows the popup window to extend beyond the bounds of the screen. By default the
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window is clipped to the screen boundaries. Setting this to false will allow windows to be
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * accurately positioned.</p>
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param enabled false if the window should be allowed to extend outside of the screen
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isShowing()
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isClippingEnabled()
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setClippingEnabled(boolean enabled) {
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mClippingEnabled = enabled;
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Change the width and height measure specs that are given to the
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window manager by the popup.  By default these are 0, meaning that
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the current width or height is requested as an explicit size from
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the window manager.  You can supply
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ViewGroup.LayoutParams#WRAP_CONTENT} or
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ViewGroup.LayoutParams#FILL_PARENT} to have that measure
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * spec supplied instead, replacing the absolute width and height that
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * has been set in the popup.</p>
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown.</p>
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param widthSpec an explicit width measure spec mode, either
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ViewGroup.LayoutParams#WRAP_CONTENT},
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ViewGroup.LayoutParams#FILL_PARENT}, or 0 to use the absolute
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * width.
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param heightSpec an explicit height measure spec mode, either
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ViewGroup.LayoutParams#WRAP_CONTENT},
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ViewGroup.LayoutParams#FILL_PARENT}, or 0 to use the absolute
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * height.
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setWindowLayoutMode(int widthSpec, int heightSpec) {
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWidthMode = widthSpec;
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHeightMode = heightSpec;
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Return this popup's height MeasureSpec</p>
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the height MeasureSpec of the popup
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setHeight(int)
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getHeight() {
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mHeight;
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Change the popup's height MeasureSpec</p>
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown.</p>
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height the height MeasureSpec of the popup
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getHeight()
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isShowing()
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setHeight(int height) {
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHeight = height;
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Return this popup's width MeasureSpec</p>
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the width MeasureSpec of the popup
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setWidth(int)
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getWidth() {
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mWidth;
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Change the popup's width MeasureSpec</p>
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown.</p>
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width the width MeasureSpec of the popup
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getWidth()
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isShowing()
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setWidth(int width) {
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWidth = width;
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicate whether this popup window is showing on screen.</p>
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is showing, false otherwise
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isShowing() {
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mIsShowing;
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Display the content view in a popup window at the specified location. If the popup window
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * cannot fit on screen, it will be clipped. See {@link android.view.WindowManager.LayoutParams}
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * for more information on how gravity and the x and y parameters are related. Specifying
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a gravity of {@link android.view.Gravity#NO_GRAVITY} is similar to specifying
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <code>Gravity.LEFT | Gravity.TOP</code>.
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </p>
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param parent a parent view to get the {@link android.view.View#getWindowToken()} token from
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param gravity the gravity which controls the placement of the popup window
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x the popup's x location offset
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y the popup's y location offset
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void showAtLocation(View parent, int gravity, int x, int y) {
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isShowing() || mContentView == null) {
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        unregisterForScrollChanged();
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsShowing = true;
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsDropdown = false;
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        WindowManager.LayoutParams p = createPopupLayout(parent.getWindowToken());
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.windowAnimations = computeAnimationResource();
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        preparePopup(p);
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (gravity == Gravity.NO_GRAVITY) {
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            gravity = Gravity.TOP | Gravity.LEFT;
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.gravity = gravity;
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.x = x;
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.y = y;
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        invokePopup(p);
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Display the content view in a popup window anchored to the bottom-left
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * corner of the anchor view. If there is not enough room on screen to show
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the popup in its entirety, this method tries to find a parent scroll
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * view to scroll. If no parent scroll view can be scrolled, the bottom-left
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * corner of the popup is pinned at the top left corner of the anchor view.</p>
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the view on which to pin the popup window
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #dismiss()
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void showAsDropDown(View anchor) {
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        showAsDropDown(anchor, 0, 0);
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Display the content view in a popup window anchored to the bottom-left
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * corner of the anchor view offset by the specified x and y coordinates.
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If there is not enough room on screen to show
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the popup in its entirety, this method tries to find a parent scroll
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * view to scroll. If no parent scroll view can be scrolled, the bottom-left
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * corner of the popup is pinned at the top left corner of the anchor view.</p>
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the view later scrolls to move <code>anchor</code> to a different
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * location, the popup will be moved correspondingly.</p>
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the view on which to pin the popup window
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #dismiss()
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void showAsDropDown(View anchor, int xoff, int yoff) {
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isShowing() || mContentView == null) {
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        registerForScrollChanged(anchor, xoff, yoff);
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsShowing = true;
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsDropdown = true;
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        WindowManager.LayoutParams p = createPopupLayout(anchor.getWindowToken());
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        preparePopup(p);
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAboveAnchor = findDropDownPosition(anchor, p, xoff, yoff);
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBackground != null) {
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If the background drawable provided was a StateListDrawable with above-anchor
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // and below-anchor states, use those. Otherwise rely on refreshDrawableState to
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // do the job.
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mAboveAnchorBackgroundDrawable != null) {
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mAboveAnchor) {
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mPopupView.setBackgroundDrawable(mAboveAnchorBackgroundDrawable);
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mPopupView.setBackgroundDrawable(mBelowAnchorBackgroundDrawable);
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mPopupView.refreshDrawableState();
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mHeightMode < 0) p.height = mLastHeight = mHeightMode;
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mWidthMode < 0) p.width = mLastWidth = mWidthMode;
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.windowAnimations = computeAnimationResource();
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        invokePopup(p);
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Indicates whether the popup is showing above (the y coordinate of the popup's bottom
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is less than the y coordinate of the anchor) or below the anchor view (the y coordinate
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of the popup is greater than y coordinate of the anchor's bottom).
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The value returned
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by this method is meaningful only after {@link #showAsDropDown(android.view.View)}
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or {@link #showAsDropDown(android.view.View, int, int)} was invoked.
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return True if this popup is showing above the anchor view, false otherwise.
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isAboveAnchor() {
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mAboveAnchor;
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Prepare the popup by embedding in into a new ViewGroup if the
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * background drawable is not null. If embedding is required, the layout
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * parameters' height is mnodified to take into account the background's
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * padding.</p>
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param p the layout parameters of the popup's content view
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void preparePopup(WindowManager.LayoutParams p) {
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBackground != null) {
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams();
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int height = ViewGroup.LayoutParams.FILL_PARENT;
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (layoutParams != null &&
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                height = ViewGroup.LayoutParams.WRAP_CONTENT;
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // when a background is available, we embed the content view
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // within another view that owns the background drawable
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            PopupViewContainer popupViewContainer = new PopupViewContainer(mContext);
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            PopupViewContainer.LayoutParams listParams = new PopupViewContainer.LayoutParams(
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ViewGroup.LayoutParams.FILL_PARENT, height
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            );
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            popupViewContainer.setBackgroundDrawable(mBackground);
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            popupViewContainer.addView(mContentView, listParams);
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mPopupView = popupViewContainer;
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mPopupView = mContentView;
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPopupWidth = p.width;
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPopupHeight = p.height;
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Invoke the popup window by adding the content view to the window
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * manager.</p>
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The content view must be non-null when this method is invoked.</p>
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param p the layout parameters of the popup's content view
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void invokePopup(WindowManager.LayoutParams p) {
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWindowManager.addView(mPopupView, p);
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Generate the layout parameters for the popup window.</p>
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param token the window token used to bind the popup's window
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the layout parameters to pass to the window manager
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private WindowManager.LayoutParams createPopupLayout(IBinder token) {
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // generates the layout parameters for the drop down
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // we want a fixed size view located at the bottom left of the anchor
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        WindowManager.LayoutParams p = new WindowManager.LayoutParams();
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // these gravity settings put the view at the top left corner of the
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // screen. The view is then positioned to the appropriate location
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // by setting the x and y offsets to match the anchor's bottom
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // left corner
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.gravity = Gravity.LEFT | Gravity.TOP;
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.width = mLastWidth = mWidth;
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.height = mLastHeight = mHeight;
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBackground != null) {
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.format = mBackground.getOpacity();
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.format = PixelFormat.TRANSLUCENT;
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.flags = computeFlags(p.flags);
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.token = token;
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.setTitle("PopupWindow:" + Integer.toHexString(hashCode()));
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return p;
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int computeFlags(int curFlags) {
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        curFlags &= ~(
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES |
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if(mIgnoreCheekPress) {
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES;
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mFocusable) {
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mInputMethodMode == INPUT_METHOD_NEEDED) {
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (mInputMethodMode == INPUT_METHOD_NOT_NEEDED) {
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mTouchable) {
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
840c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project        if (mOutsideTouchable) {
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mClippingEnabled) {
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return curFlags;
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int computeAnimationResource() {
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mAnimationStyle == -1) {
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mIsDropdown) {
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return mAboveAnchor
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ? com.android.internal.R.style.Animation_DropDownUp
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        : com.android.internal.R.style.Animation_DropDownDown;
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mAnimationStyle;
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Positions the popup window on screen. When the popup window is too
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * tall to fit under the anchor, a parent scroll view is seeked and scrolled
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * up to reclaim space. If scrolling is not possible or not enough, the
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * popup window gets moved on top of the anchor.</p>
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The height must have been set on the layout parameters prior to
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * calling this method.</p>
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the view on which the popup window must be anchored
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param p the layout parameters used to display the drop down
8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is translated upwards to fit on screen
8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean findDropDownPosition(View anchor, WindowManager.LayoutParams p,
8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int xoff, int yoff) {
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        anchor.getLocationInWindow(mDrawingLocation);
8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.x = mDrawingLocation[0] + xoff;
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.y = mDrawingLocation[1] + anchor.getMeasuredHeight() + yoff;
8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean onTop = false;
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.gravity = Gravity.LEFT | Gravity.TOP;
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        anchor.getLocationOnScreen(mScreenLocation);
8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Rect displayFrame = new Rect();
8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        anchor.getWindowVisibleDisplayFrame(displayFrame);
8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View root = anchor.getRootView();
8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p.y + mPopupHeight > displayFrame.bottom || p.x + mPopupWidth - root.getWidth() > 0) {
8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // if the drop down disappears at the bottom of the screen. we try to
8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // scroll a parent scrollview or move the drop down back up on top of
8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // the edit box
8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int scrollX = anchor.getScrollX();
8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int scrollY = anchor.getScrollY();
8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Rect r = new Rect(scrollX, scrollY,  scrollX + mPopupWidth,
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    scrollY + mPopupHeight + anchor.getMeasuredHeight());
8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            anchor.requestRectangleOnScreen(r, true);
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // now we re-evaluate the space available, and decide from that
9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // whether the pop-up will go above or below the anchor.
9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            anchor.getLocationInWindow(mDrawingLocation);
9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.x = mDrawingLocation[0] + xoff;
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.y = mDrawingLocation[1] + anchor.getMeasuredHeight() + yoff;
9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // determine whether there is more space above or below the anchor
9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            anchor.getLocationOnScreen(mScreenLocation);
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onTop = (displayFrame.bottom - mScreenLocation[1] - anchor.getMeasuredHeight() - yoff) <
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    (mScreenLocation[1] - yoff - displayFrame.top);
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (onTop) {
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                p.gravity = Gravity.LEFT | Gravity.BOTTOM;
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                p.y = root.getHeight() - mDrawingLocation[1] + yoff;
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                p.y = mDrawingLocation[1] + anchor.getMeasuredHeight() + yoff;
9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.gravity |= Gravity.DISPLAY_CLIP_VERTICAL;
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return onTop;
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the maximum height that is available for the popup to be
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * completely shown. It is recommended that this height be the maximum for
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the popup's height, otherwise it is possible that the popup will be
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * clipped.
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor The view on which the popup window must be anchored.
9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The maximum available height for the popup to be completely
9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         shown.
9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getMaxAvailableHeight(View anchor) {
9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return getMaxAvailableHeight(anchor, 0);
9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the maximum height that is available for the popup to be
9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * completely shown. It is recommended that this height be the maximum for
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the popup's height, otherwise it is possible that the popup will be
9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * clipped.
9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor The view on which the popup window must be anchored.
9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param yOffset y offset from the view's bottom edge
9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The maximum available height for the popup to be completely
9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         shown.
9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getMaxAvailableHeight(View anchor, int yOffset) {
9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Rect displayFrame = new Rect();
9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        anchor.getWindowVisibleDisplayFrame(displayFrame);
9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int[] anchorPos = mDrawingLocation;
9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        anchor.getLocationOnScreen(anchorPos);
9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int distanceToBottom = displayFrame.bottom -
9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (anchorPos[1] + anchor.getHeight()) - yOffset;
9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset;
9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // anchorPos[1] is distance from anchor to top of screen
9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int returnedHeight = Math.max(distanceToBottom, distanceToTop);
9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBackground != null) {
9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mBackground.getPadding(mTempRect);
9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            returnedHeight -= mTempRect.top + mTempRect.bottom;
9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return returnedHeight;
9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Dispose of the popup window. This method can be invoked only after
9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #showAsDropDown(android.view.View)} has been executed. Failing that, calling
9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this method will have no effect.</p>
9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #showAsDropDown(android.view.View)
9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void dismiss() {
9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isShowing() && mPopupView != null) {
9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            unregisterForScrollChanged();
9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mWindowManager.removeView(mPopupView);
9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mPopupView != mContentView && mPopupView instanceof ViewGroup) {
9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ((ViewGroup) mPopupView).removeView(mContentView);
9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mPopupView = null;
9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIsShowing = false;
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mOnDismissListener != null) {
9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mOnDismissListener.onDismiss();
9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the listener to be called when the window is dismissed.
9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param onDismissListener The listener.
9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setOnDismissListener(OnDismissListener onDismissListener) {
10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOnDismissListener = onDismissListener;
10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Updates the state of the popup window, if it is currently being displayed,
10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * from the currently set state.  This include:
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #setClippingEnabled(boolean)}, {@link #setFocusable(boolean)},
10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #setIgnoreCheekPress()}, {@link #setInputMethodMode(int)},
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #setTouchable(boolean)}, and {@link #setAnimationStyle(int)}.
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update() {
10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!isShowing() || mContentView == null) {
10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        WindowManager.LayoutParams p = (WindowManager.LayoutParams)
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mPopupView.getLayoutParams();
10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean update = false;
10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int newAnim = computeAnimationResource();
10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newAnim != p.windowAnimations) {
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.windowAnimations = newAnim;
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int newFlags = computeFlags(p.flags);
10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newFlags != p.flags) {
10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.flags = newFlags;
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (update) {
10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mWindowManager.updateViewLayout(mPopupView, p);
10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Updates the position and the dimension of the popup window. Width and
10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * height can be set to -1 to update location only.  Calling this function
10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * also updates the window with the current popup state as
10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * described for {@link #update()}.</p>
10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x the new x location
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y the new y location
10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width the new width, can be -1 to ignore
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height the new height, can be -1 to ignore
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update(int x, int y, int width, int height) {
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        update(x, y, width, height, false);
10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Updates the position and the dimension of the popup window. Width and
10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * height can be set to -1 to update location only.  Calling this function
10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * also updates the window with the current popup state as
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * described for {@link #update()}.</p>
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x the new x location
10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y the new y location
10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width the new width, can be -1 to ignore
10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height the new height, can be -1 to ignore
10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param force reposition the window even if the specified position
10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *              already seems to correspond to the LayoutParams
10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide pending API council approval
10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update(int x, int y, int width, int height, boolean force) {
10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (width != -1) {
10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mLastWidth = width;
10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setWidth(width);
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (height != -1) {
10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mLastHeight = height;
10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setHeight(height);
10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!isShowing() || mContentView == null) {
10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        WindowManager.LayoutParams p = (WindowManager.LayoutParams)
10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mPopupView.getLayoutParams();
10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean update = force;
10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int finalWidth = mWidthMode < 0 ? mWidthMode : mLastWidth;
10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (width != -1 && p.width != finalWidth) {
10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.width = mLastWidth = finalWidth;
10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int finalHeight = mHeightMode < 0 ? mHeightMode : mLastHeight;
10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (height != -1 && p.height != finalHeight) {
10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.height = mLastHeight = finalHeight;
10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p.x != x) {
11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.x = x;
11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p.y != y) {
11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.y = y;
11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int newAnim = computeAnimationResource();
11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newAnim != p.windowAnimations) {
11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.windowAnimations = newAnim;
11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int newFlags = computeFlags(p.flags);
11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newFlags != p.flags) {
11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.flags = newFlags;
11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (update) {
11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mWindowManager.updateViewLayout(mPopupView, p);
11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Updates the position and the dimension of the popup window. Width and
11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * height can be set to -1 to update location only.  Calling this function
11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * also updates the window with the current popup state as
11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * described for {@link #update()}.</p>
11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the popup's anchor view
11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width the new width, can be -1 to ignore
11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height the new height, can be -1 to ignore
11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update(View anchor, int width, int height) {
11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        update(anchor, 0, 0, width, height);
11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Updates the position and the dimension of the popup window. Width and
11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * height can be set to -1 to update location only.  Calling this function
11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * also updates the window with the current popup state as
11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * described for {@link #update()}.</p>
11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the view later scrolls to move <code>anchor</code> to a different
11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * location, the popup will be moved correspondingly.</p>
11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the popup's anchor view
11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param xoff x offset from the view's left edge
11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param yoff y offset from the view's bottom edge
11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width the new width, can be -1 to ignore
11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height the new height, can be -1 to ignore
11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update(View anchor, int xoff, int yoff, int width, int height) {
11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!isShowing() || mContentView == null) {
11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        WeakReference<View> oldAnchor = mAnchor;
11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (oldAnchor == null || oldAnchor.get() != anchor ||
11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mAnchorXoff != xoff || mAnchorYoff != yoff) {
11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            registerForScrollChanged(anchor, xoff, yoff);
11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        WindowManager.LayoutParams p = (WindowManager.LayoutParams)
11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mPopupView.getLayoutParams();
11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (width == -1) {
11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            width = mPopupWidth;
11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mPopupWidth = width;
11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (height == -1) {
11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            height = mPopupHeight;
11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mPopupHeight = height;
11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAboveAnchor = findDropDownPosition(anchor, p, xoff, yoff);
11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        update(p.x, p.y, width, height);
11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Listener that is called when this popup window is dismissed.
11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface OnDismissListener {
11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Called when this popup window is dismissed.
11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onDismiss();
11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void unregisterForScrollChanged() {
11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        WeakReference<View> anchorRef = mAnchor;
11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        View anchor = null;
11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (anchorRef != null) {
11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            anchor = anchorRef.get();
11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (anchor != null) {
12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ViewTreeObserver vto = anchor.getViewTreeObserver();
12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            vto.removeOnScrollChangedListener(mOnScrollChangedListener);
12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAnchor = null;
12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void registerForScrollChanged(View anchor, int xoff, int yoff) {
12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        unregisterForScrollChanged();
12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAnchor = new WeakReference<View>(anchor);
12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ViewTreeObserver vto = anchor.getViewTreeObserver();
12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (vto != null) {
12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            vto.addOnScrollChangedListener(mOnScrollChangedListener);
12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAnchorXoff = xoff;
12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAnchorYoff = yoff;
12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class PopupViewContainer extends FrameLayout {
12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public PopupViewContainer(Context context) {
12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(context);
12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        protected int[] onCreateDrawableState(int extraSpace) {
12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mAboveAnchor) {
12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // 1 more needed for the above anchor state
12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                View.mergeDrawableStates(drawableState, ABOVE_ANCHOR_STATE_SET);
12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return drawableState;
12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return super.onCreateDrawableState(extraSpace);
12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean dispatchKeyEvent(KeyEvent event) {
12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dismiss();
12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return super.dispatchKeyEvent(event);
12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean dispatchTouchEvent(MotionEvent ev) {
12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mTouchInterceptor != null && mTouchInterceptor.onTouch(this, ev)) {
12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return super.dispatchTouchEvent(ev);
12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean onTouchEvent(MotionEvent event) {
12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int x = (int) event.getX();
12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int y = (int) event.getY();
12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((event.getAction() == MotionEvent.ACTION_DOWN)
12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    && ((x < 0) || (x >= getWidth()) || (y < 0) || (y >= getHeight()))) {
12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dismiss();
12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dismiss();
12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return super.onTouchEvent(event);
12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1276