PopupWindow.java revision 80ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89
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
19a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport com.android.internal.R;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.Context;
22a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport android.content.res.Resources;
2375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.res.TypedArray;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PixelFormat;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.Drawable;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.StateListDrawable;
2846e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brownimport android.os.Build;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder;
305435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.Transition;
315435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.Transition.EpicenterCallback;
328fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.transition.Transition.TransitionListener;
338fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.transition.Transition.TransitionListenerAdapter;
345435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.TransitionInflater;
355435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.TransitionManager;
365435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.TransitionSet;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet;
38c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.Gravity;
39c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.KeyEvent;
40c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.MotionEvent;
41c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.View;
42a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport android.view.View.OnTouchListener;
43c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.ViewGroup;
448fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.view.ViewParent;
45c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.ViewTreeObserver;
468fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.view.ViewTreeObserver.OnGlobalLayoutListener;
47c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.ViewTreeObserver.OnScrollChangedListener;
48a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport android.view.WindowManager;
49259c2840691a79634ffd8f63291ec21c21819542Alan Viveretteimport android.view.WindowManager.LayoutParams;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
51a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport java.lang.ref.WeakReference;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>A popup window that can be used to display an arbitrary view. The popup
557ed189e457b16c06b0425bd28aeeb1df5c8ff5b8Scott Kennedy * window is a floating container that appears on top of the current
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * activity.</p>
575435a30ae552391f14009c4459731ae149675b18Alan Viverette *
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.widget.AutoCompleteTextView
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.widget.Spinner
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class PopupWindow {
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
63e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     * Mode for {@link #setInputMethodMode(int)}: the requirements for the
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * input method should be based on the focusability of the popup.  That is
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if it is focusable than it needs to work with the input method, else
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * it doesn't.
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int INPUT_METHOD_FROM_FOCUSABLE = 0;
695435a30ae552391f14009c4459731ae149675b18Alan Viverette
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
71e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     * Mode for {@link #setInputMethodMode(int)}: this popup always needs to
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * work with an input method, regardless of whether it is focusable.  This
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * means that it will always be displayed so that the user can also operate
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the input method while it is shown.
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int INPUT_METHOD_NEEDED = 1;
775435a30ae552391f14009c4459731ae149675b18Alan Viverette
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
79e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     * Mode for {@link #setInputMethodMode(int)}: this popup never needs to
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * work with an input method, regardless of whether it is focusable.  This
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * means that it will always be displayed to use as much space on the
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * screen as needed, regardless of whether this covers the input method.
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int INPUT_METHOD_NOT_NEEDED = 2;
8554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell
8654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell    private static final int DEFAULT_ANCHORED_GRAVITY = Gravity.TOP | Gravity.START;
8754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell
885435a30ae552391f14009c4459731ae149675b18Alan Viverette    /**
895435a30ae552391f14009c4459731ae149675b18Alan Viverette     * Default animation style indicating that separate animations should be
905435a30ae552391f14009c4459731ae149675b18Alan Viverette     * used for top/bottom anchoring states.
915435a30ae552391f14009c4459731ae149675b18Alan Viverette     */
925435a30ae552391f14009c4459731ae149675b18Alan Viverette    private static final int ANIMATION_STYLE_DEFAULT = -1;
935435a30ae552391f14009c4459731ae149675b18Alan Viverette
945435a30ae552391f14009c4459731ae149675b18Alan Viverette    private final int[] mDrawingLocation = new int[2];
955435a30ae552391f14009c4459731ae149675b18Alan Viverette    private final int[] mScreenLocation = new int[2];
965435a30ae552391f14009c4459731ae149675b18Alan Viverette    private final Rect mTempRect = new Rect();
975435a30ae552391f14009c4459731ae149675b18Alan Viverette
98448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy    private Context mContext;
99448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy    private WindowManager mWindowManager;
1005435a30ae552391f14009c4459731ae149675b18Alan Viverette
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mIsShowing;
1028fd949e680c15d397084430d4907c16cedfacddaAlan Viverette    private boolean mIsTransitioningToDismiss;
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mIsDropdown;
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1055435a30ae552391f14009c4459731ae149675b18Alan Viverette    /** View that handles event dispatch and content transitions. */
1065435a30ae552391f14009c4459731ae149675b18Alan Viverette    private PopupDecorView mDecorView;
1075435a30ae552391f14009c4459731ae149675b18Alan Viverette
1085435a30ae552391f14009c4459731ae149675b18Alan Viverette    /** The contents of the popup. */
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private View mContentView;
1105435a30ae552391f14009c4459731ae149675b18Alan Viverette
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mFocusable;
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mInputMethodMode = INPUT_METHOD_FROM_FOCUSABLE;
1137eab094722af54717859b7dcce3cc050f059e00bDianne Hackborn    private int mSoftInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED;
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mTouchable = true;
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mOutsideTouchable = false;
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mClippingEnabled = true;
11746e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown    private int mSplitTouchEnabled = -1;
118ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    private boolean mLayoutInScreen;
11956c2d337e02a275397fc9d0460dca90977f199acAdam Powell    private boolean mClipToScreen;
120348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell    private boolean mAllowScrollingAnchorParent = true;
1210bd1d0a15294345bf88b20df28466907f982cec7Adam Powell    private boolean mLayoutInsetDecor = false;
122e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell    private boolean mNotTouchModal;
123393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    private boolean mAttachedInDecor = true;
124393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    private boolean mAttachedInDecorSet = false;
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private OnTouchListener mTouchInterceptor;
127393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mWidthMode;
129259c2840691a79634ffd8f63291ec21c21819542Alan Viverette    private int mWidth = LayoutParams.WRAP_CONTENT;
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mLastWidth;
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mHeightMode;
132259c2840691a79634ffd8f63291ec21c21819542Alan Viverette    private int mHeight = LayoutParams.WRAP_CONTENT;
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mLastHeight;
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mPopupWidth;
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mPopupHeight;
13756c2d337e02a275397fc9d0460dca90977f199acAdam Powell
138ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    private float mElevation;
139ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mBackground;
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mAboveAnchorBackgroundDrawable;
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mBelowAnchorBackgroundDrawable;
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1445435a30ae552391f14009c4459731ae149675b18Alan Viverette    private Transition mEnterTransition;
1455435a30ae552391f14009c4459731ae149675b18Alan Viverette    private Transition mExitTransition;
146560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mAboveAnchor;
148574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    private int mWindowLayoutType = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
1495435a30ae552391f14009c4459731ae149675b18Alan Viverette
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private OnDismissListener mOnDismissListener;
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mIgnoreCheekPress = false;
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1535435a30ae552391f14009c4459731ae149675b18Alan Viverette    private int mAnimationStyle = ANIMATION_STYLE_DEFAULT;
1545435a30ae552391f14009c4459731ae149675b18Alan Viverette
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int[] ABOVE_ANCHOR_STATE_SET = new int[] {
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        com.android.internal.R.attr.state_above_anchor
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private WeakReference<View> mAnchor;
160560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
1615435a30ae552391f14009c4459731ae149675b18Alan Viverette    private final OnScrollChangedListener mOnScrollChangedListener = new OnScrollChangedListener() {
1625435a30ae552391f14009c4459731ae149675b18Alan Viverette        @Override
1635435a30ae552391f14009c4459731ae149675b18Alan Viverette        public void onScrollChanged() {
1645435a30ae552391f14009c4459731ae149675b18Alan Viverette            final View anchor = mAnchor != null ? mAnchor.get() : null;
1655435a30ae552391f14009c4459731ae149675b18Alan Viverette            if (anchor != null && mDecorView != null) {
1665435a30ae552391f14009c4459731ae149675b18Alan Viverette                final WindowManager.LayoutParams p = (WindowManager.LayoutParams)
1675435a30ae552391f14009c4459731ae149675b18Alan Viverette                        mDecorView.getLayoutParams();
1685435a30ae552391f14009c4459731ae149675b18Alan Viverette
1695435a30ae552391f14009c4459731ae149675b18Alan Viverette                updateAboveAnchor(findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff,
1705435a30ae552391f14009c4459731ae149675b18Alan Viverette                        mAnchoredGravity));
1715435a30ae552391f14009c4459731ae149675b18Alan Viverette                update(p.x, p.y, -1, -1, true);
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1735435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
1745435a30ae552391f14009c4459731ae149675b18Alan Viverette    };
175560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
1765435a30ae552391f14009c4459731ae149675b18Alan Viverette    private int mAnchorXoff;
1775435a30ae552391f14009c4459731ae149675b18Alan Viverette    private int mAnchorYoff;
1785435a30ae552391f14009c4459731ae149675b18Alan Viverette    private int mAnchoredGravity;
179560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette    private boolean mOverlapAnchor;
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
181b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio    private boolean mPopupViewInitialLayoutDirectionInherited;
182b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window of dimension (0,0).</p>
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does provide a background.</p>
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(Context context) {
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(context, null);
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window of dimension (0,0).</p>
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does provide a background.</p>
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(Context context, AttributeSet attrs) {
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(context, attrs, com.android.internal.R.attr.popupWindowStyle);
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window of dimension (0,0).</p>
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does provide a background.</p>
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
206617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr) {
207617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        this(context, attrs, defStyleAttr, 0);
208c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
2095435a30ae552391f14009c4459731ae149675b18Alan Viverette
210c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
211c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * <p>Create a new, empty, non focusable popup window of dimension (0,0).</p>
2125435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
213c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * <p>The popup does not provide a background.</p>
214c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
215c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext = context;
21775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
219617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        final TypedArray a = context.obtainStyledAttributes(
220ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                attrs, R.styleable.PopupWindow, defStyleAttr, defStyleRes);
221ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        final Drawable bg = a.getDrawable(R.styleable.PopupWindow_popupBackground);
222ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        mElevation = a.getDimension(R.styleable.PopupWindow_popupElevation, 0);
223560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        mOverlapAnchor = a.getBoolean(R.styleable.PopupWindow_overlapAnchor, false);
224c3808b5dc7d5873d04e8a0a247b179b2757764baAdam Powell
2255435a30ae552391f14009c4459731ae149675b18Alan Viverette        // Preserve default behavior from Gingerbread. If the animation is
2265435a30ae552391f14009c4459731ae149675b18Alan Viverette        // undefined or explicitly specifies the Gingerbread animation style,
2275435a30ae552391f14009c4459731ae149675b18Alan Viverette        // use a sentinel value.
2285435a30ae552391f14009c4459731ae149675b18Alan Viverette        if (a.hasValueOrEmpty(R.styleable.PopupWindow_popupAnimationStyle)) {
2295435a30ae552391f14009c4459731ae149675b18Alan Viverette            final int animStyle = a.getResourceId(R.styleable.PopupWindow_popupAnimationStyle, 0);
2305435a30ae552391f14009c4459731ae149675b18Alan Viverette            if (animStyle == R.style.Animation_PopupWindow) {
2315435a30ae552391f14009c4459731ae149675b18Alan Viverette                mAnimationStyle = ANIMATION_STYLE_DEFAULT;
2325435a30ae552391f14009c4459731ae149675b18Alan Viverette            } else {
2335435a30ae552391f14009c4459731ae149675b18Alan Viverette                mAnimationStyle = animStyle;
2345435a30ae552391f14009c4459731ae149675b18Alan Viverette            }
2355435a30ae552391f14009c4459731ae149675b18Alan Viverette        } else {
2365435a30ae552391f14009c4459731ae149675b18Alan Viverette            mAnimationStyle = ANIMATION_STYLE_DEFAULT;
2375435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
2385435a30ae552391f14009c4459731ae149675b18Alan Viverette
2395435a30ae552391f14009c4459731ae149675b18Alan Viverette        final Transition enterTransition = getTransition(a.getResourceId(
2405435a30ae552391f14009c4459731ae149675b18Alan Viverette                R.styleable.PopupWindow_popupEnterTransition, 0));
2415435a30ae552391f14009c4459731ae149675b18Alan Viverette        final Transition exitTransition;
2425435a30ae552391f14009c4459731ae149675b18Alan Viverette        if (a.hasValueOrEmpty(R.styleable.PopupWindow_popupExitTransition)) {
2435435a30ae552391f14009c4459731ae149675b18Alan Viverette            exitTransition = getTransition(a.getResourceId(
2445435a30ae552391f14009c4459731ae149675b18Alan Viverette                    R.styleable.PopupWindow_popupExitTransition, 0));
2455435a30ae552391f14009c4459731ae149675b18Alan Viverette        } else {
2465435a30ae552391f14009c4459731ae149675b18Alan Viverette            exitTransition = enterTransition == null ? null : enterTransition.clone();
2475435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        a.recycle();
250ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette
2515435a30ae552391f14009c4459731ae149675b18Alan Viverette        setEnterTransition(enterTransition);
2525435a30ae552391f14009c4459731ae149675b18Alan Viverette        setExitTransition(exitTransition);
253ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        setBackgroundDrawable(bg);
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window of dimension (0,0).</p>
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow() {
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(null, 0, 0);
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new non focusable popup window which can display the
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <tt>contentView</tt>. The dimension of the window are (0,0).</p>
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param contentView the popup's content
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(View contentView) {
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(contentView, 0, 0);
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window. The dimension of the
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window must be passed to this constructor.</p>
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width the popup's width
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height the popup's height
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(int width, int height) {
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(null, width, height);
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new non focusable popup window which can display the
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <tt>contentView</tt>. The dimension of the window must be passed to
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this constructor.</p>
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param contentView the popup's content
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width the popup's width
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height the popup's height
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(View contentView, int width, int height) {
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(contentView, width, height, false);
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new popup window which can display the <tt>contentView</tt>.
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The dimension of the window must be passed to this constructor.</p>
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param contentView the popup's content
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width the popup's width
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height the popup's height
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param focusable true if the popup can be focused, false otherwise
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
321448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy    public PopupWindow(View contentView, int width, int height, boolean focusable) {
322448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        if (contentView != null) {
323448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy            mContext = contentView.getContext();
324448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy            mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
325448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        }
326393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setContentView(contentView);
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setWidth(width);
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setHeight(height);
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setFocusable(focusable);
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3335435a30ae552391f14009c4459731ae149675b18Alan Viverette    public void setEnterTransition(Transition enterTransition) {
3345435a30ae552391f14009c4459731ae149675b18Alan Viverette        mEnterTransition = enterTransition;
3355435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
3365435a30ae552391f14009c4459731ae149675b18Alan Viverette
3375435a30ae552391f14009c4459731ae149675b18Alan Viverette    public void setExitTransition(Transition exitTransition) {
3385435a30ae552391f14009c4459731ae149675b18Alan Viverette        mExitTransition = exitTransition;
3395435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
3405435a30ae552391f14009c4459731ae149675b18Alan Viverette
3415435a30ae552391f14009c4459731ae149675b18Alan Viverette    private Transition getTransition(int resId) {
3425435a30ae552391f14009c4459731ae149675b18Alan Viverette        if (resId != 0 && resId != R.transition.no_transition) {
3435435a30ae552391f14009c4459731ae149675b18Alan Viverette            final TransitionInflater inflater = TransitionInflater.from(mContext);
3445435a30ae552391f14009c4459731ae149675b18Alan Viverette            final Transition transition = inflater.inflateTransition(resId);
3455435a30ae552391f14009c4459731ae149675b18Alan Viverette            if (transition != null) {
3465435a30ae552391f14009c4459731ae149675b18Alan Viverette                final boolean isEmpty = transition instanceof TransitionSet
3475435a30ae552391f14009c4459731ae149675b18Alan Viverette                        && ((TransitionSet) transition).getTransitionCount() == 0;
3485435a30ae552391f14009c4459731ae149675b18Alan Viverette                if (!isEmpty) {
3495435a30ae552391f14009c4459731ae149675b18Alan Viverette                    return transition;
3505435a30ae552391f14009c4459731ae149675b18Alan Viverette                }
3515435a30ae552391f14009c4459731ae149675b18Alan Viverette            }
3525435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
3535435a30ae552391f14009c4459731ae149675b18Alan Viverette        return null;
3545435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
3555435a30ae552391f14009c4459731ae149675b18Alan Viverette
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
357ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * Return the drawable used as the popup window's background.
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
359ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @return the background drawable or {@code null} if not set
360ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @see #setBackgroundDrawable(Drawable)
361ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @attr ref android.R.styleable#PopupWindow_popupBackground
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Drawable getBackground() {
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mBackground;
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
368ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * Specifies the background drawable for this popup window. The background
369ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * can be set to {@code null}.
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param background the popup's background
372ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @see #getBackground()
373ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @attr ref android.R.styleable#PopupWindow_popupBackground
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setBackgroundDrawable(Drawable background) {
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBackground = background;
377ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette
378ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // If this is a StateListDrawable, try to find and store the drawable to be
379ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // used when the drop-down is placed above its anchor view, and the one to be
380ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // used when the drop-down is placed below its anchor view. We extract
381ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // the drawables ourselves to work around a problem with using refreshDrawableState
382ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // that it will take into account the padding of all drawables specified in a
383ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // StateListDrawable, thus adding superfluous padding to drop-down views.
384ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        //
385ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // We assume a StateListDrawable will have a drawable for ABOVE_ANCHOR_STATE_SET and
386ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // at least one other drawable, intended for the 'below-anchor state'.
387ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        if (mBackground instanceof StateListDrawable) {
388ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            StateListDrawable stateList = (StateListDrawable) mBackground;
389ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette
390ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            // Find the above-anchor view - this one's easy, it should be labeled as such.
391ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            int aboveAnchorStateIndex = stateList.getStateDrawableIndex(ABOVE_ANCHOR_STATE_SET);
392ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette
393ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            // Now, for the below-anchor view, look for any other drawable specified in the
394ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            // StateListDrawable which is not for the above-anchor state and use that.
395ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            int count = stateList.getStateCount();
396ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            int belowAnchorStateIndex = -1;
397ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            for (int i = 0; i < count; i++) {
398ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                if (i != aboveAnchorStateIndex) {
399ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                    belowAnchorStateIndex = i;
400ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                    break;
401ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                }
402ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            }
403ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette
404ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            // Store the drawables we found, if we found them. Otherwise, set them both
405ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            // to null so that we'll just use refreshDrawableState.
406ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            if (aboveAnchorStateIndex != -1 && belowAnchorStateIndex != -1) {
407ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                mAboveAnchorBackgroundDrawable = stateList.getStateDrawable(aboveAnchorStateIndex);
408ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                mBelowAnchorBackgroundDrawable = stateList.getStateDrawable(belowAnchorStateIndex);
409ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            } else {
410ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                mBelowAnchorBackgroundDrawable = null;
411ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                mAboveAnchorBackgroundDrawable = null;
412ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            }
413ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        }
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
417ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @return the elevation for this popup window in pixels
418ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @see #setElevation(float)
419ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @attr ref android.R.styleable#PopupWindow_popupElevation
420ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     */
421ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    public float getElevation() {
422ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        return mElevation;
423ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    }
424ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
425ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    /**
426ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * Specifies the elevation for this popup window.
427ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     *
428ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @param elevation the popup's elevation in pixels
429ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @see #getElevation()
430ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @attr ref android.R.styleable#PopupWindow_popupElevation
431ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     */
432ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    public void setElevation(float elevation) {
433ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        mElevation = elevation;
434ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    }
435ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
436ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    /**
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Return the animation style to use the popup appears and disappears</p>
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the animation style to use the popup appears and disappears
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getAnimationStyle() {
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mAnimationStyle;
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
444393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
44654ec76d81ac38284caa6d00ad5f2d2207206b9ceShuhrat Dehkanov     * Set the flag on popup to ignore cheek press events; by default this flag
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is set to false
44854ec76d81ac38284caa6d00ad5f2d2207206b9ceShuhrat Dehkanov     * which means the popup will not ignore cheek press dispatch events.
4495435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
453393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setIgnoreCheekPress() {
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIgnoreCheekPress = true;
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4595435a30ae552391f14009c4459731ae149675b18Alan Viverette
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Change the animation style resource for this popup.</p>
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param animationStyle animation style to use when the popup appears
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *      and disappears.  Set to -1 for the default animation, 0 for no
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *      animation, or a resource identifier for an explicit animation.
4715435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setAnimationStyle(int animationStyle) {
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAnimationStyle = animationStyle;
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4775435a30ae552391f14009c4459731ae149675b18Alan Viverette
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Return the view used as the content of the popup window.</p>
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a {@link android.view.View} representing the popup's content
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setContentView(android.view.View)
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View getContentView() {
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mContentView;
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Change the popup's content. The content is represented by an instance
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of {@link android.view.View}.</p>
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
49381f08086b44a117097960195d2c9072e29644962Gilles Debunne     * <p>This method has no effect if called when the popup is showing.</p>
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param contentView the new content for the popup
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getContentView()
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isShowing()
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setContentView(View contentView) {
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isShowing()) {
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContentView = contentView;
506448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy
5070c0b768e1514280812321854db6dfba723c3d169Romain Guy        if (mContext == null && mContentView != null) {
508448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy            mContext = mContentView.getContext();
509448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        }
510448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy
5110c0b768e1514280812321854db6dfba723c3d169Romain Guy        if (mWindowManager == null && mContentView != null) {
512448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy            mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
513448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        }
514393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
515393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        // Setting the default for attachedInDecor based on SDK version here
516393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        // instead of in the constructor since we might not have the context
517393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        // object in the constructor. We only want to set default here if the
518393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        // app hasn't already set the attachedInDecor.
519393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        if (mContext != null && !mAttachedInDecorSet) {
520393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale            // Attach popup window in decor frame of parent window by default for
521393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale            // {@link Build.VERSION_CODES.LOLLIPOP_MR1} or greater. Keep current
522393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale            // behavior of not attaching to decor frame for older SDKs.
523393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale            setAttachedInDecor(mContext.getApplicationInfo().targetSdkVersion
524393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale                    >= Build.VERSION_CODES.LOLLIPOP_MR1);
525393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        }
526393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set a callback for all touch events being dispatched to the popup
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window.
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setTouchInterceptor(OnTouchListener l) {
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTouchInterceptor = l;
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
536393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicate whether the popup window can grab the focus.</p>
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is focusable, false otherwise
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setFocusable(boolean)
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isFocusable() {
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mFocusable;
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Changes the focusability of the popup window. When focusable, the
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window will grab the focus from the current focused widget if the popup
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * contains a focusable {@link android.view.View}.  By default a popup
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window is not focusable.</p>
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param focusable true if the popup should grab focus, false otherwise.
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isFocusable()
5615435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #isShowing()
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setFocusable(boolean focusable) {
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFocusable = focusable;
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the current value in {@link #setInputMethodMode(int)}.
5705435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setInputMethodMode(int)
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getInputMethodMode() {
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mInputMethodMode;
5755435a30ae552391f14009c4459731ae149675b18Alan Viverette
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5775435a30ae552391f14009c4459731ae149675b18Alan Viverette
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Control how the popup operates with an input method: one of
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #INPUT_METHOD_FROM_FOCUSABLE}, {@link #INPUT_METHOD_NEEDED},
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or {@link #INPUT_METHOD_NOT_NEEDED}.
5825435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
5865435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getInputMethodMode()
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setInputMethodMode(int mode) {
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputMethodMode = mode;
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
593374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy
594374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy    /**
595374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * Sets the operating mode for the soft input area.
596374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     *
597374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * @param mode The desired mode, see
598374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     *        {@link android.view.WindowManager.LayoutParams#softInputMode}
599374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     *        for the full list
600374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     *
601374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * @see android.view.WindowManager.LayoutParams#softInputMode
602374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * @see #getSoftInputMode()
603374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     */
604374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy    public void setSoftInputMode(int mode) {
605374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy        mSoftInputMode = mode;
606374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy    }
607374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy
608374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy    /**
609374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * Returns the current value in {@link #setSoftInputMode(int)}.
610374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     *
611374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * @see #setSoftInputMode(int)
612374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * @see android.view.WindowManager.LayoutParams#softInputMode
613374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     */
614374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy    public int getSoftInputMode() {
615374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy        return mSoftInputMode;
616374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy    }
6175435a30ae552391f14009c4459731ae149675b18Alan Viverette
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicates whether the popup window receives touch events.</p>
6205435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is touchable, false otherwise
6225435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setTouchable(boolean)
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isTouchable() {
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mTouchable;
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Changes the touchability of the popup window. When touchable, the
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window will receive touch events, otherwise touch events will go to the
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window below it. By default the window is touchable.</p>
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param touchable true if the popup should receive touch events, false otherwise
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isTouchable()
6415435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #isShowing()
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setTouchable(boolean touchable) {
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTouchable = touchable;
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicates whether the popup window will be informed of touch events
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * outside of its window.</p>
6515435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is outside touchable, false otherwise
6535435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setOutsideTouchable(boolean)
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isOutsideTouchable() {
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mOutsideTouchable;
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Controls whether the pop-up will be informed of touch events outside
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of its window.  This only makes sense for pop-ups that are touchable
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * but not focusable, which means touches outside of the window will
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be delivered to the window behind.  The default is false.</p>
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param touchable true if the popup should receive outside
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * touch events, false otherwise
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isOutsideTouchable()
6745435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #isShowing()
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setOutsideTouchable(boolean touchable) {
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOutsideTouchable = touchable;
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicates whether clipping of the popup window is enabled.</p>
6835435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the clipping is enabled, false otherwise
6855435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setClippingEnabled(boolean)
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isClippingEnabled() {
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mClippingEnabled;
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Allows the popup window to extend beyond the bounds of the screen. By default the
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window is clipped to the screen boundaries. Setting this to false will allow windows to be
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * accurately positioned.</p>
6965435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param enabled false if the window should be allowed to extend outside of the screen
7025435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #isShowing()
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isClippingEnabled()
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setClippingEnabled(boolean enabled) {
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mClippingEnabled = enabled;
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
71156c2d337e02a275397fc9d0460dca90977f199acAdam Powell     * Clip this popup window to the screen, but not to the containing window.
71256c2d337e02a275397fc9d0460dca90977f199acAdam Powell     *
71356c2d337e02a275397fc9d0460dca90977f199acAdam Powell     * @param enabled True to clip to the screen.
71456c2d337e02a275397fc9d0460dca90977f199acAdam Powell     * @hide
71556c2d337e02a275397fc9d0460dca90977f199acAdam Powell     */
71656c2d337e02a275397fc9d0460dca90977f199acAdam Powell    public void setClipToScreenEnabled(boolean enabled) {
71756c2d337e02a275397fc9d0460dca90977f199acAdam Powell        mClipToScreen = enabled;
71856c2d337e02a275397fc9d0460dca90977f199acAdam Powell        setClippingEnabled(!enabled);
71956c2d337e02a275397fc9d0460dca90977f199acAdam Powell    }
720348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell
721348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell    /**
722348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     * Allow PopupWindow to scroll the anchor's parent to provide more room
723348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     * for the popup. Enabled by default.
724348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     *
725348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     * @param enabled True to scroll the anchor's parent when more room is desired by the popup.
726348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     */
727348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell    void setAllowScrollingAnchorParent(boolean enabled) {
728348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell        mAllowScrollingAnchorParent = enabled;
729348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell    }
7305435a30ae552391f14009c4459731ae149675b18Alan Viverette
73156c2d337e02a275397fc9d0460dca90977f199acAdam Powell    /**
73201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * <p>Indicates whether the popup window supports splitting touches.</p>
7335435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
73401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * @return true if the touch splitting is enabled, false otherwise
7355435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
73601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * @see #setSplitTouchEnabled(boolean)
73701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     */
73801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    public boolean isSplitTouchEnabled() {
73946e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown        if (mSplitTouchEnabled < 0 && mContext != null) {
74046e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown            return mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB;
74146e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown        }
74246e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown        return mSplitTouchEnabled == 1;
74301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
74401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
74501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    /**
74601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * <p>Allows the popup window to split touches across other windows that also
74746e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown     * support split touch.  When this flag is false, the first pointer
74801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * that goes down determines the window to which all subsequent touches
74946e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown     * go until all pointers go up.  When this flag is true, each pointer
75001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * (not necessarily the first) that goes down determines the window
75101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * to which all subsequent touches of that pointer will go until that
75201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * pointer goes up thereby enabling touches with multiple pointers
75301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * to be split across multiple windows.</p>
75401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     *
75501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * @param enabled true if the split touches should be enabled, false otherwise
75601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * @see #isSplitTouchEnabled()
75701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     */
75801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    public void setSplitTouchEnabled(boolean enabled) {
75946e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown        mSplitTouchEnabled = enabled ? 1 : 0;
76001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
76101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
76201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    /**
763ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * <p>Indicates whether the popup window will be forced into using absolute screen coordinates
764ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * for positioning.</p>
765ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     *
766ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * @return true if the window will always be positioned in screen coordinates.
767ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * @hide
768ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     */
769ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    public boolean isLayoutInScreenEnabled() {
770ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell        return mLayoutInScreen;
771ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    }
772ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell
773ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    /**
774ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * <p>Allows the popup window to force the flag
775ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * {@link WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN}, overriding default behavior.
776ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * This will cause the popup to be positioned in absolute screen coordinates.</p>
777ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     *
778ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * @param enabled true if the popup should always be positioned in screen coordinates
779ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * @hide
780ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     */
781ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    public void setLayoutInScreenEnabled(boolean enabled) {
782ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell        mLayoutInScreen = enabled;
783ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    }
784ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell
785ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    /**
786393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * <p>Indicates whether the popup window will be attached in the decor frame of its parent
787393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * window.
788393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
789393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * @return true if the window will be attached to the decor frame of its parent window.
790393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
791393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * @see #setAttachedInDecor(boolean)
792393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR
793393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     */
794393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    public boolean isAttachedInDecor() {
795393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        return mAttachedInDecor;
796393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    }
797393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
798393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    /**
799393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * <p>This will attach the popup window to the decor frame of the parent window to avoid
800393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * overlaping with screen decorations like the navigation bar. Overrides the default behavior of
801393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * the flag {@link WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR}.
802393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
803393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * <p>By default the flag is set on SDK version {@link Build.VERSION_CODES#LOLLIPOP_MR1} or
804393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * greater and cleared on lesser SDK versions.
805393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
806393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * @param enabled true if the popup should be attached to the decor frame of its parent window.
807393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
808393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR
809393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     */
810393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    public void setAttachedInDecor(boolean enabled) {
811393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        mAttachedInDecor = enabled;
812393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        mAttachedInDecorSet = true;
813393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    }
814393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
815393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    /**
8160bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * Allows the popup window to force the flag
8170bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * {@link WindowManager.LayoutParams#FLAG_LAYOUT_INSET_DECOR}, overriding default behavior.
8180bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * This will cause the popup to inset its content to account for system windows overlaying
8190bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * the screen, such as the status bar.
8200bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     *
8210bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * <p>This will often be combined with {@link #setLayoutInScreenEnabled(boolean)}.
8220bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     *
8230bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * @param enabled true if the popup's views should inset content to account for system windows,
8240bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     *                the way that decor views behave for full-screen windows.
8250bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * @hide
8260bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     */
8270bd1d0a15294345bf88b20df28466907f982cec7Adam Powell    public void setLayoutInsetDecor(boolean enabled) {
8280bd1d0a15294345bf88b20df28466907f982cec7Adam Powell        mLayoutInsetDecor = enabled;
8290bd1d0a15294345bf88b20df28466907f982cec7Adam Powell    }
8300bd1d0a15294345bf88b20df28466907f982cec7Adam Powell
8310bd1d0a15294345bf88b20df28466907f982cec7Adam Powell    /**
83280ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette     * Set the layout type for this window.
83380ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette     * <p>
83480ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette     * See {@link WindowManager.LayoutParams#type} for possible values.
835574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell     *
836574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell     * @param layoutType Layout type for this window.
83736344a90c226c90243e4e02bfb13589e120431ddChris Banes     *
83836344a90c226c90243e4e02bfb13589e120431ddChris Banes     * @see WindowManager.LayoutParams#type
839574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell     */
840574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    public void setWindowLayoutType(int layoutType) {
841574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell        mWindowLayoutType = layoutType;
842574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    }
843574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell
844574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    /**
84536344a90c226c90243e4e02bfb13589e120431ddChris Banes     * Returns the layout type for this window.
84636344a90c226c90243e4e02bfb13589e120431ddChris Banes     *
84736344a90c226c90243e4e02bfb13589e120431ddChris Banes     * @see #setWindowLayoutType(int)
848574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell     */
849574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    public int getWindowLayoutType() {
850574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell        return mWindowLayoutType;
851574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    }
852574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell
853574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    /**
854e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell     * Set whether this window is touch modal or if outside touches will be sent to
855e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell     * other windows behind it.
856e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell     * @hide
857e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell     */
858e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell    public void setTouchModal(boolean touchModal) {
859e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell        mNotTouchModal = !touchModal;
860e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell    }
861e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell
862e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell    /**
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Change the width and height measure specs that are given to the
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window manager by the popup.  By default these are 0, meaning that
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the current width or height is requested as an explicit size from
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the window manager.  You can supply
8675435a30ae552391f14009c4459731ae149675b18Alan Viverette     * {@link ViewGroup.LayoutParams#WRAP_CONTENT} or
868980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy     * {@link ViewGroup.LayoutParams#MATCH_PARENT} to have that measure
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * spec supplied instead, replacing the absolute width and height that
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * has been set in the popup.</p>
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown.</p>
8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param widthSpec an explicit width measure spec mode, either
8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ViewGroup.LayoutParams#WRAP_CONTENT},
877980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy     * {@link ViewGroup.LayoutParams#MATCH_PARENT}, or 0 to use the absolute
8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * width.
8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param heightSpec an explicit height measure spec mode, either
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ViewGroup.LayoutParams#WRAP_CONTENT},
881980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy     * {@link ViewGroup.LayoutParams#MATCH_PARENT}, or 0 to use the absolute
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * height.
883259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *
884259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @deprecated Use {@link #setWidth(int)} and {@link #setHeight(int)}.
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
886259c2840691a79634ffd8f63291ec21c21819542Alan Viverette    @Deprecated
8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setWindowLayoutMode(int widthSpec, int heightSpec) {
8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWidthMode = widthSpec;
8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHeightMode = heightSpec;
8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8915435a30ae552391f14009c4459731ae149675b18Alan Viverette
8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
893259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Returns the popup's height MeasureSpec.
8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the height MeasureSpec of the popup
8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setHeight(int)
8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getHeight() {
8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mHeight;
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
903259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Sets the popup's height MeasureSpec.
904259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
905259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * If the popup is showing, calling this method will take effect the next
906259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * time the popup is shown.
9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height the height MeasureSpec of the popup
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getHeight()
9105435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #isShowing()
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setHeight(int height) {
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHeight = height;
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
917259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Returns the popup's width MeasureSpec.
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the width MeasureSpec of the popup
9205435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #setWidth(int)
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getWidth() {
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mWidth;
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
927259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Sets the popup's width MeasureSpec.
928259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
929259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * If the popup is showing, calling this method will take effect the next
930259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * time the popup is shown.
9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width the width MeasureSpec of the popup
9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getWidth()
9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isShowing()
9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setWidth(int width) {
9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWidth = width;
9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
94175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * Sets whether the popup window should overlap its anchor view when
94275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * displayed as a drop-down.
94375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * <p>
94475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * If the popup is showing, calling this method will take effect only
94575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * the next time the popup is shown.
94675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     *
94775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * @param overlapAnchor Whether the popup should overlap its anchor.
94875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     *
94975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * @see #getOverlapAnchor()
95075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * @see #isShowing()
95175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     */
95275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    public void setOverlapAnchor(boolean overlapAnchor) {
95375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        mOverlapAnchor = overlapAnchor;
95475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    }
95575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette
95675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    /**
95775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * Returns whether the popup window should overlap its anchor view when
95875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * displayed as a drop-down.
95975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     *
96075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * @return Whether the popup should overlap its anchor.
96175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     *
96275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * @see #setOverlapAnchor(boolean)
96375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     */
96475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    public boolean getOverlapAnchor() {
96575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        return mOverlapAnchor;
96675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    }
96775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette
96875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    /**
9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicate whether this popup window is showing on screen.</p>
9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is showing, false otherwise
9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isShowing() {
9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mIsShowing;
9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Display the content view in a popup window at the specified location. If the popup window
9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * cannot fit on screen, it will be clipped. See {@link android.view.WindowManager.LayoutParams}
9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * for more information on how gravity and the x and y parameters are related. Specifying
9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a gravity of {@link android.view.Gravity#NO_GRAVITY} is similar to specifying
9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <code>Gravity.LEFT | Gravity.TOP</code>.
9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </p>
9855435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param parent a parent view to get the {@link android.view.View#getWindowToken()} token from
9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param gravity the gravity which controls the placement of the popup window
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x the popup's x location offset
9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y the popup's y location offset
9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void showAtLocation(View parent, int gravity, int x, int y) {
9928ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell        showAtLocation(parent.getWindowToken(), gravity, x, y);
9938ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell    }
9948ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell
9958ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell    /**
9968ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * Display the content view in a popup window at the specified location.
9978ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     *
9988ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * @param token Window token to use for creating the new window
9998ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * @param gravity the gravity which controls the placement of the popup window
10008ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * @param x the popup's x location offset
10018ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * @param y the popup's y location offset
10028ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     *
10038ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * @hide Internal use only. Applications should use
10048ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     *       {@link #showAtLocation(View, int, int, int)} instead.
10058ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     */
10068ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell    public void showAtLocation(IBinder token, int gravity, int x, int y) {
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isShowing() || mContentView == null) {
10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1011e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        TransitionManager.endTransitions(mDecorView);
1012e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        unregisterForScrollChanged();
10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsShowing = true;
10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsDropdown = false;
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1018e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        final WindowManager.LayoutParams p = createPopupLayoutParams(token);
10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        preparePopup(p);
1020e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
1021e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        // Only override the default if some gravity was specified.
1022e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        if (gravity != Gravity.NO_GRAVITY) {
1023e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            p.gravity = gravity;
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1025e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.x = x;
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.y = y;
1028e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        invokePopup(p);
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
103375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * Display the content view in a popup window anchored to the bottom-left
10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * corner of the anchor view. If there is not enough room on screen to show
10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the popup in its entirety, this method tries to find a parent scroll
103675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * view to scroll. If no parent scroll view can be scrolled, the
103775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * bottom-left corner of the popup is pinned at the top left corner of the
103875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * anchor view.
10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the view on which to pin the popup window
10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #dismiss()
10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void showAsDropDown(View anchor) {
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        showAsDropDown(anchor, 0, 0);
10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
104975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * Display the content view in a popup window anchored to the bottom-left
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * corner of the anchor view offset by the specified x and y coordinates.
105175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * If there is not enough room on screen to show the popup in its entirety,
105275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * this method tries to find a parent scroll view to scroll. If no parent
105375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * scroll view can be scrolled, the bottom-left corner of the popup is
105475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * pinned at the top left corner of the anchor view.
105575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * <p>
105675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * If the view later scrolls to move <code>anchor</code> to a different
105775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * location, the popup will be moved correspondingly.
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the view on which to pin the popup window
106054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param xoff A horizontal offset from the anchor in pixels
106154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param yoff A vertical offset from the anchor in pixels
10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #dismiss()
10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void showAsDropDown(View anchor, int xoff, int yoff) {
106654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell        showAsDropDown(anchor, xoff, yoff, DEFAULT_ANCHORED_GRAVITY);
106754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell    }
106854c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell
106954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell    /**
107075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * Displays the content view in a popup window anchored to the corner of
107175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * another view. The window is positioned according to the specified
107275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * gravity and offset by the specified x and y coordinates.
107375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * <p>
107475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * If there is not enough room on screen to show the popup in its entirety,
107575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * this method tries to find a parent scroll view to scroll. If no parent
107675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * view can be scrolled, the specified vertical gravity will be ignored and
107775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * the popup will anchor itself such that it is visible.
107875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * <p>
107975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * If the view later scrolls to move <code>anchor</code> to a different
108075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * location, the popup will be moved correspondingly.
108154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     *
108254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param anchor the view on which to pin the popup window
108354c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param xoff A horizontal offset from the anchor in pixels
108454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param yoff A vertical offset from the anchor in pixels
108554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param gravity Alignment of the popup relative to the anchor
108654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     *
108754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @see #dismiss()
108854c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     */
108954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell    public void showAsDropDown(View anchor, int xoff, int yoff, int gravity) {
10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isShowing() || mContentView == null) {
10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1094e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        TransitionManager.endTransitions(mDecorView);
1095e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
109654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell        registerForScrollChanged(anchor, xoff, yoff, gravity);
10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsShowing = true;
10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsDropdown = true;
11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1101e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        final WindowManager.LayoutParams p = createPopupLayoutParams(anchor.getWindowToken());
11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        preparePopup(p);
11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1104e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        final boolean aboveAnchor = findDropDownPosition(anchor, p, xoff, yoff, gravity);
1105e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        updateAboveAnchor(aboveAnchor);
11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        invokePopup(p);
11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11103e141685003939a9addce21ba2492ea3a8aebee6Romain Guy    private void updateAboveAnchor(boolean aboveAnchor) {
11113e141685003939a9addce21ba2492ea3a8aebee6Romain Guy        if (aboveAnchor != mAboveAnchor) {
11123e141685003939a9addce21ba2492ea3a8aebee6Romain Guy            mAboveAnchor = aboveAnchor;
11133e141685003939a9addce21ba2492ea3a8aebee6Romain Guy
11143e141685003939a9addce21ba2492ea3a8aebee6Romain Guy            if (mBackground != null) {
11153e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                // If the background drawable provided was a StateListDrawable with above-anchor
11163e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                // and below-anchor states, use those. Otherwise rely on refreshDrawableState to
11173e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                // do the job.
11183e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                if (mAboveAnchorBackgroundDrawable != null) {
11193e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                    if (mAboveAnchor) {
11205435a30ae552391f14009c4459731ae149675b18Alan Viverette                        mDecorView.setBackground(mAboveAnchorBackgroundDrawable);
11213e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                    } else {
11225435a30ae552391f14009c4459731ae149675b18Alan Viverette                        mDecorView.setBackground(mBelowAnchorBackgroundDrawable);
11233e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                    }
11243e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                } else {
11255435a30ae552391f14009c4459731ae149675b18Alan Viverette                    mDecorView.refreshDrawableState();
11263e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                }
11273e141685003939a9addce21ba2492ea3a8aebee6Romain Guy            }
11283e141685003939a9addce21ba2492ea3a8aebee6Romain Guy        }
11293e141685003939a9addce21ba2492ea3a8aebee6Romain Guy    }
11303e141685003939a9addce21ba2492ea3a8aebee6Romain Guy
11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Indicates whether the popup is showing above (the y coordinate of the popup's bottom
11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is less than the y coordinate of the anchor) or below the anchor view (the y coordinate
11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of the popup is greater than y coordinate of the anchor's bottom).
11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The value returned
11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by this method is meaningful only after {@link #showAsDropDown(android.view.View)}
11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or {@link #showAsDropDown(android.view.View, int, int)} was invoked.
11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return True if this popup is showing above the anchor view, false otherwise.
11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isAboveAnchor() {
11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mAboveAnchor;
11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1147e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette     * Prepare the popup by embedding it into a new ViewGroup if the background
1148e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette     * drawable is not null. If embedding is required, the layout parameters'
1149e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette     * height is modified to take into account the background's padding.
11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param p the layout parameters of the popup's content view
11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void preparePopup(WindowManager.LayoutParams p) {
1154448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        if (mContentView == null || mContext == null || mWindowManager == null) {
1155448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy            throw new IllegalStateException("You must specify a valid content view by "
1156448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy                    + "calling setContentView() before attempting to show the popup.");
1157448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        }
1158448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy
11598fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // The old decor view may be transitioning out. Make sure it finishes
11608fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // and cleans up before we try to create another one.
11618fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        if (mDecorView != null) {
11628fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            mDecorView.cancelTransitions();
11638fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
11648fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
11655435a30ae552391f14009c4459731ae149675b18Alan Viverette        // When a background is available, we embed the content view within
11665435a30ae552391f14009c4459731ae149675b18Alan Viverette        // another view that owns the background drawable.
11678fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        final View backgroundView;
11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBackground != null) {
11698fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            backgroundView = createBackgroundView(mContentView);
11708fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            backgroundView.setBackground(mBackground);
11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
11728fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            backgroundView = mContentView;
11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1174ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
11758fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        mDecorView = createDecorView(backgroundView);
11765435a30ae552391f14009c4459731ae149675b18Alan Viverette
11775435a30ae552391f14009c4459731ae149675b18Alan Viverette        // The background owner should be elevated so that it casts a shadow.
11788fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        backgroundView.setElevation(mElevation);
11795435a30ae552391f14009c4459731ae149675b18Alan Viverette
11805435a30ae552391f14009c4459731ae149675b18Alan Viverette        // We may wrap that in another view, so we'll need to manually specify
11815435a30ae552391f14009c4459731ae149675b18Alan Viverette        // the surface insets.
11828fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        final int surfaceInset = (int) Math.ceil(backgroundView.getZ() * 2);
11835435a30ae552391f14009c4459731ae149675b18Alan Viverette        p.surfaceInsets.set(surfaceInset, surfaceInset, surfaceInset, surfaceInset);
11845435a30ae552391f14009c4459731ae149675b18Alan Viverette        p.hasManualSurfaceInsets = true;
11855435a30ae552391f14009c4459731ae149675b18Alan Viverette
1186b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio        mPopupViewInitialLayoutDirectionInherited =
11875435a30ae552391f14009c4459731ae149675b18Alan Viverette                (mContentView.getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT);
11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPopupWidth = p.width;
11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPopupHeight = p.height;
11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11935435a30ae552391f14009c4459731ae149675b18Alan Viverette     * Wraps a content view in a PopupViewContainer.
11945435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
11955435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @param contentView the content view to wrap
11965435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @return a PopupViewContainer that wraps the content view
11975435a30ae552391f14009c4459731ae149675b18Alan Viverette     */
11985435a30ae552391f14009c4459731ae149675b18Alan Viverette    private PopupBackgroundView createBackgroundView(View contentView) {
11995435a30ae552391f14009c4459731ae149675b18Alan Viverette        final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams();
12005435a30ae552391f14009c4459731ae149675b18Alan Viverette        final int height;
12015435a30ae552391f14009c4459731ae149675b18Alan Viverette        if (layoutParams != null && layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
12025435a30ae552391f14009c4459731ae149675b18Alan Viverette            height = ViewGroup.LayoutParams.WRAP_CONTENT;
12035435a30ae552391f14009c4459731ae149675b18Alan Viverette        } else {
12045435a30ae552391f14009c4459731ae149675b18Alan Viverette            height = ViewGroup.LayoutParams.MATCH_PARENT;
12055435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
12065435a30ae552391f14009c4459731ae149675b18Alan Viverette
12075435a30ae552391f14009c4459731ae149675b18Alan Viverette        final PopupBackgroundView backgroundView = new PopupBackgroundView(mContext);
12085435a30ae552391f14009c4459731ae149675b18Alan Viverette        final PopupBackgroundView.LayoutParams listParams = new PopupBackgroundView.LayoutParams(
12095435a30ae552391f14009c4459731ae149675b18Alan Viverette                ViewGroup.LayoutParams.MATCH_PARENT, height);
12105435a30ae552391f14009c4459731ae149675b18Alan Viverette        backgroundView.addView(contentView, listParams);
12115435a30ae552391f14009c4459731ae149675b18Alan Viverette
12125435a30ae552391f14009c4459731ae149675b18Alan Viverette        return backgroundView;
12135435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
12145435a30ae552391f14009c4459731ae149675b18Alan Viverette
12155435a30ae552391f14009c4459731ae149675b18Alan Viverette    /**
12165435a30ae552391f14009c4459731ae149675b18Alan Viverette     * Wraps a content view in a FrameLayout.
12175435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
12185435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @param contentView the content view to wrap
12195435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @return a FrameLayout that wraps the content view
12205435a30ae552391f14009c4459731ae149675b18Alan Viverette     */
12215435a30ae552391f14009c4459731ae149675b18Alan Viverette    private PopupDecorView createDecorView(View contentView) {
12225435a30ae552391f14009c4459731ae149675b18Alan Viverette        final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams();
12235435a30ae552391f14009c4459731ae149675b18Alan Viverette        final int height;
12245435a30ae552391f14009c4459731ae149675b18Alan Viverette        if (layoutParams != null && layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
12255435a30ae552391f14009c4459731ae149675b18Alan Viverette            height = ViewGroup.LayoutParams.WRAP_CONTENT;
12265435a30ae552391f14009c4459731ae149675b18Alan Viverette        } else {
12275435a30ae552391f14009c4459731ae149675b18Alan Viverette            height = ViewGroup.LayoutParams.MATCH_PARENT;
12285435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
12295435a30ae552391f14009c4459731ae149675b18Alan Viverette
12305435a30ae552391f14009c4459731ae149675b18Alan Viverette        final PopupDecorView decorView = new PopupDecorView(mContext);
12315435a30ae552391f14009c4459731ae149675b18Alan Viverette        decorView.addView(contentView, ViewGroup.LayoutParams.MATCH_PARENT, height);
12325435a30ae552391f14009c4459731ae149675b18Alan Viverette        decorView.setClipChildren(false);
12335435a30ae552391f14009c4459731ae149675b18Alan Viverette        decorView.setClipToPadding(false);
12345435a30ae552391f14009c4459731ae149675b18Alan Viverette
12355435a30ae552391f14009c4459731ae149675b18Alan Viverette        return decorView;
12365435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
12375435a30ae552391f14009c4459731ae149675b18Alan Viverette
12385435a30ae552391f14009c4459731ae149675b18Alan Viverette    /**
12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Invoke the popup window by adding the content view to the window
12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * manager.</p>
12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The content view must be non-null when this method is invoked.</p>
12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param p the layout parameters of the popup's content view
12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void invokePopup(WindowManager.LayoutParams p) {
12470c0b768e1514280812321854db6dfba723c3d169Romain Guy        if (mContext != null) {
12480c0b768e1514280812321854db6dfba723c3d169Romain Guy            p.packageName = mContext.getPackageName();
12490c0b768e1514280812321854db6dfba723c3d169Romain Guy        }
12505435a30ae552391f14009c4459731ae149675b18Alan Viverette
12518fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        final PopupDecorView decorView = mDecorView;
12528fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        decorView.setFitsSystemWindows(mLayoutInsetDecor);
12535435a30ae552391f14009c4459731ae149675b18Alan Viverette
12548fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        setLayoutDirectionFromAnchor();
12555435a30ae552391f14009c4459731ae149675b18Alan Viverette
12568fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        mWindowManager.addView(decorView, p);
125795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette
125895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        if (mEnterTransition != null) {
125995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            decorView.requestEnterTransition(mEnterTransition);
126095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        }
12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1263b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio    private void setLayoutDirectionFromAnchor() {
1264b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio        if (mAnchor != null) {
1265b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio            View anchor = mAnchor.get();
1266b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio            if (anchor != null && mPopupViewInitialLayoutDirectionInherited) {
12675435a30ae552391f14009c4459731ae149675b18Alan Viverette                mDecorView.setLayoutDirection(anchor.getLayoutDirection());
1268b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio            }
1269b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio        }
1270b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio    }
1271b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio
12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Generate the layout parameters for the popup window.</p>
12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param token the window token used to bind the popup's window
12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the layout parameters to pass to the window manager
12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1279e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette    private WindowManager.LayoutParams createPopupLayoutParams(IBinder token) {
1280e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        final WindowManager.LayoutParams p = new WindowManager.LayoutParams();
1281e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
1282e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        // These gravity settings put the view at the top left corner of the
1283e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        // screen. The view is then positioned to the appropriate location by
1284e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        // setting the x and y offsets to match the anchor's bottom-left
1285e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        // corner.
1286aac0d4ed026d1cfbcf3fa81c6e4eb96f4347ca17Fabrice Di Meglio        p.gravity = Gravity.START | Gravity.TOP;
1287e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        p.flags = computeFlags(p.flags);
1288e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        p.type = mWindowLayoutType;
1289e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        p.token = token;
1290e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        p.softInputMode = mSoftInputMode;
1291e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        p.windowAnimations = computeAnimationResource();
1292e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBackground != null) {
12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.format = mBackground.getOpacity();
12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.format = PixelFormat.TRANSLUCENT;
12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1298e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
1299e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        if (mHeightMode < 0) {
1300e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            p.height = mLastHeight = mHeightMode;
1301e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        } else {
1302e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            p.height = mLastHeight = mHeight;
1303e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        }
1304e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
1305e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        if (mWidthMode < 0) {
1306e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            p.width = mLastWidth = mWidthMode;
1307e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        } else {
1308e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            p.width = mLastWidth = mWidth;
1309e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        }
1310e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
1311e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        // Used for debugging.
13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.setTitle("PopupWindow:" + Integer.toHexString(hashCode()));
13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return p;
13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int computeFlags(int curFlags) {
13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        curFlags &= ~(
13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES |
13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |
1324ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell                WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
1325ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell                WindowManager.LayoutParams.FLAG_SPLIT_TOUCH);
13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if(mIgnoreCheekPress) {
13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES;
13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mFocusable) {
13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mInputMethodMode == INPUT_METHOD_NEEDED) {
13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (mInputMethodMode == INPUT_METHOD_NOT_NEEDED) {
13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mTouchable) {
13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1340c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project        if (mOutsideTouchable) {
13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mClippingEnabled) {
13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
134646e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown        if (isSplitTouchEnabled()) {
134701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            curFlags |= WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
134801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        }
1349ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell        if (mLayoutInScreen) {
1350ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell            curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
1351ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell        }
13520bd1d0a15294345bf88b20df28466907f982cec7Adam Powell        if (mLayoutInsetDecor) {
13530bd1d0a15294345bf88b20df28466907f982cec7Adam Powell            curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
13540bd1d0a15294345bf88b20df28466907f982cec7Adam Powell        }
1355e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell        if (mNotTouchModal) {
1356e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell            curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
1357e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell        }
1358393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        if (mAttachedInDecor) {
1359393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale          curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR;
1360393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        }
13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return curFlags;
13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1363393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int computeAnimationResource() {
13655435a30ae552391f14009c4459731ae149675b18Alan Viverette        if (mAnimationStyle == ANIMATION_STYLE_DEFAULT) {
13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mIsDropdown) {
13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return mAboveAnchor
13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ? com.android.internal.R.style.Animation_DropDownUp
13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        : com.android.internal.R.style.Animation_DropDownDown;
13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mAnimationStyle;
13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1375560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1377560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * Positions the popup window on screen. When the popup window is too tall
1378560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * to fit under the anchor, a parent scroll view is seeked and scrolled up
1379560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * to reclaim space. If scrolling is not possible or not enough, the popup
1380560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * window gets moved on top of the anchor.
1381560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * <p>
1382560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * The height must have been set on the layout parameters prior to calling
1383560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * this method.
13845435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the view on which the popup window must be anchored
13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param p the layout parameters used to display the drop down
1387560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * @param xoff horizontal offset used to adjust for background padding
1388560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * @param yoff vertical offset used to adjust for background padding
1389560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * @param gravity horizontal gravity specifying popup alignment
13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is translated upwards to fit on screen
13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1392560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette    private boolean findDropDownPosition(View anchor, WindowManager.LayoutParams p, int xoff,
1393560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            int yoff, int gravity) {
139462e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell        final int anchorHeight = anchor.getHeight();
1395560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        final int anchorWidth = anchor.getWidth();
1396560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        if (mOverlapAnchor) {
1397560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            yoff -= anchorHeight;
1398560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        }
1399560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        anchor.getLocationInWindow(mDrawingLocation);
14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.x = mDrawingLocation[0] + xoff;
140262e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell        p.y = mDrawingLocation[1] + anchorHeight + yoff;
140354c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell
1404560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        final int hgrav = Gravity.getAbsoluteGravity(gravity, anchor.getLayoutDirection())
1405560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette                & Gravity.HORIZONTAL_GRAVITY_MASK;
140654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell        if (hgrav == Gravity.RIGHT) {
1407560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            // Flip the location to align the right sides of the popup and
1408560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            // anchor instead of left.
1409560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            p.x -= mPopupWidth - anchorWidth;
141054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell        }
1411560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean onTop = false;
14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
141454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell        p.gravity = Gravity.LEFT | Gravity.TOP;
141554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell
14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        anchor.getLocationOnScreen(mScreenLocation);
14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Rect displayFrame = new Rect();
14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        anchor.getWindowVisibleDisplayFrame(displayFrame);
141962e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell
1420560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        final int screenY = mScreenLocation[1] + anchorHeight + yoff;
14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View root = anchor.getRootView();
1422560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        if (screenY + mPopupHeight > displayFrame.bottom
1423560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette                || p.x + mPopupWidth - root.getWidth() > 0) {
1424560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            // If the drop down disappears at the bottom of the screen, we try
1425560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            // to scroll a parent scrollview or move the drop down back up on
1426560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            // top of the edit box.
1427b7c1b20c8a5a4d4378ae91b4a1f12a34100df452Adam Powell            if (mAllowScrollingAnchorParent) {
1428560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette                final int scrollX = anchor.getScrollX();
1429560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette                final int scrollY = anchor.getScrollY();
1430560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette                final Rect r = new Rect(scrollX, scrollY, scrollX + mPopupWidth + xoff,
1431560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette                        scrollY + mPopupHeight + anchorHeight + yoff);
1432b7c1b20c8a5a4d4378ae91b4a1f12a34100df452Adam Powell                anchor.requestRectangleOnScreen(r, true);
1433b7c1b20c8a5a4d4378ae91b4a1f12a34100df452Adam Powell            }
14343e141685003939a9addce21ba2492ea3a8aebee6Romain Guy
1435560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            // Now we re-evaluate the space available, and decide from that
14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // whether the pop-up will go above or below the anchor.
14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            anchor.getLocationInWindow(mDrawingLocation);
14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.x = mDrawingLocation[0] + xoff;
1439560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            p.y = mDrawingLocation[1] + anchorHeight + yoff;
144054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell
1441560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            // Preserve the gravity adjustment.
144254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell            if (hgrav == Gravity.RIGHT) {
1443560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette                p.x -= mPopupWidth - anchorWidth;
144454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell            }
1445560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
1446560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            // Determine whether there is more space above or below the anchor.
14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            anchor.getLocationOnScreen(mScreenLocation);
1448560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            onTop = (displayFrame.bottom - mScreenLocation[1] - anchorHeight - yoff) <
14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    (mScreenLocation[1] - yoff - displayFrame.top);
14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (onTop) {
145154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell                p.gravity = Gravity.LEFT | Gravity.BOTTOM;
14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                p.y = root.getHeight() - mDrawingLocation[1] + yoff;
14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
1454560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette                p.y = mDrawingLocation[1] + anchorHeight + yoff;
14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
145856c2d337e02a275397fc9d0460dca90977f199acAdam Powell        if (mClipToScreen) {
145956c2d337e02a275397fc9d0460dca90977f199acAdam Powell            final int displayFrameWidth = displayFrame.right - displayFrame.left;
1460560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            final int right = p.x + p.width;
146156c2d337e02a275397fc9d0460dca90977f199acAdam Powell            if (right > displayFrameWidth) {
146256c2d337e02a275397fc9d0460dca90977f199acAdam Powell                p.x -= right - displayFrameWidth;
146356c2d337e02a275397fc9d0460dca90977f199acAdam Powell            }
1464560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
146556c2d337e02a275397fc9d0460dca90977f199acAdam Powell            if (p.x < displayFrame.left) {
146656c2d337e02a275397fc9d0460dca90977f199acAdam Powell                p.x = displayFrame.left;
146756c2d337e02a275397fc9d0460dca90977f199acAdam Powell                p.width = Math.min(p.width, displayFrameWidth);
146856c2d337e02a275397fc9d0460dca90977f199acAdam Powell            }
146956c2d337e02a275397fc9d0460dca90977f199acAdam Powell
14705f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell            if (onTop) {
1471560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette                final int popupTop = mScreenLocation[1] + yoff - mPopupHeight;
14725f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell                if (popupTop < 0) {
14735f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell                    p.y += popupTop;
14745f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell                }
14755f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell            } else {
14765f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell                p.y = Math.max(p.y, displayFrame.top);
14775f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell            }
147856c2d337e02a275397fc9d0460dca90977f199acAdam Powell        }
147956c2d337e02a275397fc9d0460dca90977f199acAdam Powell
14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.gravity |= Gravity.DISPLAY_CLIP_VERTICAL;
1481560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return onTop;
14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14845435a30ae552391f14009c4459731ae149675b18Alan Viverette
14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the maximum height that is available for the popup to be
14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * completely shown. It is recommended that this height be the maximum for
14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the popup's height, otherwise it is possible that the popup will be
14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * clipped.
14905435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor The view on which the popup window must be anchored.
14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The maximum available height for the popup to be completely
14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         shown.
14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getMaxAvailableHeight(View anchor) {
14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return getMaxAvailableHeight(anchor, 0);
14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the maximum height that is available for the popup to be
15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * completely shown. It is recommended that this height be the maximum for
15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the popup's height, otherwise it is possible that the popup will be
15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * clipped.
15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor The view on which the popup window must be anchored.
15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param yOffset y offset from the view's bottom edge
15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The maximum available height for the popup to be completely
15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         shown.
15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getMaxAvailableHeight(View anchor, int yOffset) {
151198acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau        return getMaxAvailableHeight(anchor, yOffset, false);
151298acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau    }
15135435a30ae552391f14009c4459731ae149675b18Alan Viverette
151498acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau    /**
151598acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * Returns the maximum height that is available for the popup to be
151698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * completely shown, optionally ignoring any bottom decorations such as
151798acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * the input method. It is recommended that this height be the maximum for
151898acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * the popup's height, otherwise it is possible that the popup will be
151998acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * clipped.
15205435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
152198acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * @param anchor The view on which the popup window must be anchored.
152298acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * @param yOffset y offset from the view's bottom edge
152398acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * @param ignoreBottomDecorations if true, the height returned will be
152498acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     *        all the way to the bottom of the display, ignoring any
152598acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     *        bottom decorations
152698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * @return The maximum available height for the popup to be completely
152798acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     *         shown.
15285435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
152998acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * @hide Pending API council approval.
153098acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     */
153198acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau    public int getMaxAvailableHeight(View anchor, int yOffset, boolean ignoreBottomDecorations) {
15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Rect displayFrame = new Rect();
15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        anchor.getWindowVisibleDisplayFrame(displayFrame);
15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int[] anchorPos = mDrawingLocation;
15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        anchor.getLocationOnScreen(anchorPos);
15375435a30ae552391f14009c4459731ae149675b18Alan Viverette
153898acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau        int bottomEdge = displayFrame.bottom;
153998acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau        if (ignoreBottomDecorations) {
1540a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powell            Resources res = anchor.getContext().getResources();
15413f4a764cf400aa209c1f8f76a1c73143eefc4905Adam Powell            bottomEdge = res.getDisplayMetrics().heightPixels;
154298acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau        }
154398acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau        final int distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset;
15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset;
15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // anchorPos[1] is distance from anchor to top of screen
15479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int returnedHeight = Math.max(distanceToBottom, distanceToTop);
15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBackground != null) {
15499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mBackground.getPadding(mTempRect);
15505435a30ae552391f14009c4459731ae149675b18Alan Viverette            returnedHeight -= mTempRect.top + mTempRect.bottom;
15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15525435a30ae552391f14009c4459731ae149675b18Alan Viverette
15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return returnedHeight;
15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15555435a30ae552391f14009c4459731ae149675b18Alan Viverette
15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
15577878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette     * Disposes of the popup window. This method can be invoked only after
15587878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette     * {@link #showAsDropDown(android.view.View)} has been executed. Failing
15597878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette     * that, calling this method will have no effect.
15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
15615435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #showAsDropDown(android.view.View)
15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void dismiss() {
15648fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        if (!isShowing() || mIsTransitioningToDismiss) {
1565e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            return;
1566e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        }
156706f938e8aa56cd89ab0bdb04c8b946392c428dd1Svetoslav Ganov
15688fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        final PopupDecorView decorView = mDecorView;
15698fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        final View contentView = mContentView;
15708fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
15718fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        final ViewGroup contentHolder;
15728fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        final ViewParent contentParent = contentView.getParent();
15738fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        if (contentParent instanceof ViewGroup) {
15748fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            contentHolder = ((ViewGroup) contentParent);
15758fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        } else {
15768fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            contentHolder = null;
15778fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
15788fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
15798fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // Ensure any ongoing or pending transitions are canceled.
15808fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        decorView.cancelTransitions();
15818fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
1582e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        mIsShowing = false;
15838fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        mIsTransitioningToDismiss = true;
1584b82d074038f4c8d86e1bd4f3fa4d3780bd4bcba5Craig Mautner
158595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final Transition exitTransition = mExitTransition;
158695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        if (exitTransition != null && decorView.isLaidOut()) {
158795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            // The decor view is non-interactive during exit transitions.
158895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            final LayoutParams p = (LayoutParams) decorView.getLayoutParams();
158995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            p.flags |= LayoutParams.FLAG_NOT_TOUCHABLE;
159095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            p.flags |= LayoutParams.FLAG_NOT_FOCUSABLE;
159195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            mWindowManager.updateViewLayout(decorView, p);
159295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette
159395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            final Rect epicenter = getRelativeAnchorBounds();
159495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            exitTransition.setEpicenterCallback(new EpicenterCallback() {
159595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                @Override
159695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                public Rect onGetEpicenter(Transition transition) {
159795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                    return epicenter;
159895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                }
159995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            });
160095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            decorView.startExitTransition(exitTransition, new TransitionListenerAdapter() {
1601e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette                @Override
1602e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette                public void onTransitionEnd(Transition transition) {
16038fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                    dismissImmediate(decorView, contentHolder, contentView);
1604e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette                }
1605e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            });
1606e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        } else {
16078fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            dismissImmediate(decorView, contentHolder, contentView);
16087878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette        }
16097878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette
161095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        // Clears the anchor view.
161195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        unregisterForScrollChanged();
161295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette
16137878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette        if (mOnDismissListener != null) {
16147878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette            mOnDismissListener.onDismiss();
16155435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
16165435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
16175435a30ae552391f14009c4459731ae149675b18Alan Viverette
161895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette    private Rect getRelativeAnchorBounds() {
161995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final View anchor = mAnchor != null ? mAnchor.get() : null;
162095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final View decor = mDecorView;
162195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        if (anchor == null || decor == null) {
162295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            return null;
162395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        }
162495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette
162595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final int[] anchorLocation = anchor.getLocationOnScreen();
162695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final int[] popupLocation = mDecorView.getLocationOnScreen();
162795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette
162895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        // Compute the position of the anchor relative to the popup.
162995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final Rect bounds = new Rect(0, 0, anchor.getWidth(), anchor.getHeight());
163095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        bounds.offset(anchorLocation[0] - popupLocation[0], anchorLocation[1] - popupLocation[1]);
163195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        return bounds;
163295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette    }
163395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette
16345435a30ae552391f14009c4459731ae149675b18Alan Viverette    /**
16355435a30ae552391f14009c4459731ae149675b18Alan Viverette     * Removes the popup from the window manager and tears down the supporting
16365435a30ae552391f14009c4459731ae149675b18Alan Viverette     * view hierarchy, if necessary.
16375435a30ae552391f14009c4459731ae149675b18Alan Viverette     */
16388fd949e680c15d397084430d4907c16cedfacddaAlan Viverette    private void dismissImmediate(View decorView, ViewGroup contentHolder, View contentView) {
16398fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // If this method gets called and the decor view doesn't have a parent,
16408fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // then it was either never added or was already removed. That should
16418fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // never happen, but it's worth checking to avoid potential crashes.
16428fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        if (decorView.getParent() != null) {
16438fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            mWindowManager.removeViewImmediate(decorView);
1644df4639a0135ea643b493067b3f7cd1e092346c78Alan Viverette        }
1645df4639a0135ea643b493067b3f7cd1e092346c78Alan Viverette
16468fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        if (contentHolder != null) {
16478fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            contentHolder.removeView(contentView);
16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16498fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
16508fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // This needs to stay until after all transitions have ended since we
16518fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // need the reference to cancel transitions in preparePopup().
16528fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        mDecorView = null;
16538fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        mIsTransitioningToDismiss = false;
16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the listener to be called when the window is dismissed.
16585435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
16599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param onDismissListener The listener.
16609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
16619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setOnDismissListener(OnDismissListener onDismissListener) {
16629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOnDismissListener = onDismissListener;
16639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16645435a30ae552391f14009c4459731ae149675b18Alan Viverette
16659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Updates the state of the popup window, if it is currently being displayed,
1667259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * from the currently set state.
1668259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
1669259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * This includes:
1670259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <ul>
1671259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setClippingEnabled(boolean)}</li>
1672259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setFocusable(boolean)}</li>
1673259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setIgnoreCheekPress()}</li>
1674259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setInputMethodMode(int)}</li>
1675259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setTouchable(boolean)}</li>
1676259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setAnimationStyle(int)}</li>
1677259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * </ul>
16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update() {
16809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!isShowing() || mContentView == null) {
16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16835435a30ae552391f14009c4459731ae149675b18Alan Viverette
16845435a30ae552391f14009c4459731ae149675b18Alan Viverette        final WindowManager.LayoutParams p =
16855435a30ae552391f14009c4459731ae149675b18Alan Viverette                (WindowManager.LayoutParams) mDecorView.getLayoutParams();
16865435a30ae552391f14009c4459731ae149675b18Alan Viverette
16879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean update = false;
16885435a30ae552391f14009c4459731ae149675b18Alan Viverette
16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int newAnim = computeAnimationResource();
16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newAnim != p.windowAnimations) {
16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.windowAnimations = newAnim;
16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int newFlags = computeFlags(p.flags);
16969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newFlags != p.flags) {
16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.flags = newFlags;
16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1700b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio
17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (update) {
1702b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio            setLayoutDirectionFromAnchor();
17035435a30ae552391f14009c4459731ae149675b18Alan Viverette            mWindowManager.updateViewLayout(mDecorView, p);
17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1706d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy
1707d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy    /**
1708259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Updates the dimension of the popup window.
1709259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
1710259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Calling this function also updates the window with the current popup
1711259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * state as described for {@link #update()}.
1712d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy     *
1713259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param width the new width, must be >= 0 or -1 to ignore
1714259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param height the new height, must be >= 0 or -1 to ignore
1715d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy     */
1716d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy    public void update(int width, int height) {
17175435a30ae552391f14009c4459731ae149675b18Alan Viverette        final WindowManager.LayoutParams p =
17185435a30ae552391f14009c4459731ae149675b18Alan Viverette                (WindowManager.LayoutParams) mDecorView.getLayoutParams();
1719d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy        update(p.x, p.y, width, height, false);
1720d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy    }
17215435a30ae552391f14009c4459731ae149675b18Alan Viverette
17229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1723259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Updates the position and the dimension of the popup window.
1724259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
1725259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Width and height can be set to -1 to update location only. Calling this
1726259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * function also updates the window with the current popup state as
1727259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * described for {@link #update()}.
17289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x the new x location
17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y the new y location
1731259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param width the new width, must be >= 0 or -1 to ignore
1732259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param height the new height, must be >= 0 or -1 to ignore
17339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update(int x, int y, int width, int height) {
17359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        update(x, y, width, height, false);
17369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1739259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Updates the position and the dimension of the popup window.
1740259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
1741259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Width and height can be set to -1 to update location only. Calling this
1742259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * function also updates the window with the current popup state as
1743259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * described for {@link #update()}.
17449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
17459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x the new x location
17469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y the new y location
1747259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param width the new width, must be >= 0 or -1 to ignore
1748259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param height the new height, must be >= 0 or -1 to ignore
1749259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param force {@code true} to reposition the window even if the specified
1750259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *              position already seems to correspond to the LayoutParams,
1751259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *              {@code false} to only reposition if needed
17529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update(int x, int y, int width, int height, boolean force) {
1754259c2840691a79634ffd8f63291ec21c21819542Alan Viverette        if (width >= 0) {
17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mLastWidth = width;
17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setWidth(width);
17579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1759259c2840691a79634ffd8f63291ec21c21819542Alan Viverette        if (height >= 0) {
17609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mLastHeight = height;
17619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setHeight(height);
17629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!isShowing() || mContentView == null) {
17659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
17669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17685435a30ae552391f14009c4459731ae149675b18Alan Viverette        final WindowManager.LayoutParams p =
17695435a30ae552391f14009c4459731ae149675b18Alan Viverette                (WindowManager.LayoutParams) mDecorView.getLayoutParams();
17709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean update = force;
17729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int finalWidth = mWidthMode < 0 ? mWidthMode : mLastWidth;
17749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (width != -1 && p.width != finalWidth) {
17759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.width = mLastWidth = finalWidth;
17769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
17779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int finalHeight = mHeightMode < 0 ? mHeightMode : mLastHeight;
17809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (height != -1 && p.height != finalHeight) {
17819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.height = mLastHeight = finalHeight;
17829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
17839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p.x != x) {
17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.x = x;
17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
17889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p.y != y) {
17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.y = y;
17929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
17939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int newAnim = computeAnimationResource();
17969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newAnim != p.windowAnimations) {
17979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.windowAnimations = newAnim;
17989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
17999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int newFlags = computeFlags(p.flags);
18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newFlags != p.flags) {
18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.flags = newFlags;
18049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
18059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
180698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau
18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (update) {
1808b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio            setLayoutDirectionFromAnchor();
18095435a30ae552391f14009c4459731ae149675b18Alan Viverette            mWindowManager.updateViewLayout(mDecorView, p);
18109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1814259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Updates the position and the dimension of the popup window.
1815259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
1816259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Calling this function also updates the window with the current popup
1817259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * state as described for {@link #update()}.
18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the popup's anchor view
1820259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param width the new width, must be >= 0 or -1 to ignore
1821259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param height the new height, must be >= 0 or -1 to ignore
18229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update(View anchor, int width, int height) {
182475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        update(anchor, false, 0, 0, true, width, height);
18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1828259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Updates the position and the dimension of the popup window.
1829259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
1830259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Width and height can be set to -1 to update location only. Calling this
1831259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * function also updates the window with the current popup state as
1832259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * described for {@link #update()}.
1833259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
1834259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * If the view later scrolls to move {@code anchor} to a different
1835259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * location, the popup will be moved correspondingly.
18369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the popup's anchor view
18389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param xoff x offset from the view's left edge
18399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param yoff y offset from the view's bottom edge
1840259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param width the new width, must be >= 0 or -1 to ignore
1841259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param height the new height, must be >= 0 or -1 to ignore
18429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update(View anchor, int xoff, int yoff, int width, int height) {
184475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        update(anchor, true, xoff, yoff, true, width, height);
1845105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
1846105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
1847105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    private void update(View anchor, boolean updateLocation, int xoff, int yoff,
184875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette            boolean updateDimension, int width, int height) {
1849105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
18509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!isShowing() || mContentView == null) {
18519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
18529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
185475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        final WeakReference<View> oldAnchor = mAnchor;
185575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        final boolean needsUpdate = updateLocation && (mAnchorXoff != xoff || mAnchorYoff != yoff);
185681f08086b44a117097960195d2c9072e29644962Gilles Debunne        if (oldAnchor == null || oldAnchor.get() != anchor || (needsUpdate && !mIsDropdown)) {
185775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette            registerForScrollChanged(anchor, xoff, yoff, mAnchoredGravity);
185881f08086b44a117097960195d2c9072e29644962Gilles Debunne        } else if (needsUpdate) {
185981f08086b44a117097960195d2c9072e29644962Gilles Debunne            // No need to register again if this is a DropDown, showAsDropDown already did.
186081f08086b44a117097960195d2c9072e29644962Gilles Debunne            mAnchorXoff = xoff;
186181f08086b44a117097960195d2c9072e29644962Gilles Debunne            mAnchorYoff = yoff;
18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1864105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (updateDimension) {
1865105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            if (width == -1) {
1866105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                width = mPopupWidth;
1867105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            } else {
1868105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                mPopupWidth = width;
1869105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            }
1870105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            if (height == -1) {
1871105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                height = mPopupHeight;
1872105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            } else {
1873105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                mPopupHeight = height;
1874105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            }
18759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1876105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
187775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        final WindowManager.LayoutParams p =
18785435a30ae552391f14009c4459731ae149675b18Alan Viverette                (WindowManager.LayoutParams) mDecorView.getLayoutParams();
187975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        final int x = p.x;
188075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        final int y = p.y;
1881105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (updateLocation) {
188275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette            updateAboveAnchor(findDropDownPosition(anchor, p, xoff, yoff, mAnchoredGravity));
18839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
188454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell            updateAboveAnchor(findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff,
188554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell                    mAnchoredGravity));
18869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1887b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio
18883e141685003939a9addce21ba2492ea3a8aebee6Romain Guy        update(p.x, p.y, width, height, x != p.x || y != p.y);
18899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Listener that is called when this popup window is dismissed.
18939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface OnDismissListener {
18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
18969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Called when this popup window is dismissed.
18979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
18989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onDismiss();
18999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void unregisterForScrollChanged() {
1902e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        final WeakReference<View> anchorRef = mAnchor;
1903e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        final View anchor = anchorRef == null ? null : anchorRef.get();
19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (anchor != null) {
1905e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            final ViewTreeObserver vto = anchor.getViewTreeObserver();
19069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            vto.removeOnScrollChangedListener(mOnScrollChangedListener);
19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1908e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
19099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAnchor = null;
19109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
191254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell    private void registerForScrollChanged(View anchor, int xoff, int yoff, int gravity) {
19139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        unregisterForScrollChanged();
19149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19155435a30ae552391f14009c4459731ae149675b18Alan Viverette        mAnchor = new WeakReference<>(anchor);
1916e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
1917e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        final ViewTreeObserver vto = anchor.getViewTreeObserver();
19189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (vto != null) {
19199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            vto.addOnScrollChangedListener(mOnScrollChangedListener);
19209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAnchorXoff = xoff;
19239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAnchorYoff = yoff;
192454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell        mAnchoredGravity = gravity;
19259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19275435a30ae552391f14009c4459731ae149675b18Alan Viverette    private class PopupDecorView extends FrameLayout {
19288fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        private TransitionListenerAdapter mPendingExitListener;
19298fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
19305435a30ae552391f14009c4459731ae149675b18Alan Viverette        public PopupDecorView(Context context) {
19315435a30ae552391f14009c4459731ae149675b18Alan Viverette            super(context);
19325435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
19339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
19359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean dispatchKeyEvent(KeyEvent event) {
19369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
19374ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson                if (getKeyDispatcherState() == null) {
19384ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson                    return super.dispatchKeyEvent(event);
19394ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson                }
19404ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson
19415435a30ae552391f14009c4459731ae149675b18Alan Viverette                if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
19425435a30ae552391f14009c4459731ae149675b18Alan Viverette                    final KeyEvent.DispatcherState state = getKeyDispatcherState();
1943b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                    if (state != null) {
1944b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                        state.startTracking(event, this);
1945b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                    }
19468d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                    return true;
1947b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                } else if (event.getAction() == KeyEvent.ACTION_UP) {
19485435a30ae552391f14009c4459731ae149675b18Alan Viverette                    final KeyEvent.DispatcherState state = getKeyDispatcherState();
1949b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                    if (state != null && state.isTracking(event) && !event.isCanceled()) {
1950b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                        dismiss();
1951b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                        return true;
1952b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                    }
19538d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                }
19548d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                return super.dispatchKeyEvent(event);
19559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
19569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return super.dispatchKeyEvent(event);
19579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
19619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean dispatchTouchEvent(MotionEvent ev) {
19629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mTouchInterceptor != null && mTouchInterceptor.onTouch(this, ev)) {
19639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
19649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
19659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return super.dispatchTouchEvent(ev);
19669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
19699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean onTouchEvent(MotionEvent event) {
19709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int x = (int) event.getX();
19719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int y = (int) event.getY();
19725435a30ae552391f14009c4459731ae149675b18Alan Viverette
19739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((event.getAction() == MotionEvent.ACTION_DOWN)
19749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    && ((x < 0) || (x >= getWidth()) || (y < 0) || (y >= getHeight()))) {
19759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dismiss();
19769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
19779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
19789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dismiss();
19799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
19809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
19819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return super.onTouchEvent(event);
19829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
19839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19848fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
19858fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        /**
19868fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * Requests that an enter transition run after the next layout pass.
19878fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         */
19888fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        public void requestEnterTransition(Transition transition) {
19898fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            final ViewTreeObserver observer = getViewTreeObserver();
19908fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            if (observer != null && transition != null) {
19918fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                final Transition enterTransition = transition.clone();
19928fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
19938fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                // Postpone the enter transition after the first layout pass.
19948fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
19958fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                    @Override
19968fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                    public void onGlobalLayout() {
19978fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                        final ViewTreeObserver observer = getViewTreeObserver();
19988fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                        if (observer != null) {
19998fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                            observer.removeOnGlobalLayoutListener(this);
20008fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                        }
20018fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
200295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                        final Rect epicenter = getRelativeAnchorBounds();
200395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                        enterTransition.setEpicenterCallback(new EpicenterCallback() {
200495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                            @Override
200595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                            public Rect onGetEpicenter(Transition transition) {
200695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                                return epicenter;
200795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                            }
200895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                        });
20098fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                        startEnterTransition(enterTransition);
20108fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                    }
20118fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                });
20128fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
20138fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
20148fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
20158fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        /**
20168fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * Starts the pending enter transition, if one is set.
20178fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         */
20188fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        private void startEnterTransition(Transition enterTransition) {
20198fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            final int count = getChildCount();
20208fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            for (int i = 0; i < count; i++) {
20218fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                final View child = getChildAt(i);
20228fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                enterTransition.addTarget(child);
20238fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                child.setVisibility(View.INVISIBLE);
20248fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
20258fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
20268fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            TransitionManager.beginDelayedTransition(this, enterTransition);
20278fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
20288fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            for (int i = 0; i < count; i++) {
20298fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                final View child = getChildAt(i);
20308fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                child.setVisibility(View.VISIBLE);
20318fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
20328fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
20338fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
20348fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        /**
20358fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * Starts an exit transition immediately.
20368fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * <p>
20378fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * <strong>Note:</strong> The transition listener is guaranteed to have
20388fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * its {@code onTransitionEnd} method called even if the transition
20398fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * never starts; however, it may be called with a {@code null} argument.
20408fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         */
20418fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        public void startExitTransition(Transition transition, final TransitionListener listener) {
20428fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            if (transition == null) {
20438fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                return;
20448fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
20458fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
20468fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            // The exit listener MUST be called for cleanup, even if the
20478fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            // transition never starts or ends. Stash it for later.
20488fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            mPendingExitListener = new TransitionListenerAdapter() {
20498fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                @Override
20508fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                public void onTransitionEnd(Transition transition) {
20518fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                    listener.onTransitionEnd(transition);
20528fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
20538fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                    // The listener was called. Our job here is done.
20548fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                    mPendingExitListener = null;
20558fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                }
20568fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            };
20578fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
20588fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            final Transition exitTransition = transition.clone();
20598fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            exitTransition.addListener(mPendingExitListener);
20608fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
20618fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            final int count = getChildCount();
20628fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            for (int i = 0; i < count; i++) {
20638fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                final View child = getChildAt(i);
20648fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                exitTransition.addTarget(child);
20658fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
20668fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
20678fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            TransitionManager.beginDelayedTransition(this, exitTransition);
20688fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
20698fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            for (int i = 0; i < count; i++) {
20708fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                final View child = getChildAt(i);
20718fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                child.setVisibility(View.INVISIBLE);
20728fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
20738fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
20748fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
20758fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        /**
20768fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * Cancels all pending or current transitions.
20778fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         */
20788fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        public void cancelTransitions() {
20798fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            TransitionManager.endTransitions(this);
20808fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
20818fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            if (mPendingExitListener != null) {
20828fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                mPendingExitListener.onTransitionEnd(null);
20838fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
20848fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
20855435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
20865435a30ae552391f14009c4459731ae149675b18Alan Viverette
20875435a30ae552391f14009c4459731ae149675b18Alan Viverette    private class PopupBackgroundView extends FrameLayout {
20885435a30ae552391f14009c4459731ae149675b18Alan Viverette        public PopupBackgroundView(Context context) {
20895435a30ae552391f14009c4459731ae149675b18Alan Viverette            super(context);
20905435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
209175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
209275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        @Override
20935435a30ae552391f14009c4459731ae149675b18Alan Viverette        protected int[] onCreateDrawableState(int extraSpace) {
20945435a30ae552391f14009c4459731ae149675b18Alan Viverette            if (mAboveAnchor) {
20955435a30ae552391f14009c4459731ae149675b18Alan Viverette                final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
20965435a30ae552391f14009c4459731ae149675b18Alan Viverette                View.mergeDrawableStates(drawableState, ABOVE_ANCHOR_STATE_SET);
20975435a30ae552391f14009c4459731ae149675b18Alan Viverette                return drawableState;
209875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            } else {
20995435a30ae552391f14009c4459731ae149675b18Alan Viverette                return super.onCreateDrawableState(extraSpace);
210075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            }
210175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
21029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2104