PopupWindow.java revision 22dac1c8df4ec212e8195a69d2de15d313d724fb
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
1999441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikasimport static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
2099441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikasimport static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
2199441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikasimport static android.view.WindowManager.LayoutParams
2299441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikas        .PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME;
2399441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikasimport static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viveretteimport android.annotation.NonNull;
261e940dc2d165fa6cdedb6945811988502f87ddceAlan Viveretteimport android.annotation.Nullable;
2775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.Context;
2875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.res.TypedArray;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PixelFormat;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.Drawable;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.StateListDrawable;
3346e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brownimport android.os.Build;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder;
355435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.Transition;
365435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.Transition.EpicenterCallback;
378fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.transition.Transition.TransitionListener;
385435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.TransitionInflater;
39e0c37bdea37f78778f6c4f23f03604e59dfb0d55Ben Weissimport android.transition.TransitionListenerAdapter;
405435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.TransitionManager;
415435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.TransitionSet;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet;
43c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.Gravity;
44c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.KeyEvent;
4550db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwalimport android.view.KeyboardShortcutGroup;
46c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.MotionEvent;
47c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.View;
48634a808226cc5d00bd6897bdc881cafe064e37acAlan Viveretteimport android.view.View.OnAttachStateChangeListener;
49a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport android.view.View.OnTouchListener;
50c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.ViewGroup;
518fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.view.ViewParent;
52c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.ViewTreeObserver;
538fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.view.ViewTreeObserver.OnGlobalLayoutListener;
54c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.ViewTreeObserver.OnScrollChangedListener;
55a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport android.view.WindowManager;
56259c2840691a79634ffd8f63291ec21c21819542Alan Viveretteimport android.view.WindowManager.LayoutParams;
5722dac1c8df4ec212e8195a69d2de15d313d724fbYohei Yukawaimport android.view.WindowManager.LayoutParams.SoftInputModeFlags;
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5999441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikasimport com.android.internal.R;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6199441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikasimport java.lang.ref.WeakReference;
6250db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwalimport java.util.List;
631e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
651e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <p>
661e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * This class represents a popup window that can be used to display an
671e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * arbitrary view. The popup window is a floating container that appears on top
681e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * of the current activity.
691e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </p>
701e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <a name="Animation"></a>
711e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <h3>Animation</h3>
721e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <p>
731e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * On all versions of Android, popup window enter and exit animations may be
741e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * specified by calling {@link #setAnimationStyle(int)} and passing the
751e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * resource ID for an animation style that defines {@code windowEnterAnimation}
761e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * and {@code windowExitAnimation}. For example, passing
771e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * {@link android.R.style#Animation_Dialog} will give a scale and alpha
781e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * animation.
791e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </br>
801e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * A window animation style may also be specified in the popup window's style
811e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * XML via the {@link android.R.styleable#PopupWindow_popupAnimationStyle popupAnimationStyle}
821e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * attribute.
831e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </p>
841e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <p>
851e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * Starting with API 23, more complex popup window enter and exit transitions
861e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * may be specified by calling either {@link #setEnterTransition(Transition)}
871e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * or {@link #setExitTransition(Transition)} and passing a  {@link Transition}.
881e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </br>
891e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * Popup enter and exit transitions may also be specified in the popup window's
901e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * style XML via the {@link android.R.styleable#PopupWindow_popupEnterTransition popupEnterTransition}
911e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * and {@link android.R.styleable#PopupWindow_popupExitTransition popupExitTransition}
921e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * attributes, respectively.
931e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </p>
941e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette *
951e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_overlapAnchor
961e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupAnimationStyle
971e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupBackground
981e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupElevation
991e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupEnterTransition
1001e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupExitTransition
1015435a30ae552391f14009c4459731ae149675b18Alan Viverette *
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.widget.AutoCompleteTextView
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.widget.Spinner
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class PopupWindow {
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
107e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     * Mode for {@link #setInputMethodMode(int)}: the requirements for the
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * input method should be based on the focusability of the popup.  That is
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if it is focusable than it needs to work with the input method, else
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * it doesn't.
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int INPUT_METHOD_FROM_FOCUSABLE = 0;
1135435a30ae552391f14009c4459731ae149675b18Alan Viverette
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
115e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     * Mode for {@link #setInputMethodMode(int)}: this popup always needs to
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * work with an input method, regardless of whether it is focusable.  This
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * means that it will always be displayed so that the user can also operate
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the input method while it is shown.
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int INPUT_METHOD_NEEDED = 1;
1215435a30ae552391f14009c4459731ae149675b18Alan Viverette
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
123e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     * Mode for {@link #setInputMethodMode(int)}: this popup never needs to
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * work with an input method, regardless of whether it is focusable.  This
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * means that it will always be displayed to use as much space on the
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * screen as needed, regardless of whether this covers the input method.
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int INPUT_METHOD_NOT_NEEDED = 2;
12954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell
13054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell    private static final int DEFAULT_ANCHORED_GRAVITY = Gravity.TOP | Gravity.START;
13154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell
1325435a30ae552391f14009c4459731ae149675b18Alan Viverette    /**
1335435a30ae552391f14009c4459731ae149675b18Alan Viverette     * Default animation style indicating that separate animations should be
1345435a30ae552391f14009c4459731ae149675b18Alan Viverette     * used for top/bottom anchoring states.
1355435a30ae552391f14009c4459731ae149675b18Alan Viverette     */
1365435a30ae552391f14009c4459731ae149675b18Alan Viverette    private static final int ANIMATION_STYLE_DEFAULT = -1;
1375435a30ae552391f14009c4459731ae149675b18Alan Viverette
138f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette    private final int[] mTmpDrawingLocation = new int[2];
139f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette    private final int[] mTmpScreenLocation = new int[2];
1405435a30ae552391f14009c4459731ae149675b18Alan Viverette    private final Rect mTempRect = new Rect();
1415435a30ae552391f14009c4459731ae149675b18Alan Viverette
142448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy    private Context mContext;
143448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy    private WindowManager mWindowManager;
1445435a30ae552391f14009c4459731ae149675b18Alan Viverette
14550db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal    /**
14650db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal     * Keeps track of popup's parent's decor view. This is needed to dispatch
14750db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal     * requestKeyboardShortcuts to the owning Activity.
14850db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal     */
14950db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal    private WeakReference<View> mParentRootView;
15050db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mIsShowing;
1528fd949e680c15d397084430d4907c16cedfacddaAlan Viverette    private boolean mIsTransitioningToDismiss;
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mIsDropdown;
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1555435a30ae552391f14009c4459731ae149675b18Alan Viverette    /** View that handles event dispatch and content transitions. */
1565435a30ae552391f14009c4459731ae149675b18Alan Viverette    private PopupDecorView mDecorView;
1575435a30ae552391f14009c4459731ae149675b18Alan Viverette
158697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette    /** View that holds the background and may animate during a transition. */
159697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette    private View mBackgroundView;
160697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette
161697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette    /** The contents of the popup. May be identical to the background view. */
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private View mContentView;
1635435a30ae552391f14009c4459731ae149675b18Alan Viverette
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mFocusable;
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mInputMethodMode = INPUT_METHOD_FROM_FOCUSABLE;
16622dac1c8df4ec212e8195a69d2de15d313d724fbYohei Yukawa    @SoftInputModeFlags
1677eab094722af54717859b7dcce3cc050f059e00bDianne Hackborn    private int mSoftInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED;
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mTouchable = true;
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mOutsideTouchable = false;
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mClippingEnabled = true;
17146e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown    private int mSplitTouchEnabled = -1;
172ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    private boolean mLayoutInScreen;
17356c2d337e02a275397fc9d0460dca90977f199acAdam Powell    private boolean mClipToScreen;
174348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell    private boolean mAllowScrollingAnchorParent = true;
1750bd1d0a15294345bf88b20df28466907f982cec7Adam Powell    private boolean mLayoutInsetDecor = false;
176e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell    private boolean mNotTouchModal;
177393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    private boolean mAttachedInDecor = true;
178393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    private boolean mAttachedInDecorSet = false;
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private OnTouchListener mTouchInterceptor;
181393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mWidthMode;
183259c2840691a79634ffd8f63291ec21c21819542Alan Viverette    private int mWidth = LayoutParams.WRAP_CONTENT;
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mLastWidth;
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mHeightMode;
186259c2840691a79634ffd8f63291ec21c21819542Alan Viverette    private int mHeight = LayoutParams.WRAP_CONTENT;
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mLastHeight;
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
189ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    private float mElevation;
190ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mBackground;
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mAboveAnchorBackgroundDrawable;
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mBelowAnchorBackgroundDrawable;
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1955435a30ae552391f14009c4459731ae149675b18Alan Viverette    private Transition mEnterTransition;
1965435a30ae552391f14009c4459731ae149675b18Alan Viverette    private Transition mExitTransition;
19791098574f90277128415e9593cce1e495cc51465Alan Viverette    private Rect mEpicenterBounds;
198560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mAboveAnchor;
200574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    private int mWindowLayoutType = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
2015435a30ae552391f14009c4459731ae149675b18Alan Viverette
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private OnDismissListener mOnDismissListener;
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mIgnoreCheekPress = false;
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2055435a30ae552391f14009c4459731ae149675b18Alan Viverette    private int mAnimationStyle = ANIMATION_STYLE_DEFAULT;
2065435a30ae552391f14009c4459731ae149675b18Alan Viverette
207085160612d9066e23c96a6cac15eb3a51481fdafRobert Carr    private int mGravity = Gravity.NO_GRAVITY;
208085160612d9066e23c96a6cac15eb3a51481fdafRobert Carr
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int[] ABOVE_ANCHOR_STATE_SET = new int[] {
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        com.android.internal.R.attr.state_above_anchor
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
213634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette    private final OnAttachStateChangeListener mOnAnchorRootDetachedListener =
214634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            new OnAttachStateChangeListener() {
215634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                @Override
216634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                public void onViewAttachedToWindow(View v) {}
217634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
218634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                @Override
219634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                public void onViewDetachedFromWindow(View v) {
220634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    mIsAnchorRootAttached = false;
221634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                }
222634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            };
223634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private WeakReference<View> mAnchor;
225634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette    private WeakReference<View> mAnchorRoot;
226634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette    private boolean mIsAnchorRootAttached;
227560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
2285435a30ae552391f14009c4459731ae149675b18Alan Viverette    private final OnScrollChangedListener mOnScrollChangedListener = new OnScrollChangedListener() {
2295435a30ae552391f14009c4459731ae149675b18Alan Viverette        @Override
2305435a30ae552391f14009c4459731ae149675b18Alan Viverette        public void onScrollChanged() {
2315435a30ae552391f14009c4459731ae149675b18Alan Viverette            final View anchor = mAnchor != null ? mAnchor.get() : null;
2325435a30ae552391f14009c4459731ae149675b18Alan Viverette            if (anchor != null && mDecorView != null) {
2335435a30ae552391f14009c4459731ae149675b18Alan Viverette                final WindowManager.LayoutParams p = (WindowManager.LayoutParams)
2345435a30ae552391f14009c4459731ae149675b18Alan Viverette                        mDecorView.getLayoutParams();
2355435a30ae552391f14009c4459731ae149675b18Alan Viverette
2365435a30ae552391f14009c4459731ae149675b18Alan Viverette                updateAboveAnchor(findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff,
23750df07a1add902da01018756c213169e4e126a28Alan Viverette                        p.width, p.height, mAnchoredGravity, false));
2385435a30ae552391f14009c4459731ae149675b18Alan Viverette                update(p.x, p.y, -1, -1, true);
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2405435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
2415435a30ae552391f14009c4459731ae149675b18Alan Viverette    };
242560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
2435435a30ae552391f14009c4459731ae149675b18Alan Viverette    private int mAnchorXoff;
2445435a30ae552391f14009c4459731ae149675b18Alan Viverette    private int mAnchorYoff;
2455435a30ae552391f14009c4459731ae149675b18Alan Viverette    private int mAnchoredGravity;
246560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette    private boolean mOverlapAnchor;
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
248b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio    private boolean mPopupViewInitialLayoutDirectionInherited;
249b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window of dimension (0,0).</p>
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does provide a background.</p>
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(Context context) {
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(context, null);
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window of dimension (0,0).</p>
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does provide a background.</p>
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(Context context, AttributeSet attrs) {
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(context, attrs, com.android.internal.R.attr.popupWindowStyle);
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window of dimension (0,0).</p>
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does provide a background.</p>
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
273617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr) {
274617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        this(context, attrs, defStyleAttr, 0);
275c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
2765435a30ae552391f14009c4459731ae149675b18Alan Viverette
277c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
278c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * <p>Create a new, empty, non focusable popup window of dimension (0,0).</p>
2795435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
280c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * <p>The popup does not provide a background.</p>
281c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
282c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext = context;
28475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
286617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        final TypedArray a = context.obtainStyledAttributes(
287ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                attrs, R.styleable.PopupWindow, defStyleAttr, defStyleRes);
288ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        final Drawable bg = a.getDrawable(R.styleable.PopupWindow_popupBackground);
289ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        mElevation = a.getDimension(R.styleable.PopupWindow_popupElevation, 0);
290560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        mOverlapAnchor = a.getBoolean(R.styleable.PopupWindow_overlapAnchor, false);
291c3808b5dc7d5873d04e8a0a247b179b2757764baAdam Powell
2925435a30ae552391f14009c4459731ae149675b18Alan Viverette        // Preserve default behavior from Gingerbread. If the animation is
2935435a30ae552391f14009c4459731ae149675b18Alan Viverette        // undefined or explicitly specifies the Gingerbread animation style,
2945435a30ae552391f14009c4459731ae149675b18Alan Viverette        // use a sentinel value.
2955435a30ae552391f14009c4459731ae149675b18Alan Viverette        if (a.hasValueOrEmpty(R.styleable.PopupWindow_popupAnimationStyle)) {
2965435a30ae552391f14009c4459731ae149675b18Alan Viverette            final int animStyle = a.getResourceId(R.styleable.PopupWindow_popupAnimationStyle, 0);
2975435a30ae552391f14009c4459731ae149675b18Alan Viverette            if (animStyle == R.style.Animation_PopupWindow) {
2985435a30ae552391f14009c4459731ae149675b18Alan Viverette                mAnimationStyle = ANIMATION_STYLE_DEFAULT;
2995435a30ae552391f14009c4459731ae149675b18Alan Viverette            } else {
3005435a30ae552391f14009c4459731ae149675b18Alan Viverette                mAnimationStyle = animStyle;
3015435a30ae552391f14009c4459731ae149675b18Alan Viverette            }
3025435a30ae552391f14009c4459731ae149675b18Alan Viverette        } else {
3035435a30ae552391f14009c4459731ae149675b18Alan Viverette            mAnimationStyle = ANIMATION_STYLE_DEFAULT;
3045435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
3055435a30ae552391f14009c4459731ae149675b18Alan Viverette
3065435a30ae552391f14009c4459731ae149675b18Alan Viverette        final Transition enterTransition = getTransition(a.getResourceId(
3075435a30ae552391f14009c4459731ae149675b18Alan Viverette                R.styleable.PopupWindow_popupEnterTransition, 0));
3085435a30ae552391f14009c4459731ae149675b18Alan Viverette        final Transition exitTransition;
3095435a30ae552391f14009c4459731ae149675b18Alan Viverette        if (a.hasValueOrEmpty(R.styleable.PopupWindow_popupExitTransition)) {
3105435a30ae552391f14009c4459731ae149675b18Alan Viverette            exitTransition = getTransition(a.getResourceId(
3115435a30ae552391f14009c4459731ae149675b18Alan Viverette                    R.styleable.PopupWindow_popupExitTransition, 0));
3125435a30ae552391f14009c4459731ae149675b18Alan Viverette        } else {
3135435a30ae552391f14009c4459731ae149675b18Alan Viverette            exitTransition = enterTransition == null ? null : enterTransition.clone();
3145435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        a.recycle();
317ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette
3185435a30ae552391f14009c4459731ae149675b18Alan Viverette        setEnterTransition(enterTransition);
3195435a30ae552391f14009c4459731ae149675b18Alan Viverette        setExitTransition(exitTransition);
320ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        setBackgroundDrawable(bg);
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window of dimension (0,0).</p>
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow() {
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(null, 0, 0);
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new non focusable popup window which can display the
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <tt>contentView</tt>. The dimension of the window are (0,0).</p>
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param contentView the popup's content
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(View contentView) {
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(contentView, 0, 0);
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window. The dimension of the
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window must be passed to this constructor.</p>
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width the popup's width
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height the popup's height
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(int width, int height) {
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(null, width, height);
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new non focusable popup window which can display the
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <tt>contentView</tt>. The dimension of the window must be passed to
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this constructor.</p>
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param contentView the popup's content
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width the popup's width
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height the popup's height
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(View contentView, int width, int height) {
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(contentView, width, height, false);
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new popup window which can display the <tt>contentView</tt>.
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The dimension of the window must be passed to this constructor.</p>
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param contentView the popup's content
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width the popup's width
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height the popup's height
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param focusable true if the popup can be focused, false otherwise
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
388448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy    public PopupWindow(View contentView, int width, int height, boolean focusable) {
389448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        if (contentView != null) {
390448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy            mContext = contentView.getContext();
391448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy            mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
392448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        }
393393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setContentView(contentView);
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setWidth(width);
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setHeight(height);
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setFocusable(focusable);
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4001e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    /**
4011e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * Sets the enter transition to be used when the popup window is shown.
4021e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     *
4031e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @param enterTransition the enter transition, or {@code null} to clear
4041e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @see #getEnterTransition()
4051e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @attr ref android.R.styleable#PopupWindow_popupEnterTransition
4061e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     */
4071e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    public void setEnterTransition(@Nullable Transition enterTransition) {
4085435a30ae552391f14009c4459731ae149675b18Alan Viverette        mEnterTransition = enterTransition;
4095435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
4105435a30ae552391f14009c4459731ae149675b18Alan Viverette
4111e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    /**
4121e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * Returns the enter transition to be used when the popup window is shown.
4131e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     *
4141e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @return the enter transition, or {@code null} if not set
4151e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @see #setEnterTransition(Transition)
4161e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @attr ref android.R.styleable#PopupWindow_popupEnterTransition
4171e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     */
4181e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    @Nullable
4191e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    public Transition getEnterTransition() {
4201e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette        return mEnterTransition;
4211e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    }
4221e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette
4231e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    /**
4241e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * Sets the exit transition to be used when the popup window is dismissed.
4251e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     *
4261e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @param exitTransition the exit transition, or {@code null} to clear
4271e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @see #getExitTransition()
4281e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @attr ref android.R.styleable#PopupWindow_popupExitTransition
4291e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     */
4301e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    public void setExitTransition(@Nullable Transition exitTransition) {
4315435a30ae552391f14009c4459731ae149675b18Alan Viverette        mExitTransition = exitTransition;
4325435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
4335435a30ae552391f14009c4459731ae149675b18Alan Viverette
43491098574f90277128415e9593cce1e495cc51465Alan Viverette    /**
4351e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * Returns the exit transition to be used when the popup window is
4361e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * dismissed.
4371e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     *
4381e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @return the exit transition, or {@code null} if not set
4391e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @see #setExitTransition(Transition)
4401e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @attr ref android.R.styleable#PopupWindow_popupExitTransition
4411e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     */
4421e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    @Nullable
4431e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    public Transition getExitTransition() {
4441e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette        return mExitTransition;
4451e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    }
4461e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette
4471e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    /**
44891098574f90277128415e9593cce1e495cc51465Alan Viverette     * Sets the bounds used as the epicenter of the enter and exit transitions.
44991098574f90277128415e9593cce1e495cc51465Alan Viverette     * <p>
45091098574f90277128415e9593cce1e495cc51465Alan Viverette     * Transitions use a point or Rect, referred to as the epicenter, to orient
45191098574f90277128415e9593cce1e495cc51465Alan Viverette     * the direction of travel. For popup windows, the anchor view bounds are
45291098574f90277128415e9593cce1e495cc51465Alan Viverette     * used as the default epicenter.
45391098574f90277128415e9593cce1e495cc51465Alan Viverette     * <p>
45491098574f90277128415e9593cce1e495cc51465Alan Viverette     * See {@link Transition#setEpicenterCallback(EpicenterCallback)} for more
45591098574f90277128415e9593cce1e495cc51465Alan Viverette     * information about how transition epicenters.
45691098574f90277128415e9593cce1e495cc51465Alan Viverette     *
45791098574f90277128415e9593cce1e495cc51465Alan Viverette     * @param bounds the epicenter bounds relative to the anchor view, or
45891098574f90277128415e9593cce1e495cc51465Alan Viverette     *               {@code null} to use the default epicenter
45991098574f90277128415e9593cce1e495cc51465Alan Viverette     * @see #getTransitionEpicenter()
46091098574f90277128415e9593cce1e495cc51465Alan Viverette     * @hide
46191098574f90277128415e9593cce1e495cc51465Alan Viverette     */
46291098574f90277128415e9593cce1e495cc51465Alan Viverette    public void setEpicenterBounds(Rect bounds) {
46391098574f90277128415e9593cce1e495cc51465Alan Viverette        mEpicenterBounds = bounds;
46491098574f90277128415e9593cce1e495cc51465Alan Viverette    }
46591098574f90277128415e9593cce1e495cc51465Alan Viverette
4665435a30ae552391f14009c4459731ae149675b18Alan Viverette    private Transition getTransition(int resId) {
4675435a30ae552391f14009c4459731ae149675b18Alan Viverette        if (resId != 0 && resId != R.transition.no_transition) {
4685435a30ae552391f14009c4459731ae149675b18Alan Viverette            final TransitionInflater inflater = TransitionInflater.from(mContext);
4695435a30ae552391f14009c4459731ae149675b18Alan Viverette            final Transition transition = inflater.inflateTransition(resId);
4705435a30ae552391f14009c4459731ae149675b18Alan Viverette            if (transition != null) {
4715435a30ae552391f14009c4459731ae149675b18Alan Viverette                final boolean isEmpty = transition instanceof TransitionSet
4725435a30ae552391f14009c4459731ae149675b18Alan Viverette                        && ((TransitionSet) transition).getTransitionCount() == 0;
4735435a30ae552391f14009c4459731ae149675b18Alan Viverette                if (!isEmpty) {
4745435a30ae552391f14009c4459731ae149675b18Alan Viverette                    return transition;
4755435a30ae552391f14009c4459731ae149675b18Alan Viverette                }
4765435a30ae552391f14009c4459731ae149675b18Alan Viverette            }
4775435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
4785435a30ae552391f14009c4459731ae149675b18Alan Viverette        return null;
4795435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
4805435a30ae552391f14009c4459731ae149675b18Alan Viverette
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
482ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * Return the drawable used as the popup window's background.
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
484ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @return the background drawable or {@code null} if not set
485ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @see #setBackgroundDrawable(Drawable)
486ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @attr ref android.R.styleable#PopupWindow_popupBackground
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Drawable getBackground() {
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mBackground;
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
493ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * Specifies the background drawable for this popup window. The background
494ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * can be set to {@code null}.
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param background the popup's background
497ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @see #getBackground()
498ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @attr ref android.R.styleable#PopupWindow_popupBackground
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setBackgroundDrawable(Drawable background) {
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBackground = background;
502ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette
503ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // If this is a StateListDrawable, try to find and store the drawable to be
504ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // used when the drop-down is placed above its anchor view, and the one to be
505ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // used when the drop-down is placed below its anchor view. We extract
506ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // the drawables ourselves to work around a problem with using refreshDrawableState
507ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // that it will take into account the padding of all drawables specified in a
508ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // StateListDrawable, thus adding superfluous padding to drop-down views.
509ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        //
510ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // We assume a StateListDrawable will have a drawable for ABOVE_ANCHOR_STATE_SET and
511ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // at least one other drawable, intended for the 'below-anchor state'.
512ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        if (mBackground instanceof StateListDrawable) {
513ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            StateListDrawable stateList = (StateListDrawable) mBackground;
514ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette
515ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            // Find the above-anchor view - this one's easy, it should be labeled as such.
516ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            int aboveAnchorStateIndex = stateList.getStateDrawableIndex(ABOVE_ANCHOR_STATE_SET);
517ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette
518ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            // Now, for the below-anchor view, look for any other drawable specified in the
519ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            // StateListDrawable which is not for the above-anchor state and use that.
520ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            int count = stateList.getStateCount();
521ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            int belowAnchorStateIndex = -1;
522ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            for (int i = 0; i < count; i++) {
523ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                if (i != aboveAnchorStateIndex) {
524ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                    belowAnchorStateIndex = i;
525ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                    break;
526ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                }
527ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            }
528ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette
529ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            // Store the drawables we found, if we found them. Otherwise, set them both
530ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            // to null so that we'll just use refreshDrawableState.
531ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            if (aboveAnchorStateIndex != -1 && belowAnchorStateIndex != -1) {
532ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                mAboveAnchorBackgroundDrawable = stateList.getStateDrawable(aboveAnchorStateIndex);
533ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                mBelowAnchorBackgroundDrawable = stateList.getStateDrawable(belowAnchorStateIndex);
534ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            } else {
535ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                mBelowAnchorBackgroundDrawable = null;
536ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                mAboveAnchorBackgroundDrawable = null;
537ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            }
538ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        }
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
542ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @return the elevation for this popup window in pixels
543ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @see #setElevation(float)
544ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @attr ref android.R.styleable#PopupWindow_popupElevation
545ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     */
546ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    public float getElevation() {
547ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        return mElevation;
548ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    }
549ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
550ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    /**
551ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * Specifies the elevation for this popup window.
552ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     *
553ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @param elevation the popup's elevation in pixels
554ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @see #getElevation()
555ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @attr ref android.R.styleable#PopupWindow_popupElevation
556ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     */
557ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    public void setElevation(float elevation) {
558ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        mElevation = elevation;
559ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    }
560ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
561ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    /**
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Return the animation style to use the popup appears and disappears</p>
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the animation style to use the popup appears and disappears
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getAnimationStyle() {
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mAnimationStyle;
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
569393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
57154ec76d81ac38284caa6d00ad5f2d2207206b9ceShuhrat Dehkanov     * Set the flag on popup to ignore cheek press events; by default this flag
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is set to false
57354ec76d81ac38284caa6d00ad5f2d2207206b9ceShuhrat Dehkanov     * which means the popup will not ignore cheek press dispatch events.
5745435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
578393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setIgnoreCheekPress() {
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIgnoreCheekPress = true;
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5845435a30ae552391f14009c4459731ae149675b18Alan Viverette
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Change the animation style resource for this popup.</p>
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param animationStyle animation style to use when the popup appears
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *      and disappears.  Set to -1 for the default animation, 0 for no
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *      animation, or a resource identifier for an explicit animation.
5965435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setAnimationStyle(int animationStyle) {
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAnimationStyle = animationStyle;
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6025435a30ae552391f14009c4459731ae149675b18Alan Viverette
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Return the view used as the content of the popup window.</p>
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a {@link android.view.View} representing the popup's content
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setContentView(android.view.View)
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View getContentView() {
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mContentView;
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Change the popup's content. The content is represented by an instance
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of {@link android.view.View}.</p>
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
61881f08086b44a117097960195d2c9072e29644962Gilles Debunne     * <p>This method has no effect if called when the popup is showing.</p>
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param contentView the new content for the popup
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getContentView()
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isShowing()
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setContentView(View contentView) {
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isShowing()) {
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContentView = contentView;
631448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy
6320c0b768e1514280812321854db6dfba723c3d169Romain Guy        if (mContext == null && mContentView != null) {
633448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy            mContext = mContentView.getContext();
634448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        }
635448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy
6360c0b768e1514280812321854db6dfba723c3d169Romain Guy        if (mWindowManager == null && mContentView != null) {
637448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy            mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
638448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        }
639393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
640393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        // Setting the default for attachedInDecor based on SDK version here
641393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        // instead of in the constructor since we might not have the context
642393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        // object in the constructor. We only want to set default here if the
643393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        // app hasn't already set the attachedInDecor.
644393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        if (mContext != null && !mAttachedInDecorSet) {
645393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale            // Attach popup window in decor frame of parent window by default for
646393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale            // {@link Build.VERSION_CODES.LOLLIPOP_MR1} or greater. Keep current
647393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale            // behavior of not attaching to decor frame for older SDKs.
648393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale            setAttachedInDecor(mContext.getApplicationInfo().targetSdkVersion
649393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale                    >= Build.VERSION_CODES.LOLLIPOP_MR1);
650393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        }
651393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set a callback for all touch events being dispatched to the popup
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window.
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setTouchInterceptor(OnTouchListener l) {
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTouchInterceptor = l;
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
661393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicate whether the popup window can grab the focus.</p>
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is focusable, false otherwise
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setFocusable(boolean)
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isFocusable() {
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mFocusable;
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Changes the focusability of the popup window. When focusable, the
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window will grab the focus from the current focused widget if the popup
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * contains a focusable {@link android.view.View}.  By default a popup
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window is not focusable.</p>
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param focusable true if the popup should grab focus, false otherwise.
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isFocusable()
6865435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #isShowing()
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setFocusable(boolean focusable) {
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFocusable = focusable;
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the current value in {@link #setInputMethodMode(int)}.
6955435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setInputMethodMode(int)
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getInputMethodMode() {
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mInputMethodMode;
7005435a30ae552391f14009c4459731ae149675b18Alan Viverette
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7025435a30ae552391f14009c4459731ae149675b18Alan Viverette
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Control how the popup operates with an input method: one of
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #INPUT_METHOD_FROM_FOCUSABLE}, {@link #INPUT_METHOD_NEEDED},
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or {@link #INPUT_METHOD_NOT_NEEDED}.
7075435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
7115435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getInputMethodMode()
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setInputMethodMode(int mode) {
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputMethodMode = mode;
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
718374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy
719374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy    /**
720374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * Sets the operating mode for the soft input area.
721374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     *
722374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * @param mode The desired mode, see
723374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     *        {@link android.view.WindowManager.LayoutParams#softInputMode}
724374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     *        for the full list
725374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     *
726374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * @see android.view.WindowManager.LayoutParams#softInputMode
727374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * @see #getSoftInputMode()
728374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     */
72922dac1c8df4ec212e8195a69d2de15d313d724fbYohei Yukawa    public void setSoftInputMode(@SoftInputModeFlags int mode) {
730374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy        mSoftInputMode = mode;
731374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy    }
732374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy
733374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy    /**
734374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * Returns the current value in {@link #setSoftInputMode(int)}.
735374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     *
736374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * @see #setSoftInputMode(int)
737374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * @see android.view.WindowManager.LayoutParams#softInputMode
738374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     */
73922dac1c8df4ec212e8195a69d2de15d313d724fbYohei Yukawa    @SoftInputModeFlags
740374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy    public int getSoftInputMode() {
741374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy        return mSoftInputMode;
742374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy    }
7435435a30ae552391f14009c4459731ae149675b18Alan Viverette
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicates whether the popup window receives touch events.</p>
7465435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is touchable, false otherwise
7485435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setTouchable(boolean)
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isTouchable() {
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mTouchable;
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Changes the touchability of the popup window. When touchable, the
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window will receive touch events, otherwise touch events will go to the
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window below it. By default the window is touchable.</p>
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param touchable true if the popup should receive touch events, false otherwise
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isTouchable()
7675435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #isShowing()
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setTouchable(boolean touchable) {
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTouchable = touchable;
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicates whether the popup window will be informed of touch events
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * outside of its window.</p>
7775435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is outside touchable, false otherwise
7795435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setOutsideTouchable(boolean)
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isOutsideTouchable() {
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mOutsideTouchable;
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Controls whether the pop-up will be informed of touch events outside
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of its window.  This only makes sense for pop-ups that are touchable
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * but not focusable, which means touches outside of the window will
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be delivered to the window behind.  The default is false.</p>
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param touchable true if the popup should receive outside
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * touch events, false otherwise
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isOutsideTouchable()
8005435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #isShowing()
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setOutsideTouchable(boolean touchable) {
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOutsideTouchable = touchable;
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicates whether clipping of the popup window is enabled.</p>
8095435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the clipping is enabled, false otherwise
8115435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setClippingEnabled(boolean)
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isClippingEnabled() {
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mClippingEnabled;
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Allows the popup window to extend beyond the bounds of the screen. By default the
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window is clipped to the screen boundaries. Setting this to false will allow windows to be
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * accurately positioned.</p>
8225435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param enabled false if the window should be allowed to extend outside of the screen
8285435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #isShowing()
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isClippingEnabled()
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setClippingEnabled(boolean enabled) {
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mClippingEnabled = enabled;
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
83756c2d337e02a275397fc9d0460dca90977f199acAdam Powell     * Clip this popup window to the screen, but not to the containing window.
83856c2d337e02a275397fc9d0460dca90977f199acAdam Powell     *
83956c2d337e02a275397fc9d0460dca90977f199acAdam Powell     * @param enabled True to clip to the screen.
84056c2d337e02a275397fc9d0460dca90977f199acAdam Powell     * @hide
84156c2d337e02a275397fc9d0460dca90977f199acAdam Powell     */
84256c2d337e02a275397fc9d0460dca90977f199acAdam Powell    public void setClipToScreenEnabled(boolean enabled) {
84356c2d337e02a275397fc9d0460dca90977f199acAdam Powell        mClipToScreen = enabled;
84456c2d337e02a275397fc9d0460dca90977f199acAdam Powell    }
845348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell
846348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell    /**
847348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     * Allow PopupWindow to scroll the anchor's parent to provide more room
848348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     * for the popup. Enabled by default.
849348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     *
850348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     * @param enabled True to scroll the anchor's parent when more room is desired by the popup.
851348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     */
852348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell    void setAllowScrollingAnchorParent(boolean enabled) {
853348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell        mAllowScrollingAnchorParent = enabled;
854348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell    }
8555435a30ae552391f14009c4459731ae149675b18Alan Viverette
85656c2d337e02a275397fc9d0460dca90977f199acAdam Powell    /**
85701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * <p>Indicates whether the popup window supports splitting touches.</p>
8585435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
85901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * @return true if the touch splitting is enabled, false otherwise
8605435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
86101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * @see #setSplitTouchEnabled(boolean)
86201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     */
86301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    public boolean isSplitTouchEnabled() {
86446e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown        if (mSplitTouchEnabled < 0 && mContext != null) {
86546e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown            return mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB;
86646e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown        }
86746e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown        return mSplitTouchEnabled == 1;
86801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
86901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
87001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    /**
87101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * <p>Allows the popup window to split touches across other windows that also
87246e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown     * support split touch.  When this flag is false, the first pointer
87301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * that goes down determines the window to which all subsequent touches
87446e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown     * go until all pointers go up.  When this flag is true, each pointer
87501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * (not necessarily the first) that goes down determines the window
87601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * to which all subsequent touches of that pointer will go until that
87701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * pointer goes up thereby enabling touches with multiple pointers
87801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * to be split across multiple windows.</p>
87901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     *
88001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * @param enabled true if the split touches should be enabled, false otherwise
88101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * @see #isSplitTouchEnabled()
88201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     */
88301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    public void setSplitTouchEnabled(boolean enabled) {
88446e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown        mSplitTouchEnabled = enabled ? 1 : 0;
88501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
88601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
88701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    /**
888ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * <p>Indicates whether the popup window will be forced into using absolute screen coordinates
889ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * for positioning.</p>
890ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     *
891ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * @return true if the window will always be positioned in screen coordinates.
892ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * @hide
893ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     */
894ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    public boolean isLayoutInScreenEnabled() {
895ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell        return mLayoutInScreen;
896ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    }
897ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell
898ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    /**
899ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * <p>Allows the popup window to force the flag
900ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * {@link WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN}, overriding default behavior.
901ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * This will cause the popup to be positioned in absolute screen coordinates.</p>
902ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     *
903ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * @param enabled true if the popup should always be positioned in screen coordinates
904ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * @hide
905ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     */
906ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    public void setLayoutInScreenEnabled(boolean enabled) {
907ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell        mLayoutInScreen = enabled;
908ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    }
909ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell
910ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    /**
911393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * <p>Indicates whether the popup window will be attached in the decor frame of its parent
912393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * window.
913393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
914393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * @return true if the window will be attached to the decor frame of its parent window.
915393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
916393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * @see #setAttachedInDecor(boolean)
917393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR
918393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     */
919393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    public boolean isAttachedInDecor() {
920393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        return mAttachedInDecor;
921393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    }
922393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
923393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    /**
924393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * <p>This will attach the popup window to the decor frame of the parent window to avoid
925393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * overlaping with screen decorations like the navigation bar. Overrides the default behavior of
926393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * the flag {@link WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR}.
927393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
928393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * <p>By default the flag is set on SDK version {@link Build.VERSION_CODES#LOLLIPOP_MR1} or
929393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * greater and cleared on lesser SDK versions.
930393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
931393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * @param enabled true if the popup should be attached to the decor frame of its parent window.
932393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
933393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR
934393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     */
935393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    public void setAttachedInDecor(boolean enabled) {
936393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        mAttachedInDecor = enabled;
937393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        mAttachedInDecorSet = true;
938393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    }
939393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
940393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    /**
9410bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * Allows the popup window to force the flag
9420bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * {@link WindowManager.LayoutParams#FLAG_LAYOUT_INSET_DECOR}, overriding default behavior.
9430bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * This will cause the popup to inset its content to account for system windows overlaying
9440bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * the screen, such as the status bar.
9450bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     *
9460bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * <p>This will often be combined with {@link #setLayoutInScreenEnabled(boolean)}.
9470bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     *
9480bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * @param enabled true if the popup's views should inset content to account for system windows,
9490bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     *                the way that decor views behave for full-screen windows.
9500bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * @hide
9510bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     */
9520bd1d0a15294345bf88b20df28466907f982cec7Adam Powell    public void setLayoutInsetDecor(boolean enabled) {
9530bd1d0a15294345bf88b20df28466907f982cec7Adam Powell        mLayoutInsetDecor = enabled;
9540bd1d0a15294345bf88b20df28466907f982cec7Adam Powell    }
9550bd1d0a15294345bf88b20df28466907f982cec7Adam Powell
9560bd1d0a15294345bf88b20df28466907f982cec7Adam Powell    /**
95780ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette     * Set the layout type for this window.
95880ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette     * <p>
95980ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette     * See {@link WindowManager.LayoutParams#type} for possible values.
960574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell     *
961574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell     * @param layoutType Layout type for this window.
96236344a90c226c90243e4e02bfb13589e120431ddChris Banes     *
96336344a90c226c90243e4e02bfb13589e120431ddChris Banes     * @see WindowManager.LayoutParams#type
964574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell     */
965574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    public void setWindowLayoutType(int layoutType) {
966574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell        mWindowLayoutType = layoutType;
967574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    }
968574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell
969574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    /**
97036344a90c226c90243e4e02bfb13589e120431ddChris Banes     * Returns the layout type for this window.
97136344a90c226c90243e4e02bfb13589e120431ddChris Banes     *
97236344a90c226c90243e4e02bfb13589e120431ddChris Banes     * @see #setWindowLayoutType(int)
973574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell     */
974574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    public int getWindowLayoutType() {
975574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell        return mWindowLayoutType;
976574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    }
977574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell
978574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    /**
979e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell     * Set whether this window is touch modal or if outside touches will be sent to
980e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell     * other windows behind it.
981e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell     * @hide
982e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell     */
983e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell    public void setTouchModal(boolean touchModal) {
984e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell        mNotTouchModal = !touchModal;
985e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell    }
986e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell
987e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell    /**
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Change the width and height measure specs that are given to the
9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window manager by the popup.  By default these are 0, meaning that
9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the current width or height is requested as an explicit size from
9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the window manager.  You can supply
9925435a30ae552391f14009c4459731ae149675b18Alan Viverette     * {@link ViewGroup.LayoutParams#WRAP_CONTENT} or
993980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy     * {@link ViewGroup.LayoutParams#MATCH_PARENT} to have that measure
9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * spec supplied instead, replacing the absolute width and height that
9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * has been set in the popup.</p>
9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown.</p>
9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param widthSpec an explicit width measure spec mode, either
10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ViewGroup.LayoutParams#WRAP_CONTENT},
1002980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy     * {@link ViewGroup.LayoutParams#MATCH_PARENT}, or 0 to use the absolute
10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * width.
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param heightSpec an explicit height measure spec mode, either
10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ViewGroup.LayoutParams#WRAP_CONTENT},
1006980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy     * {@link ViewGroup.LayoutParams#MATCH_PARENT}, or 0 to use the absolute
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * height.
1008259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *
1009259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @deprecated Use {@link #setWidth(int)} and {@link #setHeight(int)}.
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1011259c2840691a79634ffd8f63291ec21c21819542Alan Viverette    @Deprecated
10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setWindowLayoutMode(int widthSpec, int heightSpec) {
10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWidthMode = widthSpec;
10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHeightMode = heightSpec;
10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10165435a30ae552391f14009c4459731ae149675b18Alan Viverette
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1018c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * Returns the popup's requested height. May be a layout constant such as
1019c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * {@link LayoutParams#WRAP_CONTENT} or {@link LayoutParams#MATCH_PARENT}.
1020c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * <p>
1021c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * The actual size of the popup may depend on other factors such as
1022c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * clipping and window layout.
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1024c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @return the popup height in pixels or a layout constant
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setHeight(int)
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getHeight() {
10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mHeight;
10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1032c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * Sets the popup's requested height. May be a layout constant such as
1033c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * {@link LayoutParams#WRAP_CONTENT} or {@link LayoutParams#MATCH_PARENT}.
1034c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * <p>
1035c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * The actual size of the popup may depend on other factors such as
1036c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * clipping and window layout.
1037259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
1038259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * If the popup is showing, calling this method will take effect the next
1039259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * time the popup is shown.
10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1041c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param height the popup height in pixels or a layout constant
10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getHeight()
10435435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #isShowing()
10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setHeight(int height) {
10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHeight = height;
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1050c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * Returns the popup's requested width. May be a layout constant such as
1051c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * {@link LayoutParams#WRAP_CONTENT} or {@link LayoutParams#MATCH_PARENT}.
1052c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * <p>
1053c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * The actual size of the popup may depend on other factors such as
1054c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * clipping and window layout.
10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1056c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @return the popup width in pixels or a layout constant
10575435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #setWidth(int)
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getWidth() {
10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mWidth;
10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1064c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * Sets the popup's requested width. May be a layout constant such as
1065c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * {@link LayoutParams#WRAP_CONTENT} or {@link LayoutParams#MATCH_PARENT}.
1066c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * <p>
1067c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * The actual size of the popup may depend on other factors such as
1068c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * clipping and window layout.
1069259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
1070259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * If the popup is showing, calling this method will take effect the next
1071259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * time the popup is shown.
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1073c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param width the popup width in pixels or a layout constant
10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getWidth()
10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isShowing()
10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setWidth(int width) {
10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWidth = width;
10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
108275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * Sets whether the popup window should overlap its anchor view when
108375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * displayed as a drop-down.
108475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * <p>
108575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * If the popup is showing, calling this method will take effect only
108675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * the next time the popup is shown.
108775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     *
108875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * @param overlapAnchor Whether the popup should overlap its anchor.
108975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     *
109075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * @see #getOverlapAnchor()
109175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * @see #isShowing()
109275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     */
109375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    public void setOverlapAnchor(boolean overlapAnchor) {
109475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        mOverlapAnchor = overlapAnchor;
109575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    }
109675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette
109775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    /**
109875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * Returns whether the popup window should overlap its anchor view when
109975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * displayed as a drop-down.
110075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     *
110175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * @return Whether the popup should overlap its anchor.
110275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     *
110375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * @see #setOverlapAnchor(boolean)
110475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     */
110575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    public boolean getOverlapAnchor() {
110675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        return mOverlapAnchor;
110775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    }
110875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette
110975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    /**
11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicate whether this popup window is showing on screen.</p>
11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is showing, false otherwise
11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isShowing() {
11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mIsShowing;
11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Display the content view in a popup window at the specified location. If the popup window
11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * cannot fit on screen, it will be clipped. See {@link android.view.WindowManager.LayoutParams}
11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * for more information on how gravity and the x and y parameters are related. Specifying
11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a gravity of {@link android.view.Gravity#NO_GRAVITY} is similar to specifying
11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <code>Gravity.LEFT | Gravity.TOP</code>.
11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </p>
11265435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param parent a parent view to get the {@link android.view.View#getWindowToken()} token from
11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param gravity the gravity which controls the placement of the popup window
11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x the popup's x location offset
11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y the popup's y location offset
11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void showAtLocation(View parent, int gravity, int x, int y) {
113350db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal        mParentRootView = new WeakReference<>(parent.getRootView());
11348ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell        showAtLocation(parent.getWindowToken(), gravity, x, y);
11358ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell    }
11368ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell
11378ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell    /**
11388ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * Display the content view in a popup window at the specified location.
11398ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     *
11408ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * @param token Window token to use for creating the new window
11418ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * @param gravity the gravity which controls the placement of the popup window
11428ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * @param x the popup's x location offset
11438ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * @param y the popup's y location offset
11448ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     *
11458ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * @hide Internal use only. Applications should use
11468ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     *       {@link #showAtLocation(View, int, int, int)} instead.
11478ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     */
11488ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell    public void showAtLocation(IBinder token, int gravity, int x, int y) {
11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isShowing() || mContentView == null) {
11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1153e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        TransitionManager.endTransitions(mDecorView);
1154e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
1155f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        detachFromAnchor();
11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsShowing = true;
11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsDropdown = false;
1159085160612d9066e23c96a6cac15eb3a51481fdafRobert Carr        mGravity = gravity;
11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1161e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        final WindowManager.LayoutParams p = createPopupLayoutParams(token);
11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        preparePopup(p);
1163e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.x = x;
11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.y = y;
1166e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        invokePopup(p);
11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
117175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * Display the content view in a popup window anchored to the bottom-left
11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * corner of the anchor view. If there is not enough room on screen to show
11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the popup in its entirety, this method tries to find a parent scroll
117475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * view to scroll. If no parent scroll view can be scrolled, the
117575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * bottom-left corner of the popup is pinned at the top left corner of the
117675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * anchor view.
11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the view on which to pin the popup window
11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #dismiss()
11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void showAsDropDown(View anchor) {
11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        showAsDropDown(anchor, 0, 0);
11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
118775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * Display the content view in a popup window anchored to the bottom-left
11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * corner of the anchor view offset by the specified x and y coordinates.
118975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * If there is not enough room on screen to show the popup in its entirety,
119075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * this method tries to find a parent scroll view to scroll. If no parent
119175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * scroll view can be scrolled, the bottom-left corner of the popup is
119275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * pinned at the top left corner of the anchor view.
119375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * <p>
119475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * If the view later scrolls to move <code>anchor</code> to a different
119575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * location, the popup will be moved correspondingly.
11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the view on which to pin the popup window
119854c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param xoff A horizontal offset from the anchor in pixels
119954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param yoff A vertical offset from the anchor in pixels
12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #dismiss()
12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void showAsDropDown(View anchor, int xoff, int yoff) {
120454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell        showAsDropDown(anchor, xoff, yoff, DEFAULT_ANCHORED_GRAVITY);
120554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell    }
120654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell
120754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell    /**
120875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * Displays the content view in a popup window anchored to the corner of
120975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * another view. The window is positioned according to the specified
121075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * gravity and offset by the specified x and y coordinates.
121175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * <p>
121275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * If there is not enough room on screen to show the popup in its entirety,
121375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * this method tries to find a parent scroll view to scroll. If no parent
121475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * view can be scrolled, the specified vertical gravity will be ignored and
121575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * the popup will anchor itself such that it is visible.
121675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * <p>
121775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * If the view later scrolls to move <code>anchor</code> to a different
121875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * location, the popup will be moved correspondingly.
121954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     *
122054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param anchor the view on which to pin the popup window
122154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param xoff A horizontal offset from the anchor in pixels
122254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param yoff A vertical offset from the anchor in pixels
122354c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param gravity Alignment of the popup relative to the anchor
122454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     *
122554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @see #dismiss()
122654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     */
122754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell    public void showAsDropDown(View anchor, int xoff, int yoff, int gravity) {
12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isShowing() || mContentView == null) {
12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1232e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        TransitionManager.endTransitions(mDecorView);
1233e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
1234f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        attachToAnchor(anchor, xoff, yoff, gravity);
12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsShowing = true;
12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsDropdown = true;
12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1239e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        final WindowManager.LayoutParams p = createPopupLayoutParams(anchor.getWindowToken());
12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        preparePopup(p);
12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1242f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final boolean aboveAnchor = findDropDownPosition(anchor, p, xoff, yoff,
124350df07a1add902da01018756c213169e4e126a28Alan Viverette                p.width, p.height, gravity, mAllowScrollingAnchorParent);
1244e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        updateAboveAnchor(aboveAnchor);
1245396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver        p.accessibilityIdOfAnchor = (anchor != null) ? anchor.getAccessibilityViewId() : -1;
12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        invokePopup(p);
12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12503e141685003939a9addce21ba2492ea3a8aebee6Romain Guy    private void updateAboveAnchor(boolean aboveAnchor) {
12513e141685003939a9addce21ba2492ea3a8aebee6Romain Guy        if (aboveAnchor != mAboveAnchor) {
12523e141685003939a9addce21ba2492ea3a8aebee6Romain Guy            mAboveAnchor = aboveAnchor;
12533e141685003939a9addce21ba2492ea3a8aebee6Romain Guy
1254697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette            if (mBackground != null && mBackgroundView != null) {
1255697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette                // If the background drawable provided was a StateListDrawable
1256697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette                // with above-anchor and below-anchor states, use those.
1257697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette                // Otherwise, rely on refreshDrawableState to do the job.
12583e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                if (mAboveAnchorBackgroundDrawable != null) {
12593e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                    if (mAboveAnchor) {
1260697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette                        mBackgroundView.setBackground(mAboveAnchorBackgroundDrawable);
12613e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                    } else {
1262697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette                        mBackgroundView.setBackground(mBelowAnchorBackgroundDrawable);
12633e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                    }
12643e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                } else {
1265697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette                    mBackgroundView.refreshDrawableState();
12663e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                }
12673e141685003939a9addce21ba2492ea3a8aebee6Romain Guy            }
12683e141685003939a9addce21ba2492ea3a8aebee6Romain Guy        }
12693e141685003939a9addce21ba2492ea3a8aebee6Romain Guy    }
12703e141685003939a9addce21ba2492ea3a8aebee6Romain Guy
12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Indicates whether the popup is showing above (the y coordinate of the popup's bottom
12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is less than the y coordinate of the anchor) or below the anchor view (the y coordinate
12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of the popup is greater than y coordinate of the anchor's bottom).
12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The value returned
12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by this method is meaningful only after {@link #showAsDropDown(android.view.View)}
12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or {@link #showAsDropDown(android.view.View, int, int)} was invoked.
12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return True if this popup is showing above the anchor view, false otherwise.
12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isAboveAnchor() {
12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mAboveAnchor;
12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1287e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette     * Prepare the popup by embedding it into a new ViewGroup if the background
1288e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette     * drawable is not null. If embedding is required, the layout parameters'
1289e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette     * height is modified to take into account the background's padding.
12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param p the layout parameters of the popup's content view
12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void preparePopup(WindowManager.LayoutParams p) {
1294448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        if (mContentView == null || mContext == null || mWindowManager == null) {
1295448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy            throw new IllegalStateException("You must specify a valid content view by "
1296448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy                    + "calling setContentView() before attempting to show the popup.");
1297448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        }
1298448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy
12998fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // The old decor view may be transitioning out. Make sure it finishes
13008fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // and cleans up before we try to create another one.
13018fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        if (mDecorView != null) {
13028fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            mDecorView.cancelTransitions();
13038fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
13048fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
13055435a30ae552391f14009c4459731ae149675b18Alan Viverette        // When a background is available, we embed the content view within
13065435a30ae552391f14009c4459731ae149675b18Alan Viverette        // another view that owns the background drawable.
13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBackground != null) {
1308697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette            mBackgroundView = createBackgroundView(mContentView);
1309697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette            mBackgroundView.setBackground(mBackground);
13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1311697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette            mBackgroundView = mContentView;
13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1313ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
1314697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette        mDecorView = createDecorView(mBackgroundView);
13155435a30ae552391f14009c4459731ae149675b18Alan Viverette
13165435a30ae552391f14009c4459731ae149675b18Alan Viverette        // The background owner should be elevated so that it casts a shadow.
1317697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette        mBackgroundView.setElevation(mElevation);
13185435a30ae552391f14009c4459731ae149675b18Alan Viverette
13195435a30ae552391f14009c4459731ae149675b18Alan Viverette        // We may wrap that in another view, so we'll need to manually specify
13205435a30ae552391f14009c4459731ae149675b18Alan Viverette        // the surface insets.
1321246c209e4fe704c0745224be0ab05225e8431d11Wale Ogunwale        p.setSurfaceInsets(mBackgroundView, true /*manual*/, true /*preservePrevious*/);
13225435a30ae552391f14009c4459731ae149675b18Alan Viverette
1323b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio        mPopupViewInitialLayoutDirectionInherited =
13245435a30ae552391f14009c4459731ae149675b18Alan Viverette                (mContentView.getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT);
13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
13285435a30ae552391f14009c4459731ae149675b18Alan Viverette     * Wraps a content view in a PopupViewContainer.
13295435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
13305435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @param contentView the content view to wrap
13315435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @return a PopupViewContainer that wraps the content view
13325435a30ae552391f14009c4459731ae149675b18Alan Viverette     */
13335435a30ae552391f14009c4459731ae149675b18Alan Viverette    private PopupBackgroundView createBackgroundView(View contentView) {
13345435a30ae552391f14009c4459731ae149675b18Alan Viverette        final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams();
13355435a30ae552391f14009c4459731ae149675b18Alan Viverette        final int height;
13362665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr        if (layoutParams != null && layoutParams.height == WRAP_CONTENT) {
13372665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr            height = WRAP_CONTENT;
13385435a30ae552391f14009c4459731ae149675b18Alan Viverette        } else {
13392665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr            height = MATCH_PARENT;
13405435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
13415435a30ae552391f14009c4459731ae149675b18Alan Viverette
13425435a30ae552391f14009c4459731ae149675b18Alan Viverette        final PopupBackgroundView backgroundView = new PopupBackgroundView(mContext);
13435435a30ae552391f14009c4459731ae149675b18Alan Viverette        final PopupBackgroundView.LayoutParams listParams = new PopupBackgroundView.LayoutParams(
13442665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr                MATCH_PARENT, height);
13455435a30ae552391f14009c4459731ae149675b18Alan Viverette        backgroundView.addView(contentView, listParams);
13465435a30ae552391f14009c4459731ae149675b18Alan Viverette
13475435a30ae552391f14009c4459731ae149675b18Alan Viverette        return backgroundView;
13485435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
13495435a30ae552391f14009c4459731ae149675b18Alan Viverette
13505435a30ae552391f14009c4459731ae149675b18Alan Viverette    /**
13515435a30ae552391f14009c4459731ae149675b18Alan Viverette     * Wraps a content view in a FrameLayout.
13525435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
13535435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @param contentView the content view to wrap
13545435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @return a FrameLayout that wraps the content view
13555435a30ae552391f14009c4459731ae149675b18Alan Viverette     */
13565435a30ae552391f14009c4459731ae149675b18Alan Viverette    private PopupDecorView createDecorView(View contentView) {
13575435a30ae552391f14009c4459731ae149675b18Alan Viverette        final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams();
13585435a30ae552391f14009c4459731ae149675b18Alan Viverette        final int height;
13592665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr        if (layoutParams != null && layoutParams.height == WRAP_CONTENT) {
13602665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr            height = WRAP_CONTENT;
13615435a30ae552391f14009c4459731ae149675b18Alan Viverette        } else {
13622665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr            height = MATCH_PARENT;
13635435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
13645435a30ae552391f14009c4459731ae149675b18Alan Viverette
13655435a30ae552391f14009c4459731ae149675b18Alan Viverette        final PopupDecorView decorView = new PopupDecorView(mContext);
13662665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr        decorView.addView(contentView, MATCH_PARENT, height);
13675435a30ae552391f14009c4459731ae149675b18Alan Viverette        decorView.setClipChildren(false);
13685435a30ae552391f14009c4459731ae149675b18Alan Viverette        decorView.setClipToPadding(false);
13695435a30ae552391f14009c4459731ae149675b18Alan Viverette
13705435a30ae552391f14009c4459731ae149675b18Alan Viverette        return decorView;
13715435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
13725435a30ae552391f14009c4459731ae149675b18Alan Viverette
13735435a30ae552391f14009c4459731ae149675b18Alan Viverette    /**
13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Invoke the popup window by adding the content view to the window
13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * manager.</p>
13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The content view must be non-null when this method is invoked.</p>
13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param p the layout parameters of the popup's content view
13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void invokePopup(WindowManager.LayoutParams p) {
13820c0b768e1514280812321854db6dfba723c3d169Romain Guy        if (mContext != null) {
13830c0b768e1514280812321854db6dfba723c3d169Romain Guy            p.packageName = mContext.getPackageName();
13840c0b768e1514280812321854db6dfba723c3d169Romain Guy        }
13855435a30ae552391f14009c4459731ae149675b18Alan Viverette
13868fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        final PopupDecorView decorView = mDecorView;
13878fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        decorView.setFitsSystemWindows(mLayoutInsetDecor);
13885435a30ae552391f14009c4459731ae149675b18Alan Viverette
13898fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        setLayoutDirectionFromAnchor();
13905435a30ae552391f14009c4459731ae149675b18Alan Viverette
13918fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        mWindowManager.addView(decorView, p);
139295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette
139395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        if (mEnterTransition != null) {
139495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            decorView.requestEnterTransition(mEnterTransition);
139595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        }
13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1398b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio    private void setLayoutDirectionFromAnchor() {
1399b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio        if (mAnchor != null) {
1400b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio            View anchor = mAnchor.get();
1401b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio            if (anchor != null && mPopupViewInitialLayoutDirectionInherited) {
14025435a30ae552391f14009c4459731ae149675b18Alan Viverette                mDecorView.setLayoutDirection(anchor.getLayoutDirection());
1403b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio            }
1404b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio        }
1405b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio    }
1406b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio
1407489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr    private int computeGravity() {
1408085160612d9066e23c96a6cac15eb3a51481fdafRobert Carr        int gravity = mGravity == Gravity.NO_GRAVITY ?  Gravity.START | Gravity.TOP : mGravity;
1409085160612d9066e23c96a6cac15eb3a51481fdafRobert Carr        if (mIsDropdown && (mClipToScreen || mClippingEnabled)) {
14109705fa0602290b56edc81f64bfcba38f159069b1Alan Viverette            gravity |= Gravity.DISPLAY_CLIP_VERTICAL;
1411489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr        }
1412489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr        return gravity;
1413489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr    }
1414489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr
14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Generate the layout parameters for the popup window.</p>
14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param token the window token used to bind the popup's window
14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the layout parameters to pass to the window manager
14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1422e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette    private WindowManager.LayoutParams createPopupLayoutParams(IBinder token) {
1423e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        final WindowManager.LayoutParams p = new WindowManager.LayoutParams();
1424e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
1425e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        // These gravity settings put the view at the top left corner of the
1426e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        // screen. The view is then positioned to the appropriate location by
1427e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        // setting the x and y offsets to match the anchor's bottom-left
1428e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        // corner.
1429489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr        p.gravity = computeGravity();
1430e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        p.flags = computeFlags(p.flags);
1431e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        p.type = mWindowLayoutType;
1432e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        p.token = token;
1433e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        p.softInputMode = mSoftInputMode;
1434e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        p.windowAnimations = computeAnimationResource();
1435e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBackground != null) {
14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.format = mBackground.getOpacity();
14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.format = PixelFormat.TRANSLUCENT;
14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1441e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
1442e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        if (mHeightMode < 0) {
1443e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            p.height = mLastHeight = mHeightMode;
1444e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        } else {
1445e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            p.height = mLastHeight = mHeight;
1446e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        }
1447e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
1448e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        if (mWidthMode < 0) {
1449e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            p.width = mLastWidth = mWidthMode;
1450e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        } else {
1451e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            p.width = mLastWidth = mWidth;
1452e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        }
1453e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
14548216eb2221ad5ad6615d3966f43844268756f3c8Wale Ogunwale        p.privateFlags = PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH
14558216eb2221ad5ad6615d3966f43844268756f3c8Wale Ogunwale                | PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME;
1456a1eb439eee65138280c560f96e2a6896f9c9112cRobert Carr
1457e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        // Used for debugging.
14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.setTitle("PopupWindow:" + Integer.toHexString(hashCode()));
14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return p;
14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int computeFlags(int curFlags) {
14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        curFlags &= ~(
14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES |
14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |
1470ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell                WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
1471ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell                WindowManager.LayoutParams.FLAG_SPLIT_TOUCH);
14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if(mIgnoreCheekPress) {
14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES;
14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mFocusable) {
14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mInputMethodMode == INPUT_METHOD_NEEDED) {
14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (mInputMethodMode == INPUT_METHOD_NOT_NEEDED) {
14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mTouchable) {
14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1486c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project        if (mOutsideTouchable) {
14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1489cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr        if (!mClippingEnabled || mClipToScreen) {
14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
149246e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown        if (isSplitTouchEnabled()) {
149301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            curFlags |= WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
149401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        }
1495ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell        if (mLayoutInScreen) {
1496ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell            curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
1497ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell        }
14980bd1d0a15294345bf88b20df28466907f982cec7Adam Powell        if (mLayoutInsetDecor) {
14990bd1d0a15294345bf88b20df28466907f982cec7Adam Powell            curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
15000bd1d0a15294345bf88b20df28466907f982cec7Adam Powell        }
1501e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell        if (mNotTouchModal) {
1502e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell            curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
1503e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell        }
1504393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        if (mAttachedInDecor) {
1505393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale          curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR;
1506393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        }
15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return curFlags;
15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1509393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int computeAnimationResource() {
15115435a30ae552391f14009c4459731ae149675b18Alan Viverette        if (mAnimationStyle == ANIMATION_STYLE_DEFAULT) {
15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mIsDropdown) {
15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return mAboveAnchor
15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ? com.android.internal.R.style.Animation_DropDownUp
15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        : com.android.internal.R.style.Animation_DropDownDown;
15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mAnimationStyle;
15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1521560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1523560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * Positions the popup window on screen. When the popup window is too tall
1524560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * to fit under the anchor, a parent scroll view is seeked and scrolled up
1525560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * to reclaim space. If scrolling is not possible or not enough, the popup
1526560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * window gets moved on top of the anchor.
1527560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * <p>
1528f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette     * The results of positioning are placed in {@code outParams}.
15295435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the view on which the popup window must be anchored
1531f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette     * @param outParams the layout parameters used to display the drop down
15329125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette     * @param xOffset absolute horizontal offset from the left of the anchor
15336acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette     * @param yOffset absolute vertical offset from the top of the anchor
1534560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * @param gravity horizontal gravity specifying popup alignment
153550df07a1add902da01018756c213169e4e126a28Alan Viverette     * @param allowScroll whether the anchor view's parent may be scrolled
153650df07a1add902da01018756c213169e4e126a28Alan Viverette     *                    when the popup window doesn't fit on screen
15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is translated upwards to fit on screen
15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1539f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette    private boolean findDropDownPosition(View anchor, WindowManager.LayoutParams outParams,
154050df07a1add902da01018756c213169e4e126a28Alan Viverette            int xOffset, int yOffset, int width, int height, int gravity, boolean allowScroll) {
154162e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell        final int anchorHeight = anchor.getHeight();
1542560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        final int anchorWidth = anchor.getWidth();
1543560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        if (mOverlapAnchor) {
1544f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette            yOffset -= anchorHeight;
1545560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        }
1546560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
15476acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette        // Initially, align to the bottom-left corner of the anchor plus offsets.
1548f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final int[] drawingLocation = mTmpDrawingLocation;
1549f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        anchor.getLocationInWindow(drawingLocation);
1550f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        outParams.x = drawingLocation[0] + xOffset;
1551f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        outParams.y = drawingLocation[1] + anchorHeight + yOffset;
155254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell
1553f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr        final Rect displayFrame = new Rect();
1554f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr        anchor.getWindowVisibleDisplayFrame(displayFrame);
15552665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr        if (width == MATCH_PARENT) {
1556f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr            width = displayFrame.right - displayFrame.left;
1557f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr        }
15582665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr        if (height == MATCH_PARENT) {
1559f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr            height = displayFrame.bottom - displayFrame.top;
1560f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr        }
1561f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr
1562cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr        // Let the window manager know to align the top to y.
15638367c50972ee4fce55ac483441125b8b09af5eaeRobert Carr        outParams.gravity = computeGravity();
1564cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr        outParams.width = width;
1565cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr        outParams.height = height;
1566cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr
15676acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette        // If we need to adjust for gravity RIGHT, align to the bottom-right
15686acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette        // corner of the anchor (still accounting for offsets).
1569560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        final int hgrav = Gravity.getAbsoluteGravity(gravity, anchor.getLayoutDirection())
1570560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette                & Gravity.HORIZONTAL_GRAVITY_MASK;
157154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell        if (hgrav == Gravity.RIGHT) {
1572f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette            outParams.x -= width - anchorWidth;
157354c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell        }
1574560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
1575f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final int[] screenLocation = mTmpScreenLocation;
1576f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        anchor.getLocationOnScreen(screenLocation);
157754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell
15789125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        // First, attempt to fit the popup vertically without resizing.
15799125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        final boolean fitsVertical = tryFitVertical(outParams, yOffset, height,
15809125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                anchorHeight, drawingLocation[1], screenLocation[1], displayFrame.top,
15819125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                displayFrame.bottom, false);
15829125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
15839125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        // Next, attempt to fit the popup horizontally without resizing.
15849125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        final boolean fitsHorizontal = tryFitHorizontal(outParams, xOffset, width,
15859125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                anchorWidth, drawingLocation[0], screenLocation[0], displayFrame.left,
15869125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                displayFrame.right, false);
15879125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
15889125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        // If the popup still doesn't fit, attempt to scroll the parent.
15899125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        if (!fitsVertical || !fitsHorizontal) {
15909125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            final int scrollX = anchor.getScrollX();
15919125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            final int scrollY = anchor.getScrollY();
15929125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            final Rect r = new Rect(scrollX, scrollY, scrollX + width + xOffset,
15939125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                    scrollY + height + anchorHeight + yOffset);
159450df07a1add902da01018756c213169e4e126a28Alan Viverette            if (allowScroll && anchor.requestRectangleOnScreen(r, true)) {
15959125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                // Reset for the new anchor position.
15969125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                anchor.getLocationInWindow(drawingLocation);
15979125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                outParams.x = drawingLocation[0] + xOffset;
15989125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                outParams.y = drawingLocation[1] + anchorHeight + yOffset;
15999125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
16009125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                // Preserve the gravity adjustment.
16019125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                if (hgrav == Gravity.RIGHT) {
16029125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                    outParams.x -= width - anchorWidth;
16039125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                }
1604b7c1b20c8a5a4d4378ae91b4a1f12a34100df452Adam Powell            }
16053e141685003939a9addce21ba2492ea3a8aebee6Romain Guy
16069125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            // Try to fit the popup again and allowing resizing.
16079125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            tryFitVertical(outParams, yOffset, height, anchorHeight, drawingLocation[1],
16089125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                    screenLocation[1], displayFrame.top, displayFrame.bottom, mClipToScreen);
16099125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            tryFitHorizontal(outParams, xOffset, width, anchorWidth, drawingLocation[0],
16109125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                    screenLocation[0], displayFrame.left, displayFrame.right, mClipToScreen);
16119125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        }
161254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell
16139125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        // Return whether the popup's top edge is above the anchor's top edge.
16149125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        return outParams.y < drawingLocation[1];
16159125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette    }
1616560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
16179125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette    private boolean tryFitVertical(@NonNull LayoutParams outParams, int yOffset, int height,
16189125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            int anchorHeight, int drawingLocationY, int screenLocationY, int displayFrameTop,
16199125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            int displayFrameBottom, boolean allowResize) {
162055f0a99076477b77e017454e4356d908c43c2d22Alan Viverette        final int winOffsetY = screenLocationY - drawingLocationY;
162155f0a99076477b77e017454e4356d908c43c2d22Alan Viverette        final int anchorTopInScreen = outParams.y + winOffsetY;
16229125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        final int spaceBelow = displayFrameBottom - anchorTopInScreen;
162355f0a99076477b77e017454e4356d908c43c2d22Alan Viverette        if (anchorTopInScreen >= 0 && height <= spaceBelow) {
16249125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            return true;
16259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1627b8320f7c58b46fea23e2827c82b46783b8c71b63Robert Carr        final int spaceAbove = anchorTopInScreen - anchorHeight - displayFrameTop;
16289125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        if (height <= spaceAbove) {
16299125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            // Move everything up.
16309125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            if (mOverlapAnchor) {
16319125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                yOffset += anchorHeight;
163256c2d337e02a275397fc9d0460dca90977f199acAdam Powell            }
16339125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            outParams.y = drawingLocationY - height + yOffset;
16349125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
16359125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            return true;
16369125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        }
1637560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
16389125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        if (positionInDisplayVertical(outParams, height, drawingLocationY, screenLocationY,
16399125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                displayFrameTop, displayFrameBottom, allowResize)) {
16409125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            return true;
16419125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        }
1642f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette
16439125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        return false;
16449125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette    }
164556c2d337e02a275397fc9d0460dca90977f199acAdam Powell
16469125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette    private boolean positionInDisplayVertical(@NonNull LayoutParams outParams, int height,
16479125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            int drawingLocationY, int screenLocationY, int displayFrameTop, int displayFrameBottom,
16489125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            boolean canResize) {
16499125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        boolean fitsInDisplay = true;
16506acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette
16519125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        final int winOffsetY = screenLocationY - drawingLocationY;
16529125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        outParams.y += winOffsetY;
16539125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        outParams.height = height;
16549125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
16559125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        final int bottom = outParams.y + height;
16569125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        if (bottom > displayFrameBottom) {
16579125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            // The popup is too far down, move it back in.
16589125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            outParams.y -= bottom - displayFrameBottom;
16599125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        }
16606acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette
16619125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        if (outParams.y < displayFrameTop) {
16629125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            // The popup is too far up, move it back in and clip if
16639125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            // it's still too large.
16649125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            outParams.y = displayFrameTop;
16659125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
16669125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            final int displayFrameHeight = displayFrameBottom - displayFrameTop;
16679125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            if (canResize && height > displayFrameHeight) {
16689125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                outParams.height = displayFrameHeight;
16699125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            } else {
16709125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                fitsInDisplay = false;
16715f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell            }
16729125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        }
16739125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
16749125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        outParams.y -= winOffsetY;
1675f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette
16769125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        return fitsInDisplay;
16779125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette    }
16789125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
16799125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette    private boolean tryFitHorizontal(@NonNull LayoutParams outParams, int xOffset, int width,
16809125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            int anchorWidth, int drawingLocationX, int screenLocationX, int displayFrameLeft,
16819125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            int displayFrameRight, boolean allowResize) {
168255f0a99076477b77e017454e4356d908c43c2d22Alan Viverette        final int winOffsetX = screenLocationX - drawingLocationX;
168355f0a99076477b77e017454e4356d908c43c2d22Alan Viverette        final int anchorLeftInScreen = outParams.x + winOffsetX;
16849125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        final int spaceRight = displayFrameRight - anchorLeftInScreen;
168555f0a99076477b77e017454e4356d908c43c2d22Alan Viverette        if (anchorLeftInScreen >= 0 && width <= spaceRight) {
16869125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            return true;
168756c2d337e02a275397fc9d0460dca90977f199acAdam Powell        }
168856c2d337e02a275397fc9d0460dca90977f199acAdam Powell
16899125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        if (positionInDisplayHorizontal(outParams, width, drawingLocationX, screenLocationX,
16909125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                displayFrameLeft, displayFrameRight, allowResize)) {
16919125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            return true;
16929125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        }
16939125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
16949125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        return false;
16959125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette    }
16969125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
16979125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette    private boolean positionInDisplayHorizontal(@NonNull LayoutParams outParams, int width,
16989125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            int drawingLocationX, int screenLocationX, int displayFrameLeft, int displayFrameRight,
16999125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            boolean canResize) {
17009125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        boolean fitsInDisplay = true;
17019125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
17029125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        // Use screen coordinates for comparison against display frame.
17039125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        final int winOffsetX = screenLocationX - drawingLocationX;
17049125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        outParams.x += winOffsetX;
17059125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
17069125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        final int right = outParams.x + width;
17079125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        if (right > displayFrameRight) {
17089125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            // The popup is too far right, move it back in.
17099125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            outParams.x -= right - displayFrameRight;
17109125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        }
17119125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
17129125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        if (outParams.x < displayFrameLeft) {
17139125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            // The popup is too far left, move it back in and clip if it's
17149125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            // still too large.
17159125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            outParams.x = displayFrameLeft;
17169125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
17179125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            final int displayFrameWidth = displayFrameRight - displayFrameLeft;
17189125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            if (canResize && width > displayFrameWidth) {
17199125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                outParams.width = displayFrameWidth;
17209125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            } else {
17219125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                fitsInDisplay = false;
17229125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            }
17239125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        }
17249125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
17259125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        outParams.x -= winOffsetX;
1726560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
17279125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        return fitsInDisplay;
17289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17295435a30ae552391f14009c4459731ae149675b18Alan Viverette
17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the maximum height that is available for the popup to be
17329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * completely shown. It is recommended that this height be the maximum for
17339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the popup's height, otherwise it is possible that the popup will be
17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * clipped.
17355435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
17369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor The view on which the popup window must be anchored.
17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The maximum available height for the popup to be completely
17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         shown.
17399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1740b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette    public int getMaxAvailableHeight(@NonNull View anchor) {
17419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return getMaxAvailableHeight(anchor, 0);
17429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the maximum height that is available for the popup to be
17469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * completely shown. It is recommended that this height be the maximum for
17479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the popup's height, otherwise it is possible that the popup will be
17489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * clipped.
17499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
17509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor The view on which the popup window must be anchored.
17519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param yOffset y offset from the view's bottom edge
17529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The maximum available height for the popup to be completely
17539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         shown.
17549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1755b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette    public int getMaxAvailableHeight(@NonNull View anchor, int yOffset) {
175698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau        return getMaxAvailableHeight(anchor, yOffset, false);
175798acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau    }
17585435a30ae552391f14009c4459731ae149675b18Alan Viverette
175998acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau    /**
176098acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * Returns the maximum height that is available for the popup to be
176198acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * completely shown, optionally ignoring any bottom decorations such as
176298acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * the input method. It is recommended that this height be the maximum for
176398acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * the popup's height, otherwise it is possible that the popup will be
176498acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * clipped.
17655435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
176698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * @param anchor The view on which the popup window must be anchored.
176798acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * @param yOffset y offset from the view's bottom edge
176898acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * @param ignoreBottomDecorations if true, the height returned will be
176998acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     *        all the way to the bottom of the display, ignoring any
177098acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     *        bottom decorations
177198acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * @return The maximum available height for the popup to be completely
177298acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     *         shown.
177398acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     */
1774b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette    public int getMaxAvailableHeight(
1775b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette            @NonNull View anchor, int yOffset, boolean ignoreBottomDecorations) {
1776701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr        Rect displayFrame = null;
1777701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr        final Rect visibleDisplayFrame = new Rect();
1778701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr
1779701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr        anchor.getWindowVisibleDisplayFrame(visibleDisplayFrame);
17808175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi        if (ignoreBottomDecorations) {
1781701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr            // In the ignore bottom decorations case we want to
1782701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr            // still respect all other decorations so we use the inset visible
1783701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr            // frame on the top right and left and take the bottom
1784701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr            // value from the full frame.
1785701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr            displayFrame = new Rect();
17868175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi            anchor.getWindowDisplayFrame(displayFrame);
1787701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr            displayFrame.top = visibleDisplayFrame.top;
1788701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr            displayFrame.right = visibleDisplayFrame.right;
1789701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr            displayFrame.left = visibleDisplayFrame.left;
17908175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi        } else {
1791701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr            displayFrame = visibleDisplayFrame;
17928175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi        }
17939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1794f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final int[] anchorPos = mTmpDrawingLocation;
17959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        anchor.getLocationOnScreen(anchorPos);
17965435a30ae552391f14009c4459731ae149675b18Alan Viverette
17978175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi        final int bottomEdge = displayFrame.bottom;
1798ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg
1799ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg        final int distanceToBottom;
1800ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg        if (mOverlapAnchor) {
1801ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg            distanceToBottom = bottomEdge - anchorPos[1] - yOffset;
1802ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg        } else {
1803ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg            distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset;
1804ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg        }
18059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset;
18069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // anchorPos[1] is distance from anchor to top of screen
18089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int returnedHeight = Math.max(distanceToBottom, distanceToTop);
18099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBackground != null) {
18109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mBackground.getPadding(mTempRect);
18115435a30ae552391f14009c4459731ae149675b18Alan Viverette            returnedHeight -= mTempRect.top + mTempRect.bottom;
18129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18135435a30ae552391f14009c4459731ae149675b18Alan Viverette
18149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return returnedHeight;
18159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18165435a30ae552391f14009c4459731ae149675b18Alan Viverette
18179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18187878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette     * Disposes of the popup window. This method can be invoked only after
18197878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette     * {@link #showAsDropDown(android.view.View)} has been executed. Failing
18207878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette     * that, calling this method will have no effect.
18219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18225435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #showAsDropDown(android.view.View)
18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void dismiss() {
18258fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        if (!isShowing() || mIsTransitioningToDismiss) {
1826e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            return;
1827e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        }
182806f938e8aa56cd89ab0bdb04c8b946392c428dd1Svetoslav Ganov
18298fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        final PopupDecorView decorView = mDecorView;
18308fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        final View contentView = mContentView;
18318fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
18328fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        final ViewGroup contentHolder;
18338fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        final ViewParent contentParent = contentView.getParent();
18348fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        if (contentParent instanceof ViewGroup) {
18358fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            contentHolder = ((ViewGroup) contentParent);
18368fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        } else {
18378fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            contentHolder = null;
18388fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
18398fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
18408fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // Ensure any ongoing or pending transitions are canceled.
18418fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        decorView.cancelTransitions();
18428fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
1843e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        mIsShowing = false;
18448fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        mIsTransitioningToDismiss = true;
1845b82d074038f4c8d86e1bd4f3fa4d3780bd4bcba5Craig Mautner
1846634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        // This method may be called as part of window detachment, in which
1847634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        // case the anchor view (and its root) will still return true from
1848634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        // isAttachedToWindow() during execution of this method; however, we
1849634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        // can expect the OnAttachStateChangeListener to have been called prior
1850634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        // to executing this method, so we can rely on that instead.
185195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final Transition exitTransition = mExitTransition;
1852054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette        if (exitTransition != null && decorView.isLaidOut()
1853054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette                && (mIsAnchorRootAttached || mAnchorRoot == null)) {
1854dbd299de2a07a2a0a490d4f37cf92870bf87d6c1Yohei Yukawa            // The decor view is non-interactive and non-IME-focusable during exit transitions.
185595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            final LayoutParams p = (LayoutParams) decorView.getLayoutParams();
185695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            p.flags |= LayoutParams.FLAG_NOT_TOUCHABLE;
185795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            p.flags |= LayoutParams.FLAG_NOT_FOCUSABLE;
1858dbd299de2a07a2a0a490d4f37cf92870bf87d6c1Yohei Yukawa            p.flags &= ~LayoutParams.FLAG_ALT_FOCUSABLE_IM;
185995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            mWindowManager.updateViewLayout(decorView, p);
186095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette
1861054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette            final View anchorRoot = mAnchorRoot != null ? mAnchorRoot.get() : null;
1862054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette            final Rect epicenter = getTransitionEpicenter();
1863054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette
1864634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            // Once we start dismissing the decor view, all state (including
1865634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            // the anchor root) needs to be moved to the decor view since we
1866634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            // may open another popup while it's busy exiting.
1867054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette            decorView.startExitTransition(exitTransition, anchorRoot, epicenter,
1868634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    new TransitionListenerAdapter() {
1869634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                        @Override
1870634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                        public void onTransitionEnd(Transition transition) {
18717970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette                            dismissImmediate(decorView, contentHolder, contentView);
1872634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                        }
1873634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    });
1874e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        } else {
18757970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette            dismissImmediate(decorView, contentHolder, contentView);
18767878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette        }
18777878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette
187895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        // Clears the anchor view.
1879f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        detachFromAnchor();
18807970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette
18817970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette        if (mOnDismissListener != null) {
18827970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette            mOnDismissListener.onDismiss();
18837970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette        }
18845435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
18855435a30ae552391f14009c4459731ae149675b18Alan Viverette
188691098574f90277128415e9593cce1e495cc51465Alan Viverette    /**
188791098574f90277128415e9593cce1e495cc51465Alan Viverette     * Returns the window-relative epicenter bounds to be used by enter and
188891098574f90277128415e9593cce1e495cc51465Alan Viverette     * exit transitions.
188991098574f90277128415e9593cce1e495cc51465Alan Viverette     * <p>
189091098574f90277128415e9593cce1e495cc51465Alan Viverette     * <strong>Note:</strong> This is distinct from the rect passed to
189191098574f90277128415e9593cce1e495cc51465Alan Viverette     * {@link #setEpicenterBounds(Rect)}, which is anchor-relative.
189291098574f90277128415e9593cce1e495cc51465Alan Viverette     *
189391098574f90277128415e9593cce1e495cc51465Alan Viverette     * @return the window-relative epicenter bounds to be used by enter and
189491098574f90277128415e9593cce1e495cc51465Alan Viverette     *         exit transitions
189591098574f90277128415e9593cce1e495cc51465Alan Viverette     */
189691098574f90277128415e9593cce1e495cc51465Alan Viverette    private Rect getTransitionEpicenter() {
189795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final View anchor = mAnchor != null ? mAnchor.get() : null;
189895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final View decor = mDecorView;
189995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        if (anchor == null || decor == null) {
190095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            return null;
190195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        }
190295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette
190395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final int[] anchorLocation = anchor.getLocationOnScreen();
190495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final int[] popupLocation = mDecorView.getLocationOnScreen();
190595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette
190695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        // Compute the position of the anchor relative to the popup.
190795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final Rect bounds = new Rect(0, 0, anchor.getWidth(), anchor.getHeight());
190895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        bounds.offset(anchorLocation[0] - popupLocation[0], anchorLocation[1] - popupLocation[1]);
190991098574f90277128415e9593cce1e495cc51465Alan Viverette
191091098574f90277128415e9593cce1e495cc51465Alan Viverette        // Use anchor-relative epicenter, if specified.
191191098574f90277128415e9593cce1e495cc51465Alan Viverette        if (mEpicenterBounds != null) {
191291098574f90277128415e9593cce1e495cc51465Alan Viverette            final int offsetX = bounds.left;
191391098574f90277128415e9593cce1e495cc51465Alan Viverette            final int offsetY = bounds.top;
191491098574f90277128415e9593cce1e495cc51465Alan Viverette            bounds.set(mEpicenterBounds);
191591098574f90277128415e9593cce1e495cc51465Alan Viverette            bounds.offset(offsetX, offsetY);
191691098574f90277128415e9593cce1e495cc51465Alan Viverette        }
191791098574f90277128415e9593cce1e495cc51465Alan Viverette
191895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        return bounds;
191995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette    }
192095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette
19215435a30ae552391f14009c4459731ae149675b18Alan Viverette    /**
19225435a30ae552391f14009c4459731ae149675b18Alan Viverette     * Removes the popup from the window manager and tears down the supporting
19235435a30ae552391f14009c4459731ae149675b18Alan Viverette     * view hierarchy, if necessary.
19245435a30ae552391f14009c4459731ae149675b18Alan Viverette     */
19257970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette    private void dismissImmediate(View decorView, ViewGroup contentHolder, View contentView) {
19268fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // If this method gets called and the decor view doesn't have a parent,
19278fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // then it was either never added or was already removed. That should
19288fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // never happen, but it's worth checking to avoid potential crashes.
19298fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        if (decorView.getParent() != null) {
19308fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            mWindowManager.removeViewImmediate(decorView);
1931df4639a0135ea643b493067b3f7cd1e092346c78Alan Viverette        }
1932df4639a0135ea643b493067b3f7cd1e092346c78Alan Viverette
19338fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        if (contentHolder != null) {
19348fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            contentHolder.removeView(contentView);
19359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19368fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
19378fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // This needs to stay until after all transitions have ended since we
19388fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // need the reference to cancel transitions in preparePopup().
19398fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        mDecorView = null;
1940697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette        mBackgroundView = null;
19418fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        mIsTransitioningToDismiss = false;
19429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the listener to be called when the window is dismissed.
19465435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
19479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param onDismissListener The listener.
19489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setOnDismissListener(OnDismissListener onDismissListener) {
19509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOnDismissListener = onDismissListener;
19519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19525435a30ae552391f14009c4459731ae149675b18Alan Viverette
19539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Updates the state of the popup window, if it is currently being displayed,
1955259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * from the currently set state.
1956259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
1957259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * This includes:
1958259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <ul>
1959259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setClippingEnabled(boolean)}</li>
1960259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setFocusable(boolean)}</li>
1961259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setIgnoreCheekPress()}</li>
1962259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setInputMethodMode(int)}</li>
1963259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setTouchable(boolean)}</li>
1964259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setAnimationStyle(int)}</li>
1965259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * </ul>
19669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update() {
19689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!isShowing() || mContentView == null) {
19699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
19709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19715435a30ae552391f14009c4459731ae149675b18Alan Viverette
19725435a30ae552391f14009c4459731ae149675b18Alan Viverette        final WindowManager.LayoutParams p =
19735435a30ae552391f14009c4459731ae149675b18Alan Viverette                (WindowManager.LayoutParams) mDecorView.getLayoutParams();
19745435a30ae552391f14009c4459731ae149675b18Alan Viverette
19759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean update = false;
19765435a30ae552391f14009c4459731ae149675b18Alan Viverette
19779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int newAnim = computeAnimationResource();
19789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newAnim != p.windowAnimations) {
19799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.windowAnimations = newAnim;
19809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
19819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int newFlags = computeFlags(p.flags);
19849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newFlags != p.flags) {
19859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.flags = newFlags;
19869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
19879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1988b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio
1989489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr        final int newGravity = computeGravity();
1990489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr        if (newGravity != p.gravity) {
1991489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr            p.gravity = newGravity;
1992489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr            update = true;
1993489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr        }
1994489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr
19959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (update) {
1996b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio            setLayoutDirectionFromAnchor();
19975435a30ae552391f14009c4459731ae149675b18Alan Viverette            mWindowManager.updateViewLayout(mDecorView, p);
19989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2000d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy
2001d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy    /**
2002259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Updates the dimension of the popup window.
2003259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
2004259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Calling this function also updates the window with the current popup
2005259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * state as described for {@link #update()}.
2006d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy     *
2007c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param width the new width in pixels, must be >= 0 or -1 to ignore
2008c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param height the new height in pixels, must be >= 0 or -1 to ignore
2009d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy     */
2010d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy    public void update(int width, int height) {
20115435a30ae552391f14009c4459731ae149675b18Alan Viverette        final WindowManager.LayoutParams p =
20125435a30ae552391f14009c4459731ae149675b18Alan Viverette                (WindowManager.LayoutParams) mDecorView.getLayoutParams();
2013d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy        update(p.x, p.y, width, height, false);
2014d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy    }
20155435a30ae552391f14009c4459731ae149675b18Alan Viverette
20169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2017259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Updates the position and the dimension of the popup window.
2018259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
2019259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Width and height can be set to -1 to update location only. Calling this
2020259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * function also updates the window with the current popup state as
2021259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * described for {@link #update()}.
20229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
20239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x the new x location
20249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y the new y location
2025c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param width the new width in pixels, must be >= 0 or -1 to ignore
2026c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param height the new height in pixels, must be >= 0 or -1 to ignore
20279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
20289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update(int x, int y, int width, int height) {
20299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        update(x, y, width, height, false);
20309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2033259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Updates the position and the dimension of the popup window.
2034259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
2035259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Width and height can be set to -1 to update location only. Calling this
2036259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * function also updates the window with the current popup state as
2037259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * described for {@link #update()}.
20389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
20399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x the new x location
20409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y the new y location
2041c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param width the new width in pixels, must be >= 0 or -1 to ignore
2042c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param height the new height in pixels, must be >= 0 or -1 to ignore
2043259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param force {@code true} to reposition the window even if the specified
2044259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *              position already seems to correspond to the LayoutParams,
2045259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *              {@code false} to only reposition if needed
20469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
20479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update(int x, int y, int width, int height, boolean force) {
2048259c2840691a79634ffd8f63291ec21c21819542Alan Viverette        if (width >= 0) {
20499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mLastWidth = width;
20509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setWidth(width);
20519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2053259c2840691a79634ffd8f63291ec21c21819542Alan Viverette        if (height >= 0) {
20549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mLastHeight = height;
20559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setHeight(height);
20569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!isShowing() || mContentView == null) {
20599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
20609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20625435a30ae552391f14009c4459731ae149675b18Alan Viverette        final WindowManager.LayoutParams p =
20635435a30ae552391f14009c4459731ae149675b18Alan Viverette                (WindowManager.LayoutParams) mDecorView.getLayoutParams();
20649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean update = force;
20669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int finalWidth = mWidthMode < 0 ? mWidthMode : mLastWidth;
20689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (width != -1 && p.width != finalWidth) {
20699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.width = mLastWidth = finalWidth;
20709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
20719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int finalHeight = mHeightMode < 0 ? mHeightMode : mLastHeight;
20749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (height != -1 && p.height != finalHeight) {
20759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.height = mLastHeight = finalHeight;
20769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
20779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p.x != x) {
20809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.x = x;
20819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
20829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p.y != y) {
20859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.y = y;
20869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
20879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int newAnim = computeAnimationResource();
20909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newAnim != p.windowAnimations) {
20919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.windowAnimations = newAnim;
20929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
20939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int newFlags = computeFlags(p.flags);
20969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newFlags != p.flags) {
20979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.flags = newFlags;
20989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
20999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
210098acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau
2101489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr        final int newGravity = computeGravity();
2102489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr        if (newGravity != p.gravity) {
2103489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr            p.gravity = newGravity;
2104489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr            update = true;
2105489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr        }
2106489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr
2107396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver        int newAccessibilityIdOfAnchor =
2108396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver                (mAnchor != null) ? mAnchor.get().getAccessibilityViewId() : -1;
2109396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver        if (newAccessibilityIdOfAnchor != p.accessibilityIdOfAnchor) {
2110396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver            p.accessibilityIdOfAnchor = newAccessibilityIdOfAnchor;
2111396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver            update = true;
2112396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver        }
2113396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver
21149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (update) {
2115b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio            setLayoutDirectionFromAnchor();
21165435a30ae552391f14009c4459731ae149675b18Alan Viverette            mWindowManager.updateViewLayout(mDecorView, p);
21179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2121259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Updates the position and the dimension of the popup window.
2122259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
2123259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Calling this function also updates the window with the current popup
2124259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * state as described for {@link #update()}.
21259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
21269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the popup's anchor view
2127c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param width the new width in pixels, must be >= 0 or -1 to ignore
2128c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param height the new height in pixels, must be >= 0 or -1 to ignore
21299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
21309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update(View anchor, int width, int height) {
2131b91d6d06b824aab4076fb985304a602806429042Alan Viverette        update(anchor, false, 0, 0, width, height);
21329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2135259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Updates the position and the dimension of the popup window.
2136259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
2137259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Width and height can be set to -1 to update location only. Calling this
2138259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * function also updates the window with the current popup state as
2139259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * described for {@link #update()}.
2140259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
2141259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * If the view later scrolls to move {@code anchor} to a different
2142259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * location, the popup will be moved correspondingly.
21439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
21449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the popup's anchor view
21459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param xoff x offset from the view's left edge
21469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param yoff y offset from the view's bottom edge
2147c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param width the new width in pixels, must be >= 0 or -1 to ignore
2148c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param height the new height in pixels, must be >= 0 or -1 to ignore
21499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
21509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update(View anchor, int xoff, int yoff, int width, int height) {
2151b91d6d06b824aab4076fb985304a602806429042Alan Viverette        update(anchor, true, xoff, yoff, width, height);
2152105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
2153105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
2154105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    private void update(View anchor, boolean updateLocation, int xoff, int yoff,
2155b91d6d06b824aab4076fb985304a602806429042Alan Viverette            int width, int height) {
2156105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
21579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!isShowing() || mContentView == null) {
21589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
21599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
216175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        final WeakReference<View> oldAnchor = mAnchor;
2162f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final int gravity = mAnchoredGravity;
2163f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette
216475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        final boolean needsUpdate = updateLocation && (mAnchorXoff != xoff || mAnchorYoff != yoff);
216581f08086b44a117097960195d2c9072e29644962Gilles Debunne        if (oldAnchor == null || oldAnchor.get() != anchor || (needsUpdate && !mIsDropdown)) {
2166f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette            attachToAnchor(anchor, xoff, yoff, gravity);
216781f08086b44a117097960195d2c9072e29644962Gilles Debunne        } else if (needsUpdate) {
216881f08086b44a117097960195d2c9072e29644962Gilles Debunne            // No need to register again if this is a DropDown, showAsDropDown already did.
216981f08086b44a117097960195d2c9072e29644962Gilles Debunne            mAnchorXoff = xoff;
217081f08086b44a117097960195d2c9072e29644962Gilles Debunne            mAnchorYoff = yoff;
21719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2173f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final LayoutParams p = (LayoutParams) mDecorView.getLayoutParams();
2174f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final int oldGravity = p.gravity;
2175f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final int oldWidth = p.width;
2176f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final int oldHeight = p.height;
2177f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final int oldX = p.x;
2178f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final int oldY = p.y;
2179f95b2d9aabc2e989bd1d665e728922b1c529589aAlan Viverette
2180b91d6d06b824aab4076fb985304a602806429042Alan Viverette        // If an explicit width/height has not specified, use the most recent
2181b91d6d06b824aab4076fb985304a602806429042Alan Viverette        // explicitly specified value (either from setWidth/Height or update).
2182f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr        if (width < 0) {
2183b91d6d06b824aab4076fb985304a602806429042Alan Viverette            width = mWidth;
2184b91d6d06b824aab4076fb985304a602806429042Alan Viverette        }
2185f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr        if (height < 0) {
2186b91d6d06b824aab4076fb985304a602806429042Alan Viverette            height = mHeight;
21879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2188105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
2189f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final boolean aboveAnchor = findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff,
219050df07a1add902da01018756c213169e4e126a28Alan Viverette                width, height, gravity, mAllowScrollingAnchorParent);
2191f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        updateAboveAnchor(aboveAnchor);
2192b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio
2193f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final boolean paramsChanged = oldGravity != p.gravity || oldX != p.x || oldY != p.y
2194f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette                || oldWidth != p.width || oldHeight != p.height;
219550df07a1add902da01018756c213169e4e126a28Alan Viverette
219650df07a1add902da01018756c213169e4e126a28Alan Viverette        // If width and mWidth were both < 0 then we have a MATCH_PARENT or
219750df07a1add902da01018756c213169e4e126a28Alan Viverette        // WRAP_CONTENT case. findDropDownPosition will have resolved this to
219850df07a1add902da01018756c213169e4e126a28Alan Viverette        // absolute values, but we don't want to update mWidth/mHeight to these
219950df07a1add902da01018756c213169e4e126a28Alan Viverette        // absolute values.
220050df07a1add902da01018756c213169e4e126a28Alan Viverette        final int newWidth = width < 0 ? width : p.width;
220150df07a1add902da01018756c213169e4e126a28Alan Viverette        final int newHeight = height < 0 ? height : p.height;
220250df07a1add902da01018756c213169e4e126a28Alan Viverette        update(p.x, p.y, newWidth, newHeight, paramsChanged);
22039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
22069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Listener that is called when this popup window is dismissed.
22079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
22089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface OnDismissListener {
22099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
22109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Called when this popup window is dismissed.
22119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
22129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onDismiss();
22139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2215f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette    private void detachFromAnchor() {
2216634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        final View anchor = mAnchor != null ? mAnchor.get() : null;
22179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (anchor != null) {
2218e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            final ViewTreeObserver vto = anchor.getViewTreeObserver();
22199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            vto.removeOnScrollChangedListener(mOnScrollChangedListener);
22209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2221e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
2222634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        final View anchorRoot = mAnchorRoot != null ? mAnchorRoot.get() : null;
2223634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        if (anchorRoot != null) {
2224634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            anchorRoot.removeOnAttachStateChangeListener(mOnAnchorRootDetachedListener);
2225634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        }
2226634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
22279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAnchor = null;
2228634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        mAnchorRoot = null;
2229634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        mIsAnchorRootAttached = false;
22309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2232f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette    private void attachToAnchor(View anchor, int xoff, int yoff, int gravity) {
2233f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        detachFromAnchor();
2234e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
2235e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        final ViewTreeObserver vto = anchor.getViewTreeObserver();
22369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (vto != null) {
22379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            vto.addOnScrollChangedListener(mOnScrollChangedListener);
22389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
22399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2240634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        final View anchorRoot = anchor.getRootView();
2241634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        anchorRoot.addOnAttachStateChangeListener(mOnAnchorRootDetachedListener);
2242634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
2243634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        mAnchor = new WeakReference<>(anchor);
2244634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        mAnchorRoot = new WeakReference<>(anchorRoot);
2245634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        mIsAnchorRootAttached = anchorRoot.isAttachedToWindow();
224650db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal        mParentRootView = mAnchorRoot;
2247634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
22489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAnchorXoff = xoff;
22499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAnchorYoff = yoff;
225054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell        mAnchoredGravity = gravity;
22519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22535435a30ae552391f14009c4459731ae149675b18Alan Viverette    private class PopupDecorView extends FrameLayout {
22548fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        private TransitionListenerAdapter mPendingExitListener;
22558fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
22565435a30ae552391f14009c4459731ae149675b18Alan Viverette        public PopupDecorView(Context context) {
22575435a30ae552391f14009c4459731ae149675b18Alan Viverette            super(context);
22585435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
22599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
22619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean dispatchKeyEvent(KeyEvent event) {
22629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
22634ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson                if (getKeyDispatcherState() == null) {
22644ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson                    return super.dispatchKeyEvent(event);
22654ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson                }
22664ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson
22675435a30ae552391f14009c4459731ae149675b18Alan Viverette                if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
22685435a30ae552391f14009c4459731ae149675b18Alan Viverette                    final KeyEvent.DispatcherState state = getKeyDispatcherState();
2269b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                    if (state != null) {
2270b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                        state.startTracking(event, this);
2271b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                    }
22728d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                    return true;
2273b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                } else if (event.getAction() == KeyEvent.ACTION_UP) {
22745435a30ae552391f14009c4459731ae149675b18Alan Viverette                    final KeyEvent.DispatcherState state = getKeyDispatcherState();
2275b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                    if (state != null && state.isTracking(event) && !event.isCanceled()) {
2276b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                        dismiss();
2277b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                        return true;
2278b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                    }
22798d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                }
22808d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                return super.dispatchKeyEvent(event);
22819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
22829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return super.dispatchKeyEvent(event);
22839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
22849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
22859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
22879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean dispatchTouchEvent(MotionEvent ev) {
22889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mTouchInterceptor != null && mTouchInterceptor.onTouch(this, ev)) {
22899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
22909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
22919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return super.dispatchTouchEvent(ev);
22929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
22939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
22959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean onTouchEvent(MotionEvent event) {
22969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int x = (int) event.getX();
22979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int y = (int) event.getY();
22985435a30ae552391f14009c4459731ae149675b18Alan Viverette
22999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((event.getAction() == MotionEvent.ACTION_DOWN)
23009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    && ((x < 0) || (x >= getWidth()) || (y < 0) || (y >= getHeight()))) {
23019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dismiss();
23029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
23039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
23049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dismiss();
23059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
23069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
23079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return super.onTouchEvent(event);
23089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
23099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
23108fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
23118fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        /**
23128fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * Requests that an enter transition run after the next layout pass.
23138fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         */
23148fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        public void requestEnterTransition(Transition transition) {
23158fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            final ViewTreeObserver observer = getViewTreeObserver();
23168fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            if (observer != null && transition != null) {
23178fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                final Transition enterTransition = transition.clone();
23188fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
23198fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                // Postpone the enter transition after the first layout pass.
23208fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
23218fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                    @Override
23228fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                    public void onGlobalLayout() {
23238fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                        final ViewTreeObserver observer = getViewTreeObserver();
23248fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                        if (observer != null) {
23258fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                            observer.removeOnGlobalLayoutListener(this);
23268fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                        }
23278fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
232891098574f90277128415e9593cce1e495cc51465Alan Viverette                        final Rect epicenter = getTransitionEpicenter();
232995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                        enterTransition.setEpicenterCallback(new EpicenterCallback() {
233095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                            @Override
233195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                            public Rect onGetEpicenter(Transition transition) {
233295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                                return epicenter;
233395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                            }
233495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                        });
23358fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                        startEnterTransition(enterTransition);
23368fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                    }
23378fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                });
23388fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
23398fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
23408fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
23418fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        /**
23428fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * Starts the pending enter transition, if one is set.
23438fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         */
23448fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        private void startEnterTransition(Transition enterTransition) {
23458fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            final int count = getChildCount();
23468fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            for (int i = 0; i < count; i++) {
23478fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                final View child = getChildAt(i);
23488fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                enterTransition.addTarget(child);
23498fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                child.setVisibility(View.INVISIBLE);
23508fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
23518fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
23528fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            TransitionManager.beginDelayedTransition(this, enterTransition);
23538fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
23548fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            for (int i = 0; i < count; i++) {
23558fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                final View child = getChildAt(i);
23568fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                child.setVisibility(View.VISIBLE);
23578fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
23588fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
23598fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
23608fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        /**
23618fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * Starts an exit transition immediately.
23628fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * <p>
23638fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * <strong>Note:</strong> The transition listener is guaranteed to have
23648fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * its {@code onTransitionEnd} method called even if the transition
23658fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * never starts; however, it may be called with a {@code null} argument.
23668fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         */
2367054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette        public void startExitTransition(@NonNull Transition transition,
2368054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette                @Nullable final View anchorRoot, @Nullable final Rect epicenter,
2369054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette                @NonNull final TransitionListener listener) {
23708fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            if (transition == null) {
23718fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                return;
23728fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
23738fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
2374634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            // The anchor view's window may go away while we're executing our
2375634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            // transition, in which case we need to end the transition
2376634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            // immediately and execute the listener to remove the popup.
2377054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette            if (anchorRoot != null) {
2378054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette                anchorRoot.addOnAttachStateChangeListener(mOnAnchorRootDetachedListener);
2379054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette            }
2380634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
23818fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            // The exit listener MUST be called for cleanup, even if the
23828fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            // transition never starts or ends. Stash it for later.
23838fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            mPendingExitListener = new TransitionListenerAdapter() {
23848fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                @Override
2385054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette                public void onTransitionEnd(Transition t) {
2386054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette                    if (anchorRoot != null) {
2387054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette                        anchorRoot.removeOnAttachStateChangeListener(mOnAnchorRootDetachedListener);
2388054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette                    }
2389054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette
2390054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette                    listener.onTransitionEnd(t);
23918fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
23928fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                    // The listener was called. Our job here is done.
23938fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                    mPendingExitListener = null;
2394054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette                    t.removeListener(this);
23958fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                }
23968fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            };
23978fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
23988fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            final Transition exitTransition = transition.clone();
23998fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            exitTransition.addListener(mPendingExitListener);
2400054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette            exitTransition.setEpicenterCallback(new EpicenterCallback() {
2401054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette                @Override
2402054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette                public Rect onGetEpicenter(Transition transition) {
2403054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette                    return epicenter;
2404054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette                }
2405054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette            });
24068fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
24078fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            final int count = getChildCount();
24088fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            for (int i = 0; i < count; i++) {
24098fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                final View child = getChildAt(i);
24108fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                exitTransition.addTarget(child);
24118fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
24128fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
24138fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            TransitionManager.beginDelayedTransition(this, exitTransition);
24148fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
24158fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            for (int i = 0; i < count; i++) {
24168fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                final View child = getChildAt(i);
24178fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                child.setVisibility(View.INVISIBLE);
24188fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
24198fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
24208fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
24218fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        /**
24228fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * Cancels all pending or current transitions.
24238fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         */
24248fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        public void cancelTransitions() {
24258fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            TransitionManager.endTransitions(this);
24268fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
24278fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            if (mPendingExitListener != null) {
24288fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                mPendingExitListener.onTransitionEnd(null);
24298fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
24308fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
2431634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
2432634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        private final OnAttachStateChangeListener mOnAnchorRootDetachedListener =
2433634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                new OnAttachStateChangeListener() {
2434634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    @Override
2435634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    public void onViewAttachedToWindow(View v) {}
2436634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
2437634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    @Override
2438634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    public void onViewDetachedFromWindow(View v) {
2439634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                        v.removeOnAttachStateChangeListener(this);
2440634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
2441634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                        TransitionManager.endTransitions(PopupDecorView.this);
2442634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    }
2443634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                };
244450db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal
244550db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal        @Override
244650db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal        public void requestKeyboardShortcuts(List<KeyboardShortcutGroup> list, int deviceId) {
244750db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal            if (mParentRootView != null) {
244850db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal                View parentRoot = mParentRootView.get();
244950db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal                if (parentRoot != null) {
245050db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal                    parentRoot.requestKeyboardShortcuts(list, deviceId);
245150db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal                }
245250db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal            }
245350db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal        }
24545435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
24555435a30ae552391f14009c4459731ae149675b18Alan Viverette
24565435a30ae552391f14009c4459731ae149675b18Alan Viverette    private class PopupBackgroundView extends FrameLayout {
24575435a30ae552391f14009c4459731ae149675b18Alan Viverette        public PopupBackgroundView(Context context) {
24585435a30ae552391f14009c4459731ae149675b18Alan Viverette            super(context);
24595435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
246075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
246175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        @Override
24625435a30ae552391f14009c4459731ae149675b18Alan Viverette        protected int[] onCreateDrawableState(int extraSpace) {
24635435a30ae552391f14009c4459731ae149675b18Alan Viverette            if (mAboveAnchor) {
24645435a30ae552391f14009c4459731ae149675b18Alan Viverette                final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
24655435a30ae552391f14009c4459731ae149675b18Alan Viverette                View.mergeDrawableStates(drawableState, ABOVE_ANCHOR_STATE_SET);
24665435a30ae552391f14009c4459731ae149675b18Alan Viverette                return drawableState;
246775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            } else {
24685435a30ae552391f14009c4459731ae149675b18Alan Viverette                return super.onCreateDrawableState(extraSpace);
246975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            }
247075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
24719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
24729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2473