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;
58b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheevimport android.view.WindowManagerGlobal;
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6099441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikasimport com.android.internal.R;
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6299441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikasimport java.lang.ref.WeakReference;
6350db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwalimport java.util.List;
641e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
661e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <p>
671e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * This class represents a popup window that can be used to display an
681e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * arbitrary view. The popup window is a floating container that appears on top
691e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * of the current activity.
701e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </p>
711e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <a name="Animation"></a>
721e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <h3>Animation</h3>
731e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <p>
741e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * On all versions of Android, popup window enter and exit animations may be
751e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * specified by calling {@link #setAnimationStyle(int)} and passing the
761e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * resource ID for an animation style that defines {@code windowEnterAnimation}
771e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * and {@code windowExitAnimation}. For example, passing
781e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * {@link android.R.style#Animation_Dialog} will give a scale and alpha
791e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * animation.
801e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </br>
811e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * A window animation style may also be specified in the popup window's style
821e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * XML via the {@link android.R.styleable#PopupWindow_popupAnimationStyle popupAnimationStyle}
831e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * attribute.
841e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </p>
851e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <p>
861e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * Starting with API 23, more complex popup window enter and exit transitions
871e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * may be specified by calling either {@link #setEnterTransition(Transition)}
881e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * or {@link #setExitTransition(Transition)} and passing a  {@link Transition}.
891e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </br>
901e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * Popup enter and exit transitions may also be specified in the popup window's
911e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * style XML via the {@link android.R.styleable#PopupWindow_popupEnterTransition popupEnterTransition}
921e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * and {@link android.R.styleable#PopupWindow_popupExitTransition popupExitTransition}
931e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * attributes, respectively.
941e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </p>
951e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette *
961e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_overlapAnchor
971e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupAnimationStyle
981e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupBackground
991e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupElevation
1001e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupEnterTransition
1011e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupExitTransition
1025435a30ae552391f14009c4459731ae149675b18Alan Viverette *
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.widget.AutoCompleteTextView
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.widget.Spinner
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class PopupWindow {
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
108e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     * Mode for {@link #setInputMethodMode(int)}: the requirements for the
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * input method should be based on the focusability of the popup.  That is
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if it is focusable than it needs to work with the input method, else
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * it doesn't.
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int INPUT_METHOD_FROM_FOCUSABLE = 0;
1145435a30ae552391f14009c4459731ae149675b18Alan Viverette
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
116e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     * Mode for {@link #setInputMethodMode(int)}: this popup always needs to
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * work with an input method, regardless of whether it is focusable.  This
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * means that it will always be displayed so that the user can also operate
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the input method while it is shown.
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int INPUT_METHOD_NEEDED = 1;
1225435a30ae552391f14009c4459731ae149675b18Alan Viverette
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
124e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     * Mode for {@link #setInputMethodMode(int)}: this popup never needs to
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * work with an input method, regardless of whether it is focusable.  This
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * means that it will always be displayed to use as much space on the
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * screen as needed, regardless of whether this covers the input method.
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int INPUT_METHOD_NOT_NEEDED = 2;
13054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell
13154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell    private static final int DEFAULT_ANCHORED_GRAVITY = Gravity.TOP | Gravity.START;
13254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell
1335435a30ae552391f14009c4459731ae149675b18Alan Viverette    /**
1345435a30ae552391f14009c4459731ae149675b18Alan Viverette     * Default animation style indicating that separate animations should be
1355435a30ae552391f14009c4459731ae149675b18Alan Viverette     * used for top/bottom anchoring states.
1365435a30ae552391f14009c4459731ae149675b18Alan Viverette     */
1375435a30ae552391f14009c4459731ae149675b18Alan Viverette    private static final int ANIMATION_STYLE_DEFAULT = -1;
1385435a30ae552391f14009c4459731ae149675b18Alan Viverette
139f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette    private final int[] mTmpDrawingLocation = new int[2];
140f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette    private final int[] mTmpScreenLocation = new int[2];
141b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev    private final int[] mTmpAppLocation = new int[2];
1425435a30ae552391f14009c4459731ae149675b18Alan Viverette    private final Rect mTempRect = new Rect();
1435435a30ae552391f14009c4459731ae149675b18Alan Viverette
144448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy    private Context mContext;
145448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy    private WindowManager mWindowManager;
1465435a30ae552391f14009c4459731ae149675b18Alan Viverette
14750db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal    /**
14850db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal     * Keeps track of popup's parent's decor view. This is needed to dispatch
14950db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal     * requestKeyboardShortcuts to the owning Activity.
15050db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal     */
15150db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal    private WeakReference<View> mParentRootView;
15250db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mIsShowing;
1548fd949e680c15d397084430d4907c16cedfacddaAlan Viverette    private boolean mIsTransitioningToDismiss;
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mIsDropdown;
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1575435a30ae552391f14009c4459731ae149675b18Alan Viverette    /** View that handles event dispatch and content transitions. */
1585435a30ae552391f14009c4459731ae149675b18Alan Viverette    private PopupDecorView mDecorView;
1595435a30ae552391f14009c4459731ae149675b18Alan Viverette
160697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette    /** View that holds the background and may animate during a transition. */
161697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette    private View mBackgroundView;
162697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette
163697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette    /** The contents of the popup. May be identical to the background view. */
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private View mContentView;
1655435a30ae552391f14009c4459731ae149675b18Alan Viverette
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mFocusable;
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mInputMethodMode = INPUT_METHOD_FROM_FOCUSABLE;
16822dac1c8df4ec212e8195a69d2de15d313d724fbYohei Yukawa    @SoftInputModeFlags
1697eab094722af54717859b7dcce3cc050f059e00bDianne Hackborn    private int mSoftInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED;
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mTouchable = true;
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mOutsideTouchable = false;
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mClippingEnabled = true;
17346e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown    private int mSplitTouchEnabled = -1;
174ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    private boolean mLayoutInScreen;
17556c2d337e02a275397fc9d0460dca90977f199acAdam Powell    private boolean mClipToScreen;
176348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell    private boolean mAllowScrollingAnchorParent = true;
1770bd1d0a15294345bf88b20df28466907f982cec7Adam Powell    private boolean mLayoutInsetDecor = false;
178e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell    private boolean mNotTouchModal;
179393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    private boolean mAttachedInDecor = true;
180393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    private boolean mAttachedInDecorSet = false;
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private OnTouchListener mTouchInterceptor;
183393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mWidthMode;
185259c2840691a79634ffd8f63291ec21c21819542Alan Viverette    private int mWidth = LayoutParams.WRAP_CONTENT;
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mLastWidth;
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mHeightMode;
188259c2840691a79634ffd8f63291ec21c21819542Alan Viverette    private int mHeight = LayoutParams.WRAP_CONTENT;
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mLastHeight;
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
191ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    private float mElevation;
192ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mBackground;
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mAboveAnchorBackgroundDrawable;
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mBelowAnchorBackgroundDrawable;
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1975435a30ae552391f14009c4459731ae149675b18Alan Viverette    private Transition mEnterTransition;
1985435a30ae552391f14009c4459731ae149675b18Alan Viverette    private Transition mExitTransition;
19991098574f90277128415e9593cce1e495cc51465Alan Viverette    private Rect mEpicenterBounds;
200560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mAboveAnchor;
202574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    private int mWindowLayoutType = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
2035435a30ae552391f14009c4459731ae149675b18Alan Viverette
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private OnDismissListener mOnDismissListener;
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mIgnoreCheekPress = false;
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2075435a30ae552391f14009c4459731ae149675b18Alan Viverette    private int mAnimationStyle = ANIMATION_STYLE_DEFAULT;
2085435a30ae552391f14009c4459731ae149675b18Alan Viverette
209085160612d9066e23c96a6cac15eb3a51481fdafRobert Carr    private int mGravity = Gravity.NO_GRAVITY;
210085160612d9066e23c96a6cac15eb3a51481fdafRobert Carr
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int[] ABOVE_ANCHOR_STATE_SET = new int[] {
2124753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme            com.android.internal.R.attr.state_above_anchor
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
215afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev    private final OnAttachStateChangeListener mOnAnchorDetachedListener =
216afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev            new OnAttachStateChangeListener() {
217afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev                @Override
218afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev                public void onViewAttachedToWindow(View v) {
219afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev                    // Anchor might have been reattached in a different position.
220afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev                    alignToAnchor();
221afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev                }
222afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev
223afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev                @Override
224afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev                public void onViewDetachedFromWindow(View v) {
225afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev                    // Leave the popup in its current position.
226afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev                    // The anchor might become attached again.
227afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev                }
228afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev            };
229afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev
230634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette    private final OnAttachStateChangeListener mOnAnchorRootDetachedListener =
231634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            new OnAttachStateChangeListener() {
232634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                @Override
233634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                public void onViewAttachedToWindow(View v) {}
234634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
235634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                @Override
236634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                public void onViewDetachedFromWindow(View v) {
237634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    mIsAnchorRootAttached = false;
238634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                }
239634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            };
240634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private WeakReference<View> mAnchor;
242634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette    private WeakReference<View> mAnchorRoot;
243634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette    private boolean mIsAnchorRootAttached;
244560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
245afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev    private final OnScrollChangedListener mOnScrollChangedListener = this::alignToAnchor;
246560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
247b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev    private final View.OnLayoutChangeListener mOnLayoutChangeListener =
248b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev            (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> alignToAnchor();
249b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev
2505435a30ae552391f14009c4459731ae149675b18Alan Viverette    private int mAnchorXoff;
2515435a30ae552391f14009c4459731ae149675b18Alan Viverette    private int mAnchorYoff;
2525435a30ae552391f14009c4459731ae149675b18Alan Viverette    private int mAnchoredGravity;
253560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette    private boolean mOverlapAnchor;
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
255b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio    private boolean mPopupViewInitialLayoutDirectionInherited;
256b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window of dimension (0,0).</p>
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does provide a background.</p>
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(Context context) {
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(context, null);
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window of dimension (0,0).</p>
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does provide a background.</p>
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(Context context, AttributeSet attrs) {
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(context, attrs, com.android.internal.R.attr.popupWindowStyle);
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window of dimension (0,0).</p>
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does provide a background.</p>
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
280617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr) {
281617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        this(context, attrs, defStyleAttr, 0);
282c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
2835435a30ae552391f14009c4459731ae149675b18Alan Viverette
284c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
285c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * <p>Create a new, empty, non focusable popup window of dimension (0,0).</p>
2865435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
287c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * <p>The popup does not provide a background.</p>
288c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
289c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext = context;
29175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
293617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        final TypedArray a = context.obtainStyledAttributes(
294ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                attrs, R.styleable.PopupWindow, defStyleAttr, defStyleRes);
295ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        final Drawable bg = a.getDrawable(R.styleable.PopupWindow_popupBackground);
296ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        mElevation = a.getDimension(R.styleable.PopupWindow_popupElevation, 0);
297560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        mOverlapAnchor = a.getBoolean(R.styleable.PopupWindow_overlapAnchor, false);
298c3808b5dc7d5873d04e8a0a247b179b2757764baAdam Powell
2995435a30ae552391f14009c4459731ae149675b18Alan Viverette        // Preserve default behavior from Gingerbread. If the animation is
3005435a30ae552391f14009c4459731ae149675b18Alan Viverette        // undefined or explicitly specifies the Gingerbread animation style,
3015435a30ae552391f14009c4459731ae149675b18Alan Viverette        // use a sentinel value.
3025435a30ae552391f14009c4459731ae149675b18Alan Viverette        if (a.hasValueOrEmpty(R.styleable.PopupWindow_popupAnimationStyle)) {
3035435a30ae552391f14009c4459731ae149675b18Alan Viverette            final int animStyle = a.getResourceId(R.styleable.PopupWindow_popupAnimationStyle, 0);
3045435a30ae552391f14009c4459731ae149675b18Alan Viverette            if (animStyle == R.style.Animation_PopupWindow) {
3055435a30ae552391f14009c4459731ae149675b18Alan Viverette                mAnimationStyle = ANIMATION_STYLE_DEFAULT;
3065435a30ae552391f14009c4459731ae149675b18Alan Viverette            } else {
3075435a30ae552391f14009c4459731ae149675b18Alan Viverette                mAnimationStyle = animStyle;
3085435a30ae552391f14009c4459731ae149675b18Alan Viverette            }
3095435a30ae552391f14009c4459731ae149675b18Alan Viverette        } else {
3105435a30ae552391f14009c4459731ae149675b18Alan Viverette            mAnimationStyle = ANIMATION_STYLE_DEFAULT;
3115435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
3125435a30ae552391f14009c4459731ae149675b18Alan Viverette
3135435a30ae552391f14009c4459731ae149675b18Alan Viverette        final Transition enterTransition = getTransition(a.getResourceId(
3145435a30ae552391f14009c4459731ae149675b18Alan Viverette                R.styleable.PopupWindow_popupEnterTransition, 0));
3155435a30ae552391f14009c4459731ae149675b18Alan Viverette        final Transition exitTransition;
3165435a30ae552391f14009c4459731ae149675b18Alan Viverette        if (a.hasValueOrEmpty(R.styleable.PopupWindow_popupExitTransition)) {
3175435a30ae552391f14009c4459731ae149675b18Alan Viverette            exitTransition = getTransition(a.getResourceId(
3185435a30ae552391f14009c4459731ae149675b18Alan Viverette                    R.styleable.PopupWindow_popupExitTransition, 0));
3195435a30ae552391f14009c4459731ae149675b18Alan Viverette        } else {
3205435a30ae552391f14009c4459731ae149675b18Alan Viverette            exitTransition = enterTransition == null ? null : enterTransition.clone();
3215435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        a.recycle();
324ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette
3255435a30ae552391f14009c4459731ae149675b18Alan Viverette        setEnterTransition(enterTransition);
3265435a30ae552391f14009c4459731ae149675b18Alan Viverette        setExitTransition(exitTransition);
327ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        setBackgroundDrawable(bg);
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window of dimension (0,0).</p>
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow() {
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(null, 0, 0);
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new non focusable popup window which can display the
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <tt>contentView</tt>. The dimension of the window are (0,0).</p>
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param contentView the popup's content
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(View contentView) {
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(contentView, 0, 0);
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window. The dimension of the
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window must be passed to this constructor.</p>
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width the popup's width
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height the popup's height
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(int width, int height) {
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(null, width, height);
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new non focusable popup window which can display the
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <tt>contentView</tt>. The dimension of the window must be passed to
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this constructor.</p>
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param contentView the popup's content
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width the popup's width
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height the popup's height
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(View contentView, int width, int height) {
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(contentView, width, height, false);
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new popup window which can display the <tt>contentView</tt>.
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The dimension of the window must be passed to this constructor.</p>
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param contentView the popup's content
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width the popup's width
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height the popup's height
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param focusable true if the popup can be focused, false otherwise
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
395448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy    public PopupWindow(View contentView, int width, int height, boolean focusable) {
396448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        if (contentView != null) {
397448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy            mContext = contentView.getContext();
398448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy            mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
399448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        }
400393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setContentView(contentView);
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setWidth(width);
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setHeight(height);
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setFocusable(focusable);
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4071e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    /**
4081e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * Sets the enter transition to be used when the popup window is shown.
4091e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     *
4101e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @param enterTransition the enter transition, or {@code null} to clear
4111e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @see #getEnterTransition()
4121e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @attr ref android.R.styleable#PopupWindow_popupEnterTransition
4131e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     */
4141e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    public void setEnterTransition(@Nullable Transition enterTransition) {
4155435a30ae552391f14009c4459731ae149675b18Alan Viverette        mEnterTransition = enterTransition;
4165435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
4175435a30ae552391f14009c4459731ae149675b18Alan Viverette
4181e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    /**
4191e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * Returns the enter transition to be used when the popup window is shown.
4201e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     *
4211e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @return the enter transition, or {@code null} if not set
4221e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @see #setEnterTransition(Transition)
4231e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @attr ref android.R.styleable#PopupWindow_popupEnterTransition
4241e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     */
4251e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    @Nullable
4261e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    public Transition getEnterTransition() {
4271e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette        return mEnterTransition;
4281e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    }
4291e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette
4301e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    /**
4311e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * Sets the exit transition to be used when the popup window is dismissed.
4321e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     *
4331e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @param exitTransition the exit transition, or {@code null} to clear
4341e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @see #getExitTransition()
4351e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @attr ref android.R.styleable#PopupWindow_popupExitTransition
4361e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     */
4371e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    public void setExitTransition(@Nullable Transition exitTransition) {
4385435a30ae552391f14009c4459731ae149675b18Alan Viverette        mExitTransition = exitTransition;
4395435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
4405435a30ae552391f14009c4459731ae149675b18Alan Viverette
44191098574f90277128415e9593cce1e495cc51465Alan Viverette    /**
4421e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * Returns the exit transition to be used when the popup window is
4431e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * dismissed.
4441e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     *
4451e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @return the exit transition, or {@code null} if not set
4461e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @see #setExitTransition(Transition)
4471e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     * @attr ref android.R.styleable#PopupWindow_popupExitTransition
4481e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette     */
4491e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    @Nullable
4501e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    public Transition getExitTransition() {
4511e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette        return mExitTransition;
4521e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    }
4531e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette
4541e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette    /**
45591098574f90277128415e9593cce1e495cc51465Alan Viverette     * Sets the bounds used as the epicenter of the enter and exit transitions.
45691098574f90277128415e9593cce1e495cc51465Alan Viverette     * <p>
45791098574f90277128415e9593cce1e495cc51465Alan Viverette     * Transitions use a point or Rect, referred to as the epicenter, to orient
45891098574f90277128415e9593cce1e495cc51465Alan Viverette     * the direction of travel. For popup windows, the anchor view bounds are
45991098574f90277128415e9593cce1e495cc51465Alan Viverette     * used as the default epicenter.
46091098574f90277128415e9593cce1e495cc51465Alan Viverette     * <p>
46191098574f90277128415e9593cce1e495cc51465Alan Viverette     * See {@link Transition#setEpicenterCallback(EpicenterCallback)} for more
46291098574f90277128415e9593cce1e495cc51465Alan Viverette     * information about how transition epicenters.
46391098574f90277128415e9593cce1e495cc51465Alan Viverette     *
46491098574f90277128415e9593cce1e495cc51465Alan Viverette     * @param bounds the epicenter bounds relative to the anchor view, or
46591098574f90277128415e9593cce1e495cc51465Alan Viverette     *               {@code null} to use the default epicenter
46691098574f90277128415e9593cce1e495cc51465Alan Viverette     * @see #getTransitionEpicenter()
46791098574f90277128415e9593cce1e495cc51465Alan Viverette     * @hide
46891098574f90277128415e9593cce1e495cc51465Alan Viverette     */
46991098574f90277128415e9593cce1e495cc51465Alan Viverette    public void setEpicenterBounds(Rect bounds) {
47091098574f90277128415e9593cce1e495cc51465Alan Viverette        mEpicenterBounds = bounds;
47191098574f90277128415e9593cce1e495cc51465Alan Viverette    }
47291098574f90277128415e9593cce1e495cc51465Alan Viverette
4735435a30ae552391f14009c4459731ae149675b18Alan Viverette    private Transition getTransition(int resId) {
4745435a30ae552391f14009c4459731ae149675b18Alan Viverette        if (resId != 0 && resId != R.transition.no_transition) {
4755435a30ae552391f14009c4459731ae149675b18Alan Viverette            final TransitionInflater inflater = TransitionInflater.from(mContext);
4765435a30ae552391f14009c4459731ae149675b18Alan Viverette            final Transition transition = inflater.inflateTransition(resId);
4775435a30ae552391f14009c4459731ae149675b18Alan Viverette            if (transition != null) {
4785435a30ae552391f14009c4459731ae149675b18Alan Viverette                final boolean isEmpty = transition instanceof TransitionSet
4795435a30ae552391f14009c4459731ae149675b18Alan Viverette                        && ((TransitionSet) transition).getTransitionCount() == 0;
4805435a30ae552391f14009c4459731ae149675b18Alan Viverette                if (!isEmpty) {
4815435a30ae552391f14009c4459731ae149675b18Alan Viverette                    return transition;
4825435a30ae552391f14009c4459731ae149675b18Alan Viverette                }
4835435a30ae552391f14009c4459731ae149675b18Alan Viverette            }
4845435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
4855435a30ae552391f14009c4459731ae149675b18Alan Viverette        return null;
4865435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
4875435a30ae552391f14009c4459731ae149675b18Alan Viverette
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
489ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * Return the drawable used as the popup window's background.
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
491ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @return the background drawable or {@code null} if not set
492ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @see #setBackgroundDrawable(Drawable)
493ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @attr ref android.R.styleable#PopupWindow_popupBackground
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Drawable getBackground() {
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mBackground;
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
500ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * Specifies the background drawable for this popup window. The background
501ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * can be set to {@code null}.
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param background the popup's background
504ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @see #getBackground()
505ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @attr ref android.R.styleable#PopupWindow_popupBackground
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setBackgroundDrawable(Drawable background) {
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBackground = background;
509ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette
510ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // If this is a StateListDrawable, try to find and store the drawable to be
511ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // used when the drop-down is placed above its anchor view, and the one to be
512ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // used when the drop-down is placed below its anchor view. We extract
513ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // the drawables ourselves to work around a problem with using refreshDrawableState
514ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // that it will take into account the padding of all drawables specified in a
515ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // StateListDrawable, thus adding superfluous padding to drop-down views.
516ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        //
517ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // We assume a StateListDrawable will have a drawable for ABOVE_ANCHOR_STATE_SET and
518ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // at least one other drawable, intended for the 'below-anchor state'.
519ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        if (mBackground instanceof StateListDrawable) {
520ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            StateListDrawable stateList = (StateListDrawable) mBackground;
521ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette
522ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            // Find the above-anchor view - this one's easy, it should be labeled as such.
523ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            int aboveAnchorStateIndex = stateList.getStateDrawableIndex(ABOVE_ANCHOR_STATE_SET);
524ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette
525ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            // Now, for the below-anchor view, look for any other drawable specified in the
526ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            // StateListDrawable which is not for the above-anchor state and use that.
527ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            int count = stateList.getStateCount();
528ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            int belowAnchorStateIndex = -1;
529ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            for (int i = 0; i < count; i++) {
530ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                if (i != aboveAnchorStateIndex) {
531ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                    belowAnchorStateIndex = i;
532ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                    break;
533ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                }
534ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            }
535ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette
536ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            // Store the drawables we found, if we found them. Otherwise, set them both
537ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            // to null so that we'll just use refreshDrawableState.
538ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            if (aboveAnchorStateIndex != -1 && belowAnchorStateIndex != -1) {
539ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                mAboveAnchorBackgroundDrawable = stateList.getStateDrawable(aboveAnchorStateIndex);
540ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                mBelowAnchorBackgroundDrawable = stateList.getStateDrawable(belowAnchorStateIndex);
541ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            } else {
542ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                mBelowAnchorBackgroundDrawable = null;
543ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                mAboveAnchorBackgroundDrawable = null;
544ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            }
545ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        }
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
549ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @return the elevation for this popup window in pixels
550ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @see #setElevation(float)
551ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @attr ref android.R.styleable#PopupWindow_popupElevation
552ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     */
553ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    public float getElevation() {
554ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        return mElevation;
555ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    }
556ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
557ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    /**
558ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * Specifies the elevation for this popup window.
559ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     *
560ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @param elevation the popup's elevation in pixels
561ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @see #getElevation()
562ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @attr ref android.R.styleable#PopupWindow_popupElevation
563ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     */
564ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    public void setElevation(float elevation) {
565ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        mElevation = elevation;
566ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    }
567ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
568ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    /**
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Return the animation style to use the popup appears and disappears</p>
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the animation style to use the popup appears and disappears
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getAnimationStyle() {
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mAnimationStyle;
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
576393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
57854ec76d81ac38284caa6d00ad5f2d2207206b9ceShuhrat Dehkanov     * Set the flag on popup to ignore cheek press events; by default this flag
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is set to false
58054ec76d81ac38284caa6d00ad5f2d2207206b9ceShuhrat Dehkanov     * which means the popup will not ignore cheek press dispatch events.
5815435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
585393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setIgnoreCheekPress() {
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIgnoreCheekPress = true;
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5915435a30ae552391f14009c4459731ae149675b18Alan Viverette
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Change the animation style resource for this popup.</p>
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param animationStyle animation style to use when the popup appears
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *      and disappears.  Set to -1 for the default animation, 0 for no
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *      animation, or a resource identifier for an explicit animation.
6025435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setAnimationStyle(int animationStyle) {
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAnimationStyle = animationStyle;
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6085435a30ae552391f14009c4459731ae149675b18Alan Viverette
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Return the view used as the content of the popup window.</p>
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a {@link android.view.View} representing the popup's content
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setContentView(android.view.View)
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View getContentView() {
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mContentView;
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Change the popup's content. The content is represented by an instance
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of {@link android.view.View}.</p>
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
62481f08086b44a117097960195d2c9072e29644962Gilles Debunne     * <p>This method has no effect if called when the popup is showing.</p>
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param contentView the new content for the popup
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getContentView()
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isShowing()
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setContentView(View contentView) {
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isShowing()) {
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContentView = contentView;
637448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy
6380c0b768e1514280812321854db6dfba723c3d169Romain Guy        if (mContext == null && mContentView != null) {
639448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy            mContext = mContentView.getContext();
640448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        }
641448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy
6420c0b768e1514280812321854db6dfba723c3d169Romain Guy        if (mWindowManager == null && mContentView != null) {
643448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy            mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
644448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        }
645393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
646393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        // Setting the default for attachedInDecor based on SDK version here
647393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        // instead of in the constructor since we might not have the context
648393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        // object in the constructor. We only want to set default here if the
649393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        // app hasn't already set the attachedInDecor.
650393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        if (mContext != null && !mAttachedInDecorSet) {
651393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale            // Attach popup window in decor frame of parent window by default for
652393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale            // {@link Build.VERSION_CODES.LOLLIPOP_MR1} or greater. Keep current
653393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale            // behavior of not attaching to decor frame for older SDKs.
654393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale            setAttachedInDecor(mContext.getApplicationInfo().targetSdkVersion
655393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale                    >= Build.VERSION_CODES.LOLLIPOP_MR1);
656393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        }
657393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set a callback for all touch events being dispatched to the popup
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window.
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setTouchInterceptor(OnTouchListener l) {
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTouchInterceptor = l;
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
667393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicate whether the popup window can grab the focus.</p>
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is focusable, false otherwise
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setFocusable(boolean)
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isFocusable() {
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mFocusable;
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Changes the focusability of the popup window. When focusable, the
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window will grab the focus from the current focused widget if the popup
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * contains a focusable {@link android.view.View}.  By default a popup
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window is not focusable.</p>
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param focusable true if the popup should grab focus, false otherwise.
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isFocusable()
6925435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #isShowing()
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setFocusable(boolean focusable) {
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFocusable = focusable;
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the current value in {@link #setInputMethodMode(int)}.
7015435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setInputMethodMode(int)
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getInputMethodMode() {
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mInputMethodMode;
7065435a30ae552391f14009c4459731ae149675b18Alan Viverette
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7085435a30ae552391f14009c4459731ae149675b18Alan Viverette
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Control how the popup operates with an input method: one of
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #INPUT_METHOD_FROM_FOCUSABLE}, {@link #INPUT_METHOD_NEEDED},
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or {@link #INPUT_METHOD_NOT_NEEDED}.
7135435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
7175435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getInputMethodMode()
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setInputMethodMode(int mode) {
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputMethodMode = mode;
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
724374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy
725374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy    /**
726374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * Sets the operating mode for the soft input area.
727374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     *
728374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * @param mode The desired mode, see
729374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     *        {@link android.view.WindowManager.LayoutParams#softInputMode}
730374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     *        for the full list
731374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     *
732374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * @see android.view.WindowManager.LayoutParams#softInputMode
733374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * @see #getSoftInputMode()
734374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     */
73522dac1c8df4ec212e8195a69d2de15d313d724fbYohei Yukawa    public void setSoftInputMode(@SoftInputModeFlags int mode) {
736374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy        mSoftInputMode = mode;
737374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy    }
738374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy
739374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy    /**
740374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * Returns the current value in {@link #setSoftInputMode(int)}.
741374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     *
742374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * @see #setSoftInputMode(int)
743374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * @see android.view.WindowManager.LayoutParams#softInputMode
744374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     */
74522dac1c8df4ec212e8195a69d2de15d313d724fbYohei Yukawa    @SoftInputModeFlags
746374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy    public int getSoftInputMode() {
747374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy        return mSoftInputMode;
748374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy    }
7495435a30ae552391f14009c4459731ae149675b18Alan Viverette
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicates whether the popup window receives touch events.</p>
7525435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is touchable, false otherwise
7545435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setTouchable(boolean)
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isTouchable() {
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mTouchable;
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Changes the touchability of the popup window. When touchable, the
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window will receive touch events, otherwise touch events will go to the
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window below it. By default the window is touchable.</p>
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param touchable true if the popup should receive touch events, false otherwise
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isTouchable()
7735435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #isShowing()
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setTouchable(boolean touchable) {
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTouchable = touchable;
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicates whether the popup window will be informed of touch events
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * outside of its window.</p>
7835435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is outside touchable, false otherwise
7855435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setOutsideTouchable(boolean)
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isOutsideTouchable() {
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mOutsideTouchable;
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Controls whether the pop-up will be informed of touch events outside
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of its window.  This only makes sense for pop-ups that are touchable
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * but not focusable, which means touches outside of the window will
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be delivered to the window behind.  The default is false.</p>
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param touchable true if the popup should receive outside
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * touch events, false otherwise
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isOutsideTouchable()
8065435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #isShowing()
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setOutsideTouchable(boolean touchable) {
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOutsideTouchable = touchable;
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicates whether clipping of the popup window is enabled.</p>
8155435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the clipping is enabled, false otherwise
8175435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setClippingEnabled(boolean)
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isClippingEnabled() {
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mClippingEnabled;
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Allows the popup window to extend beyond the bounds of the screen. By default the
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window is clipped to the screen boundaries. Setting this to false will allow windows to be
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * accurately positioned.</p>
8285435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param enabled false if the window should be allowed to extend outside of the screen
8345435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #isShowing()
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isClippingEnabled()
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setClippingEnabled(boolean enabled) {
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mClippingEnabled = enabled;
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
84356c2d337e02a275397fc9d0460dca90977f199acAdam Powell     * Clip this popup window to the screen, but not to the containing window.
84456c2d337e02a275397fc9d0460dca90977f199acAdam Powell     *
84556c2d337e02a275397fc9d0460dca90977f199acAdam Powell     * @param enabled True to clip to the screen.
84656c2d337e02a275397fc9d0460dca90977f199acAdam Powell     * @hide
84756c2d337e02a275397fc9d0460dca90977f199acAdam Powell     */
84856c2d337e02a275397fc9d0460dca90977f199acAdam Powell    public void setClipToScreenEnabled(boolean enabled) {
84956c2d337e02a275397fc9d0460dca90977f199acAdam Powell        mClipToScreen = enabled;
85056c2d337e02a275397fc9d0460dca90977f199acAdam Powell    }
851348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell
852348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell    /**
853348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     * Allow PopupWindow to scroll the anchor's parent to provide more room
854348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     * for the popup. Enabled by default.
855348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     *
856348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     * @param enabled True to scroll the anchor's parent when more room is desired by the popup.
857348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     */
858348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell    void setAllowScrollingAnchorParent(boolean enabled) {
859348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell        mAllowScrollingAnchorParent = enabled;
860348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell    }
8615435a30ae552391f14009c4459731ae149675b18Alan Viverette
8624753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    /** @hide */
8634753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    protected final boolean getAllowScrollingAnchorParent() {
8644753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        return mAllowScrollingAnchorParent;
8654753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    }
8664753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme
86756c2d337e02a275397fc9d0460dca90977f199acAdam Powell    /**
86801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * <p>Indicates whether the popup window supports splitting touches.</p>
8695435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
87001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * @return true if the touch splitting is enabled, false otherwise
8715435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
87201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * @see #setSplitTouchEnabled(boolean)
87301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     */
87401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    public boolean isSplitTouchEnabled() {
87546e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown        if (mSplitTouchEnabled < 0 && mContext != null) {
87646e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown            return mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB;
87746e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown        }
87846e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown        return mSplitTouchEnabled == 1;
87901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
88001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
88101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    /**
88201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * <p>Allows the popup window to split touches across other windows that also
88346e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown     * support split touch.  When this flag is false, the first pointer
88401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * that goes down determines the window to which all subsequent touches
88546e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown     * go until all pointers go up.  When this flag is true, each pointer
88601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * (not necessarily the first) that goes down determines the window
88701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * to which all subsequent touches of that pointer will go until that
88801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * pointer goes up thereby enabling touches with multiple pointers
88901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * to be split across multiple windows.</p>
89001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     *
89101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * @param enabled true if the split touches should be enabled, false otherwise
89201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * @see #isSplitTouchEnabled()
89301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     */
89401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    public void setSplitTouchEnabled(boolean enabled) {
89546e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown        mSplitTouchEnabled = enabled ? 1 : 0;
89601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
89701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
89801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    /**
899ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * <p>Indicates whether the popup window will be forced into using absolute screen coordinates
900ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * for positioning.</p>
901ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     *
902ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * @return true if the window will always be positioned in screen coordinates.
903ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * @hide
904ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     */
905ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    public boolean isLayoutInScreenEnabled() {
906ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell        return mLayoutInScreen;
907ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    }
908ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell
909ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    /**
910ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * <p>Allows the popup window to force the flag
911ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * {@link WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN}, overriding default behavior.
912ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * This will cause the popup to be positioned in absolute screen coordinates.</p>
913ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     *
914ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * @param enabled true if the popup should always be positioned in screen coordinates
915ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * @hide
916ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     */
917ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    public void setLayoutInScreenEnabled(boolean enabled) {
918ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell        mLayoutInScreen = enabled;
919ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    }
920ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell
921ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    /**
922393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * <p>Indicates whether the popup window will be attached in the decor frame of its parent
923393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * window.
924393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
925393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * @return true if the window will be attached to the decor frame of its parent window.
926393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
927393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * @see #setAttachedInDecor(boolean)
928393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR
929393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     */
930393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    public boolean isAttachedInDecor() {
931393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        return mAttachedInDecor;
932393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    }
933393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
934393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    /**
935393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * <p>This will attach the popup window to the decor frame of the parent window to avoid
936393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * overlaping with screen decorations like the navigation bar. Overrides the default behavior of
937393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * the flag {@link WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR}.
938393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
939393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * <p>By default the flag is set on SDK version {@link Build.VERSION_CODES#LOLLIPOP_MR1} or
940393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * greater and cleared on lesser SDK versions.
941393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
942393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * @param enabled true if the popup should be attached to the decor frame of its parent window.
943393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
944393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR
945393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     */
946393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    public void setAttachedInDecor(boolean enabled) {
947393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        mAttachedInDecor = enabled;
948393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        mAttachedInDecorSet = true;
949393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    }
950393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
951393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    /**
9520bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * Allows the popup window to force the flag
9530bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * {@link WindowManager.LayoutParams#FLAG_LAYOUT_INSET_DECOR}, overriding default behavior.
9540bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * This will cause the popup to inset its content to account for system windows overlaying
9550bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * the screen, such as the status bar.
9560bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     *
9570bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * <p>This will often be combined with {@link #setLayoutInScreenEnabled(boolean)}.
9580bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     *
9590bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * @param enabled true if the popup's views should inset content to account for system windows,
9600bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     *                the way that decor views behave for full-screen windows.
9610bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * @hide
9620bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     */
9630bd1d0a15294345bf88b20df28466907f982cec7Adam Powell    public void setLayoutInsetDecor(boolean enabled) {
9640bd1d0a15294345bf88b20df28466907f982cec7Adam Powell        mLayoutInsetDecor = enabled;
9650bd1d0a15294345bf88b20df28466907f982cec7Adam Powell    }
9660bd1d0a15294345bf88b20df28466907f982cec7Adam Powell
9674753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    /** @hide */
9684753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    protected final boolean isLayoutInsetDecor() {
9694753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        return mLayoutInsetDecor;
9704753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    }
9714753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme
9720bd1d0a15294345bf88b20df28466907f982cec7Adam Powell    /**
97380ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette     * Set the layout type for this window.
97480ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette     * <p>
97580ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette     * See {@link WindowManager.LayoutParams#type} for possible values.
976574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell     *
977574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell     * @param layoutType Layout type for this window.
97836344a90c226c90243e4e02bfb13589e120431ddChris Banes     *
97936344a90c226c90243e4e02bfb13589e120431ddChris Banes     * @see WindowManager.LayoutParams#type
980574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell     */
981574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    public void setWindowLayoutType(int layoutType) {
982574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell        mWindowLayoutType = layoutType;
983574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    }
984574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell
985574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    /**
98636344a90c226c90243e4e02bfb13589e120431ddChris Banes     * Returns the layout type for this window.
98736344a90c226c90243e4e02bfb13589e120431ddChris Banes     *
98836344a90c226c90243e4e02bfb13589e120431ddChris Banes     * @see #setWindowLayoutType(int)
989574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell     */
990574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    public int getWindowLayoutType() {
991574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell        return mWindowLayoutType;
992574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    }
993574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell
994574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    /**
995e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell     * Set whether this window is touch modal or if outside touches will be sent to
996e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell     * other windows behind it.
997e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell     * @hide
998e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell     */
999e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell    public void setTouchModal(boolean touchModal) {
1000e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell        mNotTouchModal = !touchModal;
1001e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell    }
1002e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell
1003e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell    /**
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Change the width and height measure specs that are given to the
10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window manager by the popup.  By default these are 0, meaning that
10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the current width or height is requested as an explicit size from
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the window manager.  You can supply
10085435a30ae552391f14009c4459731ae149675b18Alan Viverette     * {@link ViewGroup.LayoutParams#WRAP_CONTENT} or
1009980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy     * {@link ViewGroup.LayoutParams#MATCH_PARENT} to have that measure
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * spec supplied instead, replacing the absolute width and height that
10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * has been set in the popup.</p>
10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown.</p>
10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param widthSpec an explicit width measure spec mode, either
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ViewGroup.LayoutParams#WRAP_CONTENT},
1018980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy     * {@link ViewGroup.LayoutParams#MATCH_PARENT}, or 0 to use the absolute
10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * width.
10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param heightSpec an explicit height measure spec mode, either
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ViewGroup.LayoutParams#WRAP_CONTENT},
1022980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy     * {@link ViewGroup.LayoutParams#MATCH_PARENT}, or 0 to use the absolute
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * height.
1024259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *
1025259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @deprecated Use {@link #setWidth(int)} and {@link #setHeight(int)}.
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1027259c2840691a79634ffd8f63291ec21c21819542Alan Viverette    @Deprecated
10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setWindowLayoutMode(int widthSpec, int heightSpec) {
10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWidthMode = widthSpec;
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHeightMode = heightSpec;
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10325435a30ae552391f14009c4459731ae149675b18Alan Viverette
10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1034c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * Returns the popup's requested height. May be a layout constant such as
1035c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * {@link LayoutParams#WRAP_CONTENT} or {@link LayoutParams#MATCH_PARENT}.
1036c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * <p>
1037c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * The actual size of the popup may depend on other factors such as
1038c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * clipping and window layout.
10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1040c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @return the popup height in pixels or a layout constant
10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setHeight(int)
10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getHeight() {
10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mHeight;
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1048c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * Sets the popup's requested height. May be a layout constant such as
1049c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * {@link LayoutParams#WRAP_CONTENT} or {@link LayoutParams#MATCH_PARENT}.
1050c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * <p>
1051c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * The actual size of the popup may depend on other factors such as
1052c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * clipping and window layout.
1053259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
1054259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * If the popup is showing, calling this method will take effect the next
1055259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * time the popup is shown.
10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1057c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param height the popup height in pixels or a layout constant
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getHeight()
10595435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #isShowing()
10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setHeight(int height) {
10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHeight = height;
10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1066c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * Returns the popup's requested width. May be a layout constant such as
1067c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * {@link LayoutParams#WRAP_CONTENT} or {@link LayoutParams#MATCH_PARENT}.
1068c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * <p>
1069c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * The actual size of the popup may depend on other factors such as
1070c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * clipping and window layout.
10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1072c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @return the popup width in pixels or a layout constant
10735435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #setWidth(int)
10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getWidth() {
10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mWidth;
10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1080c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * Sets the popup's requested width. May be a layout constant such as
1081c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * {@link LayoutParams#WRAP_CONTENT} or {@link LayoutParams#MATCH_PARENT}.
1082c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * <p>
1083c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * The actual size of the popup may depend on other factors such as
1084c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * clipping and window layout.
1085259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
1086259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * If the popup is showing, calling this method will take effect the next
1087259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * time the popup is shown.
10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1089c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param width the popup width in pixels or a layout constant
10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getWidth()
10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isShowing()
10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setWidth(int width) {
10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWidth = width;
10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
109875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * Sets whether the popup window should overlap its anchor view when
109975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * displayed as a drop-down.
110075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * <p>
110175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * If the popup is showing, calling this method will take effect only
110275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * the next time the popup is shown.
110375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     *
110475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * @param overlapAnchor Whether the popup should overlap its anchor.
110575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     *
110675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * @see #getOverlapAnchor()
110775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * @see #isShowing()
110875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     */
110975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    public void setOverlapAnchor(boolean overlapAnchor) {
111075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        mOverlapAnchor = overlapAnchor;
111175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    }
111275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette
111375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    /**
111475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * Returns whether the popup window should overlap its anchor view when
111575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * displayed as a drop-down.
111675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     *
111775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * @return Whether the popup should overlap its anchor.
111875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     *
111975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * @see #setOverlapAnchor(boolean)
112075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     */
112175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    public boolean getOverlapAnchor() {
112275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        return mOverlapAnchor;
112375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    }
112475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette
112575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    /**
11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicate whether this popup window is showing on screen.</p>
11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is showing, false otherwise
11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isShowing() {
11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mIsShowing;
11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11344753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    /** @hide */
11354753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    protected final void setShowing(boolean isShowing) {
11364753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        mIsShowing = isShowing;
11374753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    }
11384753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme
11394753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    /** @hide */
11404753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    protected final void setDropDown(boolean isDropDown) {
11414753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        mIsDropdown = isDropDown;
11424753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    }
11434753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme
11444753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    /** @hide */
11454753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    protected final void setTransitioningToDismiss(boolean transitioningToDismiss) {
11464753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        mIsTransitioningToDismiss = transitioningToDismiss;
11474753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    }
11484753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme
11494753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    /** @hide */
11504753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    protected final boolean isTransitioningToDismiss() {
11514753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        return mIsTransitioningToDismiss;
11524753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    }
11534753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme
11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Display the content view in a popup window at the specified location. If the popup window
11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * cannot fit on screen, it will be clipped. See {@link android.view.WindowManager.LayoutParams}
11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * for more information on how gravity and the x and y parameters are related. Specifying
11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a gravity of {@link android.view.Gravity#NO_GRAVITY} is similar to specifying
11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <code>Gravity.LEFT | Gravity.TOP</code>.
11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </p>
11625435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param parent a parent view to get the {@link android.view.View#getWindowToken()} token from
11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param gravity the gravity which controls the placement of the popup window
11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x the popup's x location offset
11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y the popup's y location offset
11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void showAtLocation(View parent, int gravity, int x, int y) {
116950db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal        mParentRootView = new WeakReference<>(parent.getRootView());
11708ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell        showAtLocation(parent.getWindowToken(), gravity, x, y);
11718ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell    }
11728ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell
11738ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell    /**
11748ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * Display the content view in a popup window at the specified location.
11758ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     *
11768ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * @param token Window token to use for creating the new window
11778ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * @param gravity the gravity which controls the placement of the popup window
11788ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * @param x the popup's x location offset
11798ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * @param y the popup's y location offset
11808ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     *
11818ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * @hide Internal use only. Applications should use
11828ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     *       {@link #showAtLocation(View, int, int, int)} instead.
11838ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     */
11848ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell    public void showAtLocation(IBinder token, int gravity, int x, int y) {
11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isShowing() || mContentView == null) {
11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1189e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        TransitionManager.endTransitions(mDecorView);
1190e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
1191f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        detachFromAnchor();
11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsShowing = true;
11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsDropdown = false;
1195085160612d9066e23c96a6cac15eb3a51481fdafRobert Carr        mGravity = gravity;
11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1197e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        final WindowManager.LayoutParams p = createPopupLayoutParams(token);
11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        preparePopup(p);
1199e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.x = x;
12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.y = y;
1202e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        invokePopup(p);
12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
120775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * Display the content view in a popup window anchored to the bottom-left
12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * corner of the anchor view. If there is not enough room on screen to show
12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the popup in its entirety, this method tries to find a parent scroll
121075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * view to scroll. If no parent scroll view can be scrolled, the
121175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * bottom-left corner of the popup is pinned at the top left corner of the
121275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * anchor view.
12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the view on which to pin the popup window
12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #dismiss()
12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void showAsDropDown(View anchor) {
12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        showAsDropDown(anchor, 0, 0);
12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
122375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * Display the content view in a popup window anchored to the bottom-left
12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * corner of the anchor view offset by the specified x and y coordinates.
122575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * If there is not enough room on screen to show the popup in its entirety,
122675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * this method tries to find a parent scroll view to scroll. If no parent
122775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * scroll view can be scrolled, the bottom-left corner of the popup is
122875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * pinned at the top left corner of the anchor view.
122975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * <p>
123075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * If the view later scrolls to move <code>anchor</code> to a different
123175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * location, the popup will be moved correspondingly.
12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the view on which to pin the popup window
123454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param xoff A horizontal offset from the anchor in pixels
123554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param yoff A vertical offset from the anchor in pixels
12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #dismiss()
12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void showAsDropDown(View anchor, int xoff, int yoff) {
124054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell        showAsDropDown(anchor, xoff, yoff, DEFAULT_ANCHORED_GRAVITY);
124154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell    }
124254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell
124354c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell    /**
124475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * Displays the content view in a popup window anchored to the corner of
124575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * another view. The window is positioned according to the specified
124675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * gravity and offset by the specified x and y coordinates.
124775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * <p>
124875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * If there is not enough room on screen to show the popup in its entirety,
124975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * this method tries to find a parent scroll view to scroll. If no parent
125075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * view can be scrolled, the specified vertical gravity will be ignored and
125175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * the popup will anchor itself such that it is visible.
125275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * <p>
125375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * If the view later scrolls to move <code>anchor</code> to a different
125475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * location, the popup will be moved correspondingly.
125554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     *
125654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param anchor the view on which to pin the popup window
125754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param xoff A horizontal offset from the anchor in pixels
125854c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param yoff A vertical offset from the anchor in pixels
125954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param gravity Alignment of the popup relative to the anchor
126054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     *
126154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @see #dismiss()
126254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     */
126354c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell    public void showAsDropDown(View anchor, int xoff, int yoff, int gravity) {
12644753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        if (isShowing() || !hasContentView()) {
12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1268e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        TransitionManager.endTransitions(mDecorView);
1269e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
1270f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        attachToAnchor(anchor, xoff, yoff, gravity);
12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsShowing = true;
12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsDropdown = true;
12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1275b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev        final WindowManager.LayoutParams p =
1276b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev                createPopupLayoutParams(anchor.getApplicationWindowToken());
12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        preparePopup(p);
12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1279f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final boolean aboveAnchor = findDropDownPosition(anchor, p, xoff, yoff,
128050df07a1add902da01018756c213169e4e126a28Alan Viverette                p.width, p.height, gravity, mAllowScrollingAnchorParent);
1281e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        updateAboveAnchor(aboveAnchor);
1282396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver        p.accessibilityIdOfAnchor = (anchor != null) ? anchor.getAccessibilityViewId() : -1;
12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        invokePopup(p);
12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12874753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    /** @hide */
12884753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    protected final void updateAboveAnchor(boolean aboveAnchor) {
12893e141685003939a9addce21ba2492ea3a8aebee6Romain Guy        if (aboveAnchor != mAboveAnchor) {
12903e141685003939a9addce21ba2492ea3a8aebee6Romain Guy            mAboveAnchor = aboveAnchor;
12913e141685003939a9addce21ba2492ea3a8aebee6Romain Guy
1292697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette            if (mBackground != null && mBackgroundView != null) {
1293697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette                // If the background drawable provided was a StateListDrawable
1294697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette                // with above-anchor and below-anchor states, use those.
1295697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette                // Otherwise, rely on refreshDrawableState to do the job.
12963e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                if (mAboveAnchorBackgroundDrawable != null) {
12973e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                    if (mAboveAnchor) {
1298697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette                        mBackgroundView.setBackground(mAboveAnchorBackgroundDrawable);
12993e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                    } else {
1300697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette                        mBackgroundView.setBackground(mBelowAnchorBackgroundDrawable);
13013e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                    }
13023e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                } else {
1303697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette                    mBackgroundView.refreshDrawableState();
13043e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                }
13053e141685003939a9addce21ba2492ea3a8aebee6Romain Guy            }
13063e141685003939a9addce21ba2492ea3a8aebee6Romain Guy        }
13073e141685003939a9addce21ba2492ea3a8aebee6Romain Guy    }
13083e141685003939a9addce21ba2492ea3a8aebee6Romain Guy
13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Indicates whether the popup is showing above (the y coordinate of the popup's bottom
13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is less than the y coordinate of the anchor) or below the anchor view (the y coordinate
13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of the popup is greater than y coordinate of the anchor's bottom).
13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The value returned
13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by this method is meaningful only after {@link #showAsDropDown(android.view.View)}
13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or {@link #showAsDropDown(android.view.View, int, int)} was invoked.
13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return True if this popup is showing above the anchor view, false otherwise.
13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isAboveAnchor() {
13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mAboveAnchor;
13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1325e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette     * Prepare the popup by embedding it into a new ViewGroup if the background
1326e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette     * drawable is not null. If embedding is required, the layout parameters'
1327e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette     * height is modified to take into account the background's padding.
13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param p the layout parameters of the popup's content view
13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void preparePopup(WindowManager.LayoutParams p) {
1332448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        if (mContentView == null || mContext == null || mWindowManager == null) {
1333448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy            throw new IllegalStateException("You must specify a valid content view by "
1334448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy                    + "calling setContentView() before attempting to show the popup.");
1335448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        }
1336448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy
1337dd6978545fc8123cb4db6d79f09592c42f75e648Phil Weaver        if (p.accessibilityTitle == null) {
1338dd6978545fc8123cb4db6d79f09592c42f75e648Phil Weaver            p.accessibilityTitle = mContext.getString(R.string.popup_window_default_title);
1339dd6978545fc8123cb4db6d79f09592c42f75e648Phil Weaver        }
1340dd6978545fc8123cb4db6d79f09592c42f75e648Phil Weaver
13418fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // The old decor view may be transitioning out. Make sure it finishes
13428fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // and cleans up before we try to create another one.
13438fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        if (mDecorView != null) {
13448fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            mDecorView.cancelTransitions();
13458fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
13468fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
13475435a30ae552391f14009c4459731ae149675b18Alan Viverette        // When a background is available, we embed the content view within
13485435a30ae552391f14009c4459731ae149675b18Alan Viverette        // another view that owns the background drawable.
13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBackground != null) {
1350697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette            mBackgroundView = createBackgroundView(mContentView);
1351697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette            mBackgroundView.setBackground(mBackground);
13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1353697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette            mBackgroundView = mContentView;
13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1355ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
1356697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette        mDecorView = createDecorView(mBackgroundView);
13575435a30ae552391f14009c4459731ae149675b18Alan Viverette
13585435a30ae552391f14009c4459731ae149675b18Alan Viverette        // The background owner should be elevated so that it casts a shadow.
1359697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette        mBackgroundView.setElevation(mElevation);
13605435a30ae552391f14009c4459731ae149675b18Alan Viverette
13615435a30ae552391f14009c4459731ae149675b18Alan Viverette        // We may wrap that in another view, so we'll need to manually specify
13625435a30ae552391f14009c4459731ae149675b18Alan Viverette        // the surface insets.
1363246c209e4fe704c0745224be0ab05225e8431d11Wale Ogunwale        p.setSurfaceInsets(mBackgroundView, true /*manual*/, true /*preservePrevious*/);
13645435a30ae552391f14009c4459731ae149675b18Alan Viverette
1365b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio        mPopupViewInitialLayoutDirectionInherited =
13665435a30ae552391f14009c4459731ae149675b18Alan Viverette                (mContentView.getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT);
13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
13705435a30ae552391f14009c4459731ae149675b18Alan Viverette     * Wraps a content view in a PopupViewContainer.
13715435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
13725435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @param contentView the content view to wrap
13735435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @return a PopupViewContainer that wraps the content view
13745435a30ae552391f14009c4459731ae149675b18Alan Viverette     */
13755435a30ae552391f14009c4459731ae149675b18Alan Viverette    private PopupBackgroundView createBackgroundView(View contentView) {
13765435a30ae552391f14009c4459731ae149675b18Alan Viverette        final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams();
13775435a30ae552391f14009c4459731ae149675b18Alan Viverette        final int height;
13782665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr        if (layoutParams != null && layoutParams.height == WRAP_CONTENT) {
13792665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr            height = WRAP_CONTENT;
13805435a30ae552391f14009c4459731ae149675b18Alan Viverette        } else {
13812665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr            height = MATCH_PARENT;
13825435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
13835435a30ae552391f14009c4459731ae149675b18Alan Viverette
13845435a30ae552391f14009c4459731ae149675b18Alan Viverette        final PopupBackgroundView backgroundView = new PopupBackgroundView(mContext);
13855435a30ae552391f14009c4459731ae149675b18Alan Viverette        final PopupBackgroundView.LayoutParams listParams = new PopupBackgroundView.LayoutParams(
13862665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr                MATCH_PARENT, height);
13875435a30ae552391f14009c4459731ae149675b18Alan Viverette        backgroundView.addView(contentView, listParams);
13885435a30ae552391f14009c4459731ae149675b18Alan Viverette
13895435a30ae552391f14009c4459731ae149675b18Alan Viverette        return backgroundView;
13905435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
13915435a30ae552391f14009c4459731ae149675b18Alan Viverette
13925435a30ae552391f14009c4459731ae149675b18Alan Viverette    /**
13935435a30ae552391f14009c4459731ae149675b18Alan Viverette     * Wraps a content view in a FrameLayout.
13945435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
13955435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @param contentView the content view to wrap
13965435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @return a FrameLayout that wraps the content view
13975435a30ae552391f14009c4459731ae149675b18Alan Viverette     */
13985435a30ae552391f14009c4459731ae149675b18Alan Viverette    private PopupDecorView createDecorView(View contentView) {
13995435a30ae552391f14009c4459731ae149675b18Alan Viverette        final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams();
14005435a30ae552391f14009c4459731ae149675b18Alan Viverette        final int height;
14012665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr        if (layoutParams != null && layoutParams.height == WRAP_CONTENT) {
14022665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr            height = WRAP_CONTENT;
14035435a30ae552391f14009c4459731ae149675b18Alan Viverette        } else {
14042665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr            height = MATCH_PARENT;
14055435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
14065435a30ae552391f14009c4459731ae149675b18Alan Viverette
14075435a30ae552391f14009c4459731ae149675b18Alan Viverette        final PopupDecorView decorView = new PopupDecorView(mContext);
14082665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr        decorView.addView(contentView, MATCH_PARENT, height);
14095435a30ae552391f14009c4459731ae149675b18Alan Viverette        decorView.setClipChildren(false);
14105435a30ae552391f14009c4459731ae149675b18Alan Viverette        decorView.setClipToPadding(false);
14115435a30ae552391f14009c4459731ae149675b18Alan Viverette
14125435a30ae552391f14009c4459731ae149675b18Alan Viverette        return decorView;
14135435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
14145435a30ae552391f14009c4459731ae149675b18Alan Viverette
14155435a30ae552391f14009c4459731ae149675b18Alan Viverette    /**
14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Invoke the popup window by adding the content view to the window
14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * manager.</p>
14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The content view must be non-null when this method is invoked.</p>
14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param p the layout parameters of the popup's content view
14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void invokePopup(WindowManager.LayoutParams p) {
14240c0b768e1514280812321854db6dfba723c3d169Romain Guy        if (mContext != null) {
14250c0b768e1514280812321854db6dfba723c3d169Romain Guy            p.packageName = mContext.getPackageName();
14260c0b768e1514280812321854db6dfba723c3d169Romain Guy        }
14275435a30ae552391f14009c4459731ae149675b18Alan Viverette
14288fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        final PopupDecorView decorView = mDecorView;
14298fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        decorView.setFitsSystemWindows(mLayoutInsetDecor);
14305435a30ae552391f14009c4459731ae149675b18Alan Viverette
14318fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        setLayoutDirectionFromAnchor();
14325435a30ae552391f14009c4459731ae149675b18Alan Viverette
14338fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        mWindowManager.addView(decorView, p);
143495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette
143595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        if (mEnterTransition != null) {
143695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            decorView.requestEnterTransition(mEnterTransition);
143795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        }
14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1440b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio    private void setLayoutDirectionFromAnchor() {
1441b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio        if (mAnchor != null) {
1442b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio            View anchor = mAnchor.get();
1443b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio            if (anchor != null && mPopupViewInitialLayoutDirectionInherited) {
14445435a30ae552391f14009c4459731ae149675b18Alan Viverette                mDecorView.setLayoutDirection(anchor.getLayoutDirection());
1445b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio            }
1446b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio        }
1447b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio    }
1448b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio
1449489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr    private int computeGravity() {
1450085160612d9066e23c96a6cac15eb3a51481fdafRobert Carr        int gravity = mGravity == Gravity.NO_GRAVITY ?  Gravity.START | Gravity.TOP : mGravity;
1451085160612d9066e23c96a6cac15eb3a51481fdafRobert Carr        if (mIsDropdown && (mClipToScreen || mClippingEnabled)) {
14529705fa0602290b56edc81f64bfcba38f159069b1Alan Viverette            gravity |= Gravity.DISPLAY_CLIP_VERTICAL;
1453489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr        }
1454489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr        return gravity;
1455489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr    }
1456489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr
14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Generate the layout parameters for the popup window.</p>
14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param token the window token used to bind the popup's window
14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the layout parameters to pass to the window manager
14634753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme     *
14644753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme     * @hide
14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
14664753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    protected final WindowManager.LayoutParams createPopupLayoutParams(IBinder token) {
1467e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        final WindowManager.LayoutParams p = new WindowManager.LayoutParams();
1468e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
1469e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        // These gravity settings put the view at the top left corner of the
1470e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        // screen. The view is then positioned to the appropriate location by
1471e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        // setting the x and y offsets to match the anchor's bottom-left
1472e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        // corner.
1473489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr        p.gravity = computeGravity();
1474e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        p.flags = computeFlags(p.flags);
1475e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        p.type = mWindowLayoutType;
1476e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        p.token = token;
1477e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        p.softInputMode = mSoftInputMode;
1478e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        p.windowAnimations = computeAnimationResource();
1479e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBackground != null) {
14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.format = mBackground.getOpacity();
14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.format = PixelFormat.TRANSLUCENT;
14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1485e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
1486e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        if (mHeightMode < 0) {
1487e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            p.height = mLastHeight = mHeightMode;
1488e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        } else {
1489e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            p.height = mLastHeight = mHeight;
1490e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        }
1491e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
1492e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        if (mWidthMode < 0) {
1493e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            p.width = mLastWidth = mWidthMode;
1494e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        } else {
1495e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            p.width = mLastWidth = mWidth;
1496e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        }
1497e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
14988216eb2221ad5ad6615d3966f43844268756f3c8Wale Ogunwale        p.privateFlags = PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH
14998216eb2221ad5ad6615d3966f43844268756f3c8Wale Ogunwale                | PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME;
1500a1eb439eee65138280c560f96e2a6896f9c9112cRobert Carr
1501e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        // Used for debugging.
15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.setTitle("PopupWindow:" + Integer.toHexString(hashCode()));
15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return p;
15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int computeFlags(int curFlags) {
15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        curFlags &= ~(
15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES |
15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |
1514ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell                WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
1515ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell                WindowManager.LayoutParams.FLAG_SPLIT_TOUCH);
15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if(mIgnoreCheekPress) {
15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES;
15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mFocusable) {
15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mInputMethodMode == INPUT_METHOD_NEEDED) {
15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (mInputMethodMode == INPUT_METHOD_NOT_NEEDED) {
15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mTouchable) {
15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1530c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project        if (mOutsideTouchable) {
15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1533cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr        if (!mClippingEnabled || mClipToScreen) {
15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
153646e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown        if (isSplitTouchEnabled()) {
153701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            curFlags |= WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
153801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        }
1539ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell        if (mLayoutInScreen) {
1540ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell            curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
1541ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell        }
15420bd1d0a15294345bf88b20df28466907f982cec7Adam Powell        if (mLayoutInsetDecor) {
15430bd1d0a15294345bf88b20df28466907f982cec7Adam Powell            curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
15440bd1d0a15294345bf88b20df28466907f982cec7Adam Powell        }
1545e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell        if (mNotTouchModal) {
1546e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell            curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
1547e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell        }
1548393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        if (mAttachedInDecor) {
15494753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme            curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR;
1550393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        }
15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return curFlags;
15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1553393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int computeAnimationResource() {
15555435a30ae552391f14009c4459731ae149675b18Alan Viverette        if (mAnimationStyle == ANIMATION_STYLE_DEFAULT) {
15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mIsDropdown) {
15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return mAboveAnchor
15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ? com.android.internal.R.style.Animation_DropDownUp
15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        : com.android.internal.R.style.Animation_DropDownDown;
15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mAnimationStyle;
15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1565560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1567560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * Positions the popup window on screen. When the popup window is too tall
1568560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * to fit under the anchor, a parent scroll view is seeked and scrolled up
1569560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * to reclaim space. If scrolling is not possible or not enough, the popup
1570560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * window gets moved on top of the anchor.
1571560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * <p>
1572f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette     * The results of positioning are placed in {@code outParams}.
15735435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the view on which the popup window must be anchored
1575f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette     * @param outParams the layout parameters used to display the drop down
15769125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette     * @param xOffset absolute horizontal offset from the left of the anchor
15776acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette     * @param yOffset absolute vertical offset from the top of the anchor
1578560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * @param gravity horizontal gravity specifying popup alignment
157950df07a1add902da01018756c213169e4e126a28Alan Viverette     * @param allowScroll whether the anchor view's parent may be scrolled
158050df07a1add902da01018756c213169e4e126a28Alan Viverette     *                    when the popup window doesn't fit on screen
15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is translated upwards to fit on screen
15824753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme     *
15834753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme     * @hide
15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
15854753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    protected final boolean findDropDownPosition(View anchor, WindowManager.LayoutParams outParams,
158650df07a1add902da01018756c213169e4e126a28Alan Viverette            int xOffset, int yOffset, int width, int height, int gravity, boolean allowScroll) {
158762e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell        final int anchorHeight = anchor.getHeight();
1588560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        final int anchorWidth = anchor.getWidth();
1589560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        if (mOverlapAnchor) {
1590f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette            yOffset -= anchorHeight;
1591560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        }
1592560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
15936acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette        // Initially, align to the bottom-left corner of the anchor plus offsets.
1594b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev        final int[] appScreenLocation = mTmpAppLocation;
1595b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev        final View appRootView = getAppRootView(anchor);
1596b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev        appRootView.getLocationOnScreen(appScreenLocation);
1597b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev
1598b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev        final int[] screenLocation = mTmpScreenLocation;
1599b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev        anchor.getLocationOnScreen(screenLocation);
1600b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev
1601f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final int[] drawingLocation = mTmpDrawingLocation;
1602b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev        drawingLocation[0] = screenLocation[0] - appScreenLocation[0];
1603b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev        drawingLocation[1] = screenLocation[1] - appScreenLocation[1];
1604f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        outParams.x = drawingLocation[0] + xOffset;
1605f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        outParams.y = drawingLocation[1] + anchorHeight + yOffset;
160654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell
1607f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr        final Rect displayFrame = new Rect();
1608b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev        appRootView.getWindowVisibleDisplayFrame(displayFrame);
16092665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr        if (width == MATCH_PARENT) {
1610f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr            width = displayFrame.right - displayFrame.left;
1611f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr        }
16122665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr        if (height == MATCH_PARENT) {
1613f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr            height = displayFrame.bottom - displayFrame.top;
1614f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr        }
1615f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr
1616cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr        // Let the window manager know to align the top to y.
16178367c50972ee4fce55ac483441125b8b09af5eaeRobert Carr        outParams.gravity = computeGravity();
1618cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr        outParams.width = width;
1619cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr        outParams.height = height;
1620cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr
16216acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette        // If we need to adjust for gravity RIGHT, align to the bottom-right
16226acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette        // corner of the anchor (still accounting for offsets).
1623560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        final int hgrav = Gravity.getAbsoluteGravity(gravity, anchor.getLayoutDirection())
1624560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette                & Gravity.HORIZONTAL_GRAVITY_MASK;
162554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell        if (hgrav == Gravity.RIGHT) {
1626f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette            outParams.x -= width - anchorWidth;
162754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell        }
1628560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
16299125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        // First, attempt to fit the popup vertically without resizing.
16309125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        final boolean fitsVertical = tryFitVertical(outParams, yOffset, height,
16319125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                anchorHeight, drawingLocation[1], screenLocation[1], displayFrame.top,
16329125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                displayFrame.bottom, false);
16339125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
16349125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        // Next, attempt to fit the popup horizontally without resizing.
16359125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        final boolean fitsHorizontal = tryFitHorizontal(outParams, xOffset, width,
16369125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                anchorWidth, drawingLocation[0], screenLocation[0], displayFrame.left,
16379125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                displayFrame.right, false);
16389125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
16399125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        // If the popup still doesn't fit, attempt to scroll the parent.
16409125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        if (!fitsVertical || !fitsHorizontal) {
16419125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            final int scrollX = anchor.getScrollX();
16429125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            final int scrollY = anchor.getScrollY();
16439125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            final Rect r = new Rect(scrollX, scrollY, scrollX + width + xOffset,
16449125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                    scrollY + height + anchorHeight + yOffset);
164550df07a1add902da01018756c213169e4e126a28Alan Viverette            if (allowScroll && anchor.requestRectangleOnScreen(r, true)) {
16469125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                // Reset for the new anchor position.
1647b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev                anchor.getLocationOnScreen(screenLocation);
1648b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev                drawingLocation[0] = screenLocation[0] - appScreenLocation[0];
1649b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev                drawingLocation[1] = screenLocation[1] - appScreenLocation[1];
16509125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                outParams.x = drawingLocation[0] + xOffset;
16519125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                outParams.y = drawingLocation[1] + anchorHeight + yOffset;
16529125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
16539125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                // Preserve the gravity adjustment.
16549125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                if (hgrav == Gravity.RIGHT) {
16559125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                    outParams.x -= width - anchorWidth;
16569125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                }
1657b7c1b20c8a5a4d4378ae91b4a1f12a34100df452Adam Powell            }
16583e141685003939a9addce21ba2492ea3a8aebee6Romain Guy
16599125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            // Try to fit the popup again and allowing resizing.
16609125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            tryFitVertical(outParams, yOffset, height, anchorHeight, drawingLocation[1],
16619125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                    screenLocation[1], displayFrame.top, displayFrame.bottom, mClipToScreen);
16629125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            tryFitHorizontal(outParams, xOffset, width, anchorWidth, drawingLocation[0],
16639125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                    screenLocation[0], displayFrame.left, displayFrame.right, mClipToScreen);
16649125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        }
166554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell
16669125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        // Return whether the popup's top edge is above the anchor's top edge.
16679125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        return outParams.y < drawingLocation[1];
16689125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette    }
1669560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
16709125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette    private boolean tryFitVertical(@NonNull LayoutParams outParams, int yOffset, int height,
16719125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            int anchorHeight, int drawingLocationY, int screenLocationY, int displayFrameTop,
16729125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            int displayFrameBottom, boolean allowResize) {
167355f0a99076477b77e017454e4356d908c43c2d22Alan Viverette        final int winOffsetY = screenLocationY - drawingLocationY;
16743b105d92a5913777a8a89bdce8647da5e27267b7Vladislav Kaznacheev        final int anchorTopInScreen = outParams.y + winOffsetY;
16753b105d92a5913777a8a89bdce8647da5e27267b7Vladislav Kaznacheev        final int spaceBelow = displayFrameBottom - anchorTopInScreen;
16763b105d92a5913777a8a89bdce8647da5e27267b7Vladislav Kaznacheev        if (anchorTopInScreen >= 0 && height <= spaceBelow) {
16779125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            return true;
16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16803b105d92a5913777a8a89bdce8647da5e27267b7Vladislav Kaznacheev        final int spaceAbove = anchorTopInScreen - anchorHeight - displayFrameTop;
16819125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        if (height <= spaceAbove) {
16829125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            // Move everything up.
16839125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            if (mOverlapAnchor) {
16843b105d92a5913777a8a89bdce8647da5e27267b7Vladislav Kaznacheev                yOffset += anchorHeight;
168556c2d337e02a275397fc9d0460dca90977f199acAdam Powell            }
16869125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            outParams.y = drawingLocationY - height + yOffset;
16879125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
16889125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            return true;
16899125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        }
1690560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
16919125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        if (positionInDisplayVertical(outParams, height, drawingLocationY, screenLocationY,
16929125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                displayFrameTop, displayFrameBottom, allowResize)) {
16939125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            return true;
16949125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        }
1695f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette
16969125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        return false;
16979125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette    }
169856c2d337e02a275397fc9d0460dca90977f199acAdam Powell
16999125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette    private boolean positionInDisplayVertical(@NonNull LayoutParams outParams, int height,
17009125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            int drawingLocationY, int screenLocationY, int displayFrameTop, int displayFrameBottom,
17019125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            boolean canResize) {
17029125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        boolean fitsInDisplay = true;
17036acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette
17049125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        final int winOffsetY = screenLocationY - drawingLocationY;
17059125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        outParams.y += winOffsetY;
17069125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        outParams.height = height;
17079125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
17089125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        final int bottom = outParams.y + height;
17099125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        if (bottom > displayFrameBottom) {
17109125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            // The popup is too far down, move it back in.
17119125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            outParams.y -= bottom - displayFrameBottom;
17129125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        }
17136acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette
17149125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        if (outParams.y < displayFrameTop) {
17159125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            // The popup is too far up, move it back in and clip if
17169125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            // it's still too large.
17179125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            outParams.y = displayFrameTop;
17189125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
17199125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            final int displayFrameHeight = displayFrameBottom - displayFrameTop;
17209125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            if (canResize && height > displayFrameHeight) {
17219125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                outParams.height = displayFrameHeight;
17229125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            } else {
17239125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                fitsInDisplay = false;
17245f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell            }
17259125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        }
17269125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
17279125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        outParams.y -= winOffsetY;
1728f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette
17299125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        return fitsInDisplay;
17309125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette    }
17319125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
17329125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette    private boolean tryFitHorizontal(@NonNull LayoutParams outParams, int xOffset, int width,
17339125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            int anchorWidth, int drawingLocationX, int screenLocationX, int displayFrameLeft,
17349125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            int displayFrameRight, boolean allowResize) {
173555f0a99076477b77e017454e4356d908c43c2d22Alan Viverette        final int winOffsetX = screenLocationX - drawingLocationX;
173655f0a99076477b77e017454e4356d908c43c2d22Alan Viverette        final int anchorLeftInScreen = outParams.x + winOffsetX;
17379125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        final int spaceRight = displayFrameRight - anchorLeftInScreen;
173855f0a99076477b77e017454e4356d908c43c2d22Alan Viverette        if (anchorLeftInScreen >= 0 && width <= spaceRight) {
17399125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            return true;
174056c2d337e02a275397fc9d0460dca90977f199acAdam Powell        }
174156c2d337e02a275397fc9d0460dca90977f199acAdam Powell
17429125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        if (positionInDisplayHorizontal(outParams, width, drawingLocationX, screenLocationX,
17439125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                displayFrameLeft, displayFrameRight, allowResize)) {
17449125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            return true;
17459125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        }
17469125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
17479125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        return false;
17489125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette    }
17499125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
17509125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette    private boolean positionInDisplayHorizontal(@NonNull LayoutParams outParams, int width,
17519125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            int drawingLocationX, int screenLocationX, int displayFrameLeft, int displayFrameRight,
17529125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            boolean canResize) {
17539125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        boolean fitsInDisplay = true;
17549125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
17559125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        // Use screen coordinates for comparison against display frame.
17569125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        final int winOffsetX = screenLocationX - drawingLocationX;
17579125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        outParams.x += winOffsetX;
17589125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
17599125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        final int right = outParams.x + width;
17609125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        if (right > displayFrameRight) {
17619125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            // The popup is too far right, move it back in.
17629125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            outParams.x -= right - displayFrameRight;
17639125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        }
17649125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
17659125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        if (outParams.x < displayFrameLeft) {
17669125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            // The popup is too far left, move it back in and clip if it's
17679125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            // still too large.
17689125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            outParams.x = displayFrameLeft;
17699125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
17709125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            final int displayFrameWidth = displayFrameRight - displayFrameLeft;
17719125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            if (canResize && width > displayFrameWidth) {
17729125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                outParams.width = displayFrameWidth;
17739125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            } else {
17749125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette                fitsInDisplay = false;
17759125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette            }
17769125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        }
17779125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette
17789125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        outParams.x -= winOffsetX;
1779560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
17809125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette        return fitsInDisplay;
17819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17825435a30ae552391f14009c4459731ae149675b18Alan Viverette
17839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the maximum height that is available for the popup to be
17859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * completely shown. It is recommended that this height be the maximum for
17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the popup's height, otherwise it is possible that the popup will be
17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * clipped.
17885435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
17899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor The view on which the popup window must be anchored.
17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The maximum available height for the popup to be completely
17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         shown.
17929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1793b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette    public int getMaxAvailableHeight(@NonNull View anchor) {
17949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return getMaxAvailableHeight(anchor, 0);
17959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the maximum height that is available for the popup to be
17999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * completely shown. It is recommended that this height be the maximum for
18009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the popup's height, otherwise it is possible that the popup will be
18019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * clipped.
18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor The view on which the popup window must be anchored.
18049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param yOffset y offset from the view's bottom edge
18059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The maximum available height for the popup to be completely
18069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         shown.
18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1808b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette    public int getMaxAvailableHeight(@NonNull View anchor, int yOffset) {
180998acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau        return getMaxAvailableHeight(anchor, yOffset, false);
181098acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau    }
18115435a30ae552391f14009c4459731ae149675b18Alan Viverette
181298acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau    /**
181398acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * Returns the maximum height that is available for the popup to be
181498acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * completely shown, optionally ignoring any bottom decorations such as
181598acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * the input method. It is recommended that this height be the maximum for
181698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * the popup's height, otherwise it is possible that the popup will be
181798acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * clipped.
18185435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
181998acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * @param anchor The view on which the popup window must be anchored.
182098acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * @param yOffset y offset from the view's bottom edge
182198acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * @param ignoreBottomDecorations if true, the height returned will be
182298acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     *        all the way to the bottom of the display, ignoring any
182398acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     *        bottom decorations
182498acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * @return The maximum available height for the popup to be completely
182598acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     *         shown.
182698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     */
1827b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette    public int getMaxAvailableHeight(
1828b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette            @NonNull View anchor, int yOffset, boolean ignoreBottomDecorations) {
1829701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr        Rect displayFrame = null;
1830701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr        final Rect visibleDisplayFrame = new Rect();
1831701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr
1832b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev        final View appView = getAppRootView(anchor);
1833b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev        appView.getWindowVisibleDisplayFrame(visibleDisplayFrame);
18348175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi        if (ignoreBottomDecorations) {
1835701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr            // In the ignore bottom decorations case we want to
1836701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr            // still respect all other decorations so we use the inset visible
1837701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr            // frame on the top right and left and take the bottom
1838701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr            // value from the full frame.
1839701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr            displayFrame = new Rect();
18408175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi            anchor.getWindowDisplayFrame(displayFrame);
1841701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr            displayFrame.top = visibleDisplayFrame.top;
1842701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr            displayFrame.right = visibleDisplayFrame.right;
1843701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr            displayFrame.left = visibleDisplayFrame.left;
18448175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi        } else {
1845701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr            displayFrame = visibleDisplayFrame;
18468175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi        }
18479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1848f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final int[] anchorPos = mTmpDrawingLocation;
18499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        anchor.getLocationOnScreen(anchorPos);
18505435a30ae552391f14009c4459731ae149675b18Alan Viverette
18518175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi        final int bottomEdge = displayFrame.bottom;
1852ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg
1853ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg        final int distanceToBottom;
1854ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg        if (mOverlapAnchor) {
1855ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg            distanceToBottom = bottomEdge - anchorPos[1] - yOffset;
1856ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg        } else {
1857ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg            distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset;
1858ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg        }
18599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset;
18609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // anchorPos[1] is distance from anchor to top of screen
18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int returnedHeight = Math.max(distanceToBottom, distanceToTop);
18639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBackground != null) {
18649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mBackground.getPadding(mTempRect);
18655435a30ae552391f14009c4459731ae149675b18Alan Viverette            returnedHeight -= mTempRect.top + mTempRect.bottom;
18669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18675435a30ae552391f14009c4459731ae149675b18Alan Viverette
18689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return returnedHeight;
18699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18705435a30ae552391f14009c4459731ae149675b18Alan Viverette
18719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18727878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette     * Disposes of the popup window. This method can be invoked only after
18737878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette     * {@link #showAsDropDown(android.view.View)} has been executed. Failing
18747878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette     * that, calling this method will have no effect.
18759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18765435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #showAsDropDown(android.view.View)
18779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void dismiss() {
18794753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        if (!isShowing() || isTransitioningToDismiss()) {
1880e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            return;
1881e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        }
188206f938e8aa56cd89ab0bdb04c8b946392c428dd1Svetoslav Ganov
18838fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        final PopupDecorView decorView = mDecorView;
18848fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        final View contentView = mContentView;
18858fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
18868fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        final ViewGroup contentHolder;
18878fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        final ViewParent contentParent = contentView.getParent();
18888fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        if (contentParent instanceof ViewGroup) {
18898fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            contentHolder = ((ViewGroup) contentParent);
18908fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        } else {
18918fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            contentHolder = null;
18928fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
18938fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
18948fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // Ensure any ongoing or pending transitions are canceled.
18958fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        decorView.cancelTransitions();
18968fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
1897e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        mIsShowing = false;
18988fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        mIsTransitioningToDismiss = true;
1899b82d074038f4c8d86e1bd4f3fa4d3780bd4bcba5Craig Mautner
1900634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        // This method may be called as part of window detachment, in which
1901634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        // case the anchor view (and its root) will still return true from
1902634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        // isAttachedToWindow() during execution of this method; however, we
1903634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        // can expect the OnAttachStateChangeListener to have been called prior
1904634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        // to executing this method, so we can rely on that instead.
190595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final Transition exitTransition = mExitTransition;
1906054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette        if (exitTransition != null && decorView.isLaidOut()
1907054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette                && (mIsAnchorRootAttached || mAnchorRoot == null)) {
1908dbd299de2a07a2a0a490d4f37cf92870bf87d6c1Yohei Yukawa            // The decor view is non-interactive and non-IME-focusable during exit transitions.
190995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            final LayoutParams p = (LayoutParams) decorView.getLayoutParams();
191095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            p.flags |= LayoutParams.FLAG_NOT_TOUCHABLE;
191195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            p.flags |= LayoutParams.FLAG_NOT_FOCUSABLE;
1912dbd299de2a07a2a0a490d4f37cf92870bf87d6c1Yohei Yukawa            p.flags &= ~LayoutParams.FLAG_ALT_FOCUSABLE_IM;
191395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            mWindowManager.updateViewLayout(decorView, p);
191495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette
1915054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette            final View anchorRoot = mAnchorRoot != null ? mAnchorRoot.get() : null;
1916054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette            final Rect epicenter = getTransitionEpicenter();
1917054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette
1918634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            // Once we start dismissing the decor view, all state (including
1919634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            // the anchor root) needs to be moved to the decor view since we
1920634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            // may open another popup while it's busy exiting.
1921054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette            decorView.startExitTransition(exitTransition, anchorRoot, epicenter,
1922634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    new TransitionListenerAdapter() {
1923634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                        @Override
1924634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                        public void onTransitionEnd(Transition transition) {
19257970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette                            dismissImmediate(decorView, contentHolder, contentView);
1926634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                        }
1927634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    });
1928e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        } else {
19297970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette            dismissImmediate(decorView, contentHolder, contentView);
19307878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette        }
19317878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette
193295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        // Clears the anchor view.
1933f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        detachFromAnchor();
19347970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette
19357970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette        if (mOnDismissListener != null) {
19367970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette            mOnDismissListener.onDismiss();
19377970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette        }
19385435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
19395435a30ae552391f14009c4459731ae149675b18Alan Viverette
194091098574f90277128415e9593cce1e495cc51465Alan Viverette    /**
194191098574f90277128415e9593cce1e495cc51465Alan Viverette     * Returns the window-relative epicenter bounds to be used by enter and
194291098574f90277128415e9593cce1e495cc51465Alan Viverette     * exit transitions.
194391098574f90277128415e9593cce1e495cc51465Alan Viverette     * <p>
194491098574f90277128415e9593cce1e495cc51465Alan Viverette     * <strong>Note:</strong> This is distinct from the rect passed to
194591098574f90277128415e9593cce1e495cc51465Alan Viverette     * {@link #setEpicenterBounds(Rect)}, which is anchor-relative.
194691098574f90277128415e9593cce1e495cc51465Alan Viverette     *
194791098574f90277128415e9593cce1e495cc51465Alan Viverette     * @return the window-relative epicenter bounds to be used by enter and
194891098574f90277128415e9593cce1e495cc51465Alan Viverette     *         exit transitions
19494753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme     *
19504753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme     * @hide
195191098574f90277128415e9593cce1e495cc51465Alan Viverette     */
19524753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    protected final Rect getTransitionEpicenter() {
195395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final View anchor = mAnchor != null ? mAnchor.get() : null;
195495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final View decor = mDecorView;
195595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        if (anchor == null || decor == null) {
195695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            return null;
195795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        }
195895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette
195995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final int[] anchorLocation = anchor.getLocationOnScreen();
196095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final int[] popupLocation = mDecorView.getLocationOnScreen();
196195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette
196295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        // Compute the position of the anchor relative to the popup.
196395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final Rect bounds = new Rect(0, 0, anchor.getWidth(), anchor.getHeight());
196495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        bounds.offset(anchorLocation[0] - popupLocation[0], anchorLocation[1] - popupLocation[1]);
196591098574f90277128415e9593cce1e495cc51465Alan Viverette
196691098574f90277128415e9593cce1e495cc51465Alan Viverette        // Use anchor-relative epicenter, if specified.
196791098574f90277128415e9593cce1e495cc51465Alan Viverette        if (mEpicenterBounds != null) {
196891098574f90277128415e9593cce1e495cc51465Alan Viverette            final int offsetX = bounds.left;
196991098574f90277128415e9593cce1e495cc51465Alan Viverette            final int offsetY = bounds.top;
197091098574f90277128415e9593cce1e495cc51465Alan Viverette            bounds.set(mEpicenterBounds);
197191098574f90277128415e9593cce1e495cc51465Alan Viverette            bounds.offset(offsetX, offsetY);
197291098574f90277128415e9593cce1e495cc51465Alan Viverette        }
197391098574f90277128415e9593cce1e495cc51465Alan Viverette
197495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        return bounds;
197595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette    }
197695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette
19775435a30ae552391f14009c4459731ae149675b18Alan Viverette    /**
19785435a30ae552391f14009c4459731ae149675b18Alan Viverette     * Removes the popup from the window manager and tears down the supporting
19795435a30ae552391f14009c4459731ae149675b18Alan Viverette     * view hierarchy, if necessary.
19805435a30ae552391f14009c4459731ae149675b18Alan Viverette     */
19817970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette    private void dismissImmediate(View decorView, ViewGroup contentHolder, View contentView) {
19828fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // If this method gets called and the decor view doesn't have a parent,
19838fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // then it was either never added or was already removed. That should
19848fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // never happen, but it's worth checking to avoid potential crashes.
19858fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        if (decorView.getParent() != null) {
19868fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            mWindowManager.removeViewImmediate(decorView);
1987df4639a0135ea643b493067b3f7cd1e092346c78Alan Viverette        }
1988df4639a0135ea643b493067b3f7cd1e092346c78Alan Viverette
19898fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        if (contentHolder != null) {
19908fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            contentHolder.removeView(contentView);
19919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19928fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
19938fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // This needs to stay until after all transitions have ended since we
19948fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // need the reference to cancel transitions in preparePopup().
19958fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        mDecorView = null;
1996697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette        mBackgroundView = null;
19978fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        mIsTransitioningToDismiss = false;
19989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
20019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the listener to be called when the window is dismissed.
20025435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
20039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param onDismissListener The listener.
20049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
20059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setOnDismissListener(OnDismissListener onDismissListener) {
20069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOnDismissListener = onDismissListener;
20079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20085435a30ae552391f14009c4459731ae149675b18Alan Viverette
20094753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    /** @hide */
20104753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    protected final OnDismissListener getOnDismissListener() {
20114753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        return mOnDismissListener;
20124753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    }
20134753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme
20149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
20159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Updates the state of the popup window, if it is currently being displayed,
2016259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * from the currently set state.
2017259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
2018259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * This includes:
2019259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <ul>
2020259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setClippingEnabled(boolean)}</li>
2021259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setFocusable(boolean)}</li>
2022259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setIgnoreCheekPress()}</li>
2023259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setInputMethodMode(int)}</li>
2024259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setTouchable(boolean)}</li>
2025259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setAnimationStyle(int)}</li>
2026259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * </ul>
20279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
20289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update() {
20294753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        if (!isShowing() || !hasContentView()) {
20309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
20319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20325435a30ae552391f14009c4459731ae149675b18Alan Viverette
20334753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        final WindowManager.LayoutParams p = getDecorViewLayoutParams();
20345435a30ae552391f14009c4459731ae149675b18Alan Viverette
20359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean update = false;
20365435a30ae552391f14009c4459731ae149675b18Alan Viverette
20379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int newAnim = computeAnimationResource();
20389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newAnim != p.windowAnimations) {
20399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.windowAnimations = newAnim;
20409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
20419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int newFlags = computeFlags(p.flags);
20449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newFlags != p.flags) {
20459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.flags = newFlags;
20469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
20479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2048b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio
2049489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr        final int newGravity = computeGravity();
2050489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr        if (newGravity != p.gravity) {
2051489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr            p.gravity = newGravity;
2052489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr            update = true;
2053489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr        }
2054489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr
20559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (update) {
20566f7971701499cc7558e7476ee6bb4e62a39d10fdFelipe Leme            update(mAnchor != null ? mAnchor.get() : null, p);
20579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2059d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy
20604753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    /** @hide */
20614753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    protected void update(View anchor, WindowManager.LayoutParams params) {
20624753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        setLayoutDirectionFromAnchor();
20634753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        mWindowManager.updateViewLayout(mDecorView, params);
20644753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    }
20654753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme
2066d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy    /**
2067259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Updates the dimension of the popup window.
2068259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
2069259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Calling this function also updates the window with the current popup
2070259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * state as described for {@link #update()}.
2071d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy     *
2072c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param width the new width in pixels, must be >= 0 or -1 to ignore
2073c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param height the new height in pixels, must be >= 0 or -1 to ignore
2074d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy     */
2075d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy    public void update(int width, int height) {
20764753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        final WindowManager.LayoutParams p = getDecorViewLayoutParams();
2077d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy        update(p.x, p.y, width, height, false);
2078d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy    }
20795435a30ae552391f14009c4459731ae149675b18Alan Viverette
20809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2081259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Updates the position and the dimension of the popup window.
2082259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
2083259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Width and height can be set to -1 to update location only. Calling this
2084259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * function also updates the window with the current popup state as
2085259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * described for {@link #update()}.
20869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
20879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x the new x location
20889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y the new y location
2089c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param width the new width in pixels, must be >= 0 or -1 to ignore
2090c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param height the new height in pixels, must be >= 0 or -1 to ignore
20919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
20929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update(int x, int y, int width, int height) {
20939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        update(x, y, width, height, false);
20949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2097259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Updates the position and the dimension of the popup window.
2098259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
2099259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Width and height can be set to -1 to update location only. Calling this
2100259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * function also updates the window with the current popup state as
2101259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * described for {@link #update()}.
21029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
21039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x the new x location
21049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y the new y location
2105c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param width the new width in pixels, must be >= 0 or -1 to ignore
2106c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param height the new height in pixels, must be >= 0 or -1 to ignore
2107259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param force {@code true} to reposition the window even if the specified
2108259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *              position already seems to correspond to the LayoutParams,
2109259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *              {@code false} to only reposition if needed
21109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
21119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update(int x, int y, int width, int height, boolean force) {
2112259c2840691a79634ffd8f63291ec21c21819542Alan Viverette        if (width >= 0) {
21139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mLastWidth = width;
21149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setWidth(width);
21159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2117259c2840691a79634ffd8f63291ec21c21819542Alan Viverette        if (height >= 0) {
21189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mLastHeight = height;
21199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setHeight(height);
21209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21224753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        if (!isShowing() || !hasContentView()) {
21239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
21249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21264753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        final WindowManager.LayoutParams p = getDecorViewLayoutParams();
21279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean update = force;
21299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int finalWidth = mWidthMode < 0 ? mWidthMode : mLastWidth;
21319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (width != -1 && p.width != finalWidth) {
21329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.width = mLastWidth = finalWidth;
21339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
21349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int finalHeight = mHeightMode < 0 ? mHeightMode : mLastHeight;
21379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (height != -1 && p.height != finalHeight) {
21389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.height = mLastHeight = finalHeight;
21399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
21409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p.x != x) {
21439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.x = x;
21449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
21459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p.y != y) {
21489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.y = y;
21499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
21509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int newAnim = computeAnimationResource();
21539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newAnim != p.windowAnimations) {
21549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.windowAnimations = newAnim;
21559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
21569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int newFlags = computeFlags(p.flags);
21599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newFlags != p.flags) {
21609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.flags = newFlags;
21619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
21629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
216398acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau
2164489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr        final int newGravity = computeGravity();
2165489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr        if (newGravity != p.gravity) {
2166489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr            p.gravity = newGravity;
2167489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr            update = true;
2168489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr        }
2169489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr
2170dd23777dfbbe6299f5e07584c69c73ea0835fe46Felipe Leme        View anchor = null;
2171dd23777dfbbe6299f5e07584c69c73ea0835fe46Felipe Leme        int newAccessibilityIdOfAnchor = -1;
2172dd23777dfbbe6299f5e07584c69c73ea0835fe46Felipe Leme
2173dd23777dfbbe6299f5e07584c69c73ea0835fe46Felipe Leme        if (mAnchor != null && mAnchor.get() != null) {
2174dd23777dfbbe6299f5e07584c69c73ea0835fe46Felipe Leme            anchor = mAnchor.get();
2175dd23777dfbbe6299f5e07584c69c73ea0835fe46Felipe Leme            newAccessibilityIdOfAnchor = anchor.getAccessibilityViewId();
2176dd23777dfbbe6299f5e07584c69c73ea0835fe46Felipe Leme        }
2177dd23777dfbbe6299f5e07584c69c73ea0835fe46Felipe Leme
2178396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver        if (newAccessibilityIdOfAnchor != p.accessibilityIdOfAnchor) {
2179396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver            p.accessibilityIdOfAnchor = newAccessibilityIdOfAnchor;
2180396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver            update = true;
2181396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver        }
2182396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver
21839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (update) {
21844753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme            update(anchor, p);
21859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21884753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    /** @hide */
21894753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    protected boolean hasContentView() {
21904753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        return mContentView != null;
21914753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    }
21924753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme
21934753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    /** @hide */
21944753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    protected boolean hasDecorView() {
21954753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        return mDecorView != null;
21964753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    }
21974753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme
21984753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    /** @hide */
21994753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    protected WindowManager.LayoutParams getDecorViewLayoutParams() {
22004753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        return (WindowManager.LayoutParams) mDecorView.getLayoutParams();
22014753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    }
22024753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme
22039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2204259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Updates the position and the dimension of the popup window.
2205259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
2206259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Calling this function also updates the window with the current popup
2207259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * state as described for {@link #update()}.
22089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
22099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the popup's anchor view
2210c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param width the new width in pixels, must be >= 0 or -1 to ignore
2211c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param height the new height in pixels, must be >= 0 or -1 to ignore
22129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
22139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update(View anchor, int width, int height) {
2214b91d6d06b824aab4076fb985304a602806429042Alan Viverette        update(anchor, false, 0, 0, width, height);
22159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2218259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Updates the position and the dimension of the popup window.
2219259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
2220259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Width and height can be set to -1 to update location only. Calling this
2221259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * function also updates the window with the current popup state as
2222259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * described for {@link #update()}.
2223259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
2224259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * If the view later scrolls to move {@code anchor} to a different
2225259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * location, the popup will be moved correspondingly.
22269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
22279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the popup's anchor view
22289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param xoff x offset from the view's left edge
22299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param yoff y offset from the view's bottom edge
2230c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param width the new width in pixels, must be >= 0 or -1 to ignore
2231c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette     * @param height the new height in pixels, must be >= 0 or -1 to ignore
22329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
22339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update(View anchor, int xoff, int yoff, int width, int height) {
2234b91d6d06b824aab4076fb985304a602806429042Alan Viverette        update(anchor, true, xoff, yoff, width, height);
2235105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
2236105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
2237105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    private void update(View anchor, boolean updateLocation, int xoff, int yoff,
2238b91d6d06b824aab4076fb985304a602806429042Alan Viverette            int width, int height) {
2239105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
22404753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        if (!isShowing() || !hasContentView()) {
22419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
22429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
22439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
224475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        final WeakReference<View> oldAnchor = mAnchor;
2245f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final int gravity = mAnchoredGravity;
2246f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette
224775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        final boolean needsUpdate = updateLocation && (mAnchorXoff != xoff || mAnchorYoff != yoff);
224881f08086b44a117097960195d2c9072e29644962Gilles Debunne        if (oldAnchor == null || oldAnchor.get() != anchor || (needsUpdate && !mIsDropdown)) {
2249f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette            attachToAnchor(anchor, xoff, yoff, gravity);
225081f08086b44a117097960195d2c9072e29644962Gilles Debunne        } else if (needsUpdate) {
225181f08086b44a117097960195d2c9072e29644962Gilles Debunne            // No need to register again if this is a DropDown, showAsDropDown already did.
225281f08086b44a117097960195d2c9072e29644962Gilles Debunne            mAnchorXoff = xoff;
225381f08086b44a117097960195d2c9072e29644962Gilles Debunne            mAnchorYoff = yoff;
22549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
22559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22564753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        final WindowManager.LayoutParams p = getDecorViewLayoutParams();
2257f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final int oldGravity = p.gravity;
2258f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final int oldWidth = p.width;
2259f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final int oldHeight = p.height;
2260f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final int oldX = p.x;
2261f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final int oldY = p.y;
2262f95b2d9aabc2e989bd1d665e728922b1c529589aAlan Viverette
2263b91d6d06b824aab4076fb985304a602806429042Alan Viverette        // If an explicit width/height has not specified, use the most recent
2264b91d6d06b824aab4076fb985304a602806429042Alan Viverette        // explicitly specified value (either from setWidth/Height or update).
2265f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr        if (width < 0) {
2266b91d6d06b824aab4076fb985304a602806429042Alan Viverette            width = mWidth;
2267b91d6d06b824aab4076fb985304a602806429042Alan Viverette        }
2268f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr        if (height < 0) {
2269b91d6d06b824aab4076fb985304a602806429042Alan Viverette            height = mHeight;
22709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2271105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
2272f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final boolean aboveAnchor = findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff,
227350df07a1add902da01018756c213169e4e126a28Alan Viverette                width, height, gravity, mAllowScrollingAnchorParent);
2274f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        updateAboveAnchor(aboveAnchor);
2275b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio
2276f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        final boolean paramsChanged = oldGravity != p.gravity || oldX != p.x || oldY != p.y
2277f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette                || oldWidth != p.width || oldHeight != p.height;
227850df07a1add902da01018756c213169e4e126a28Alan Viverette
227950df07a1add902da01018756c213169e4e126a28Alan Viverette        // If width and mWidth were both < 0 then we have a MATCH_PARENT or
228050df07a1add902da01018756c213169e4e126a28Alan Viverette        // WRAP_CONTENT case. findDropDownPosition will have resolved this to
228150df07a1add902da01018756c213169e4e126a28Alan Viverette        // absolute values, but we don't want to update mWidth/mHeight to these
228250df07a1add902da01018756c213169e4e126a28Alan Viverette        // absolute values.
228350df07a1add902da01018756c213169e4e126a28Alan Viverette        final int newWidth = width < 0 ? width : p.width;
228450df07a1add902da01018756c213169e4e126a28Alan Viverette        final int newHeight = height < 0 ? height : p.height;
228550df07a1add902da01018756c213169e4e126a28Alan Viverette        update(p.x, p.y, newWidth, newHeight, paramsChanged);
22869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
22899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Listener that is called when this popup window is dismissed.
22909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
22919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface OnDismissListener {
22929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
22939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Called when this popup window is dismissed.
22949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
22959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onDismiss();
22969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22984753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    /** @hide */
229977150c5fbb1996d6e56e52020ac240d6ea14a64bSvet Ganov    protected void detachFromAnchor() {
230077150c5fbb1996d6e56e52020ac240d6ea14a64bSvet Ganov        final View anchor = getAnchor();
23019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (anchor != null) {
2302e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            final ViewTreeObserver vto = anchor.getViewTreeObserver();
23039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            vto.removeOnScrollChangedListener(mOnScrollChangedListener);
2304afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev            anchor.removeOnAttachStateChangeListener(mOnAnchorDetachedListener);
23059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2306e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
2307634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        final View anchorRoot = mAnchorRoot != null ? mAnchorRoot.get() : null;
2308634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        if (anchorRoot != null) {
2309634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            anchorRoot.removeOnAttachStateChangeListener(mOnAnchorRootDetachedListener);
2310b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev            anchorRoot.removeOnLayoutChangeListener(mOnLayoutChangeListener);
2311634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        }
2312634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
23139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAnchor = null;
2314634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        mAnchorRoot = null;
2315634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        mIsAnchorRootAttached = false;
23169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23184753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme    /** @hide */
231977150c5fbb1996d6e56e52020ac240d6ea14a64bSvet Ganov    protected void attachToAnchor(View anchor, int xoff, int yoff, int gravity) {
2320f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette        detachFromAnchor();
2321e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
2322e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        final ViewTreeObserver vto = anchor.getViewTreeObserver();
23239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (vto != null) {
23249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            vto.addOnScrollChangedListener(mOnScrollChangedListener);
23259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2326afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev        anchor.addOnAttachStateChangeListener(mOnAnchorDetachedListener);
23279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2328634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        final View anchorRoot = anchor.getRootView();
2329634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        anchorRoot.addOnAttachStateChangeListener(mOnAnchorRootDetachedListener);
2330b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev        anchorRoot.addOnLayoutChangeListener(mOnLayoutChangeListener);
2331634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
2332634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        mAnchor = new WeakReference<>(anchor);
2333634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        mAnchorRoot = new WeakReference<>(anchorRoot);
2334634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        mIsAnchorRootAttached = anchorRoot.isAttachedToWindow();
233550db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal        mParentRootView = mAnchorRoot;
2336634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
23379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAnchorXoff = xoff;
23389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAnchorYoff = yoff;
233954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell        mAnchoredGravity = gravity;
23409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
23419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
234277150c5fbb1996d6e56e52020ac240d6ea14a64bSvet Ganov    /** @hide */
234377150c5fbb1996d6e56e52020ac240d6ea14a64bSvet Ganov    protected @Nullable View getAnchor() {
234477150c5fbb1996d6e56e52020ac240d6ea14a64bSvet Ganov        return mAnchor != null ? mAnchor.get() : null;
234577150c5fbb1996d6e56e52020ac240d6ea14a64bSvet Ganov    }
234677150c5fbb1996d6e56e52020ac240d6ea14a64bSvet Ganov
2347afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev    private void alignToAnchor() {
2348afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev        final View anchor = mAnchor != null ? mAnchor.get() : null;
23494753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        if (anchor != null && anchor.isAttachedToWindow() && hasDecorView()) {
23504753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme            final WindowManager.LayoutParams p = getDecorViewLayoutParams();
2351afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev
2352afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev            updateAboveAnchor(findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff,
2353afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev                    p.width, p.height, mAnchoredGravity, false));
2354afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev            update(p.x, p.y, -1, -1, true);
2355afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev        }
2356afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev    }
2357afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev
2358b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev    private View getAppRootView(View anchor) {
2359b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev        final View appWindowView = WindowManagerGlobal.getInstance().getWindowView(
2360b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev                anchor.getApplicationWindowToken());
2361b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev        if (appWindowView != null) {
2362b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev            return appWindowView;
2363b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev        }
2364b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev        return anchor.getRootView();
2365b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev    }
2366b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev
23675435a30ae552391f14009c4459731ae149675b18Alan Viverette    private class PopupDecorView extends FrameLayout {
23687e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette        /** Runnable used to clean up listeners after exit transition. */
23697e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette        private Runnable mCleanupAfterExit;
23708fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
23715435a30ae552391f14009c4459731ae149675b18Alan Viverette        public PopupDecorView(Context context) {
23725435a30ae552391f14009c4459731ae149675b18Alan Viverette            super(context);
23735435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
23749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
23769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean dispatchKeyEvent(KeyEvent event) {
23779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
23784ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson                if (getKeyDispatcherState() == null) {
23794ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson                    return super.dispatchKeyEvent(event);
23804ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson                }
23814ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson
23825435a30ae552391f14009c4459731ae149675b18Alan Viverette                if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
23835435a30ae552391f14009c4459731ae149675b18Alan Viverette                    final KeyEvent.DispatcherState state = getKeyDispatcherState();
2384b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                    if (state != null) {
2385b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                        state.startTracking(event, this);
2386b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                    }
23878d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                    return true;
2388b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                } else if (event.getAction() == KeyEvent.ACTION_UP) {
23895435a30ae552391f14009c4459731ae149675b18Alan Viverette                    final KeyEvent.DispatcherState state = getKeyDispatcherState();
2390b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                    if (state != null && state.isTracking(event) && !event.isCanceled()) {
2391b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                        dismiss();
2392b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                        return true;
2393b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                    }
23948d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                }
23958d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                return super.dispatchKeyEvent(event);
23969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
23979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return super.dispatchKeyEvent(event);
23989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
23999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
24029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean dispatchTouchEvent(MotionEvent ev) {
24039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mTouchInterceptor != null && mTouchInterceptor.onTouch(this, ev)) {
24049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
24059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
24069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return super.dispatchTouchEvent(ev);
24079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
24109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean onTouchEvent(MotionEvent event) {
24119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int x = (int) event.getX();
24129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int y = (int) event.getY();
24135435a30ae552391f14009c4459731ae149675b18Alan Viverette
24149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((event.getAction() == MotionEvent.ACTION_DOWN)
24159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    && ((x < 0) || (x >= getWidth()) || (y < 0) || (y >= getHeight()))) {
24169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dismiss();
24179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
24189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
24199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dismiss();
24209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
24219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
24229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return super.onTouchEvent(event);
24239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
24249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
24258fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
24268fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        /**
24278fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * Requests that an enter transition run after the next layout pass.
24288fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         */
24298fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        public void requestEnterTransition(Transition transition) {
24308fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            final ViewTreeObserver observer = getViewTreeObserver();
24318fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            if (observer != null && transition != null) {
24328fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                final Transition enterTransition = transition.clone();
24338fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
24348fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                // Postpone the enter transition after the first layout pass.
24358fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
24368fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                    @Override
24378fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                    public void onGlobalLayout() {
24388fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                        final ViewTreeObserver observer = getViewTreeObserver();
24398fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                        if (observer != null) {
24408fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                            observer.removeOnGlobalLayoutListener(this);
24418fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                        }
24428fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
244391098574f90277128415e9593cce1e495cc51465Alan Viverette                        final Rect epicenter = getTransitionEpicenter();
244495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                        enterTransition.setEpicenterCallback(new EpicenterCallback() {
244595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                            @Override
244695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                            public Rect onGetEpicenter(Transition transition) {
244795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                                return epicenter;
244895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                            }
244995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                        });
24508fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                        startEnterTransition(enterTransition);
24518fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                    }
24528fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                });
24538fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
24548fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
24558fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
24568fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        /**
24578fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * Starts the pending enter transition, if one is set.
24588fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         */
24598fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        private void startEnterTransition(Transition enterTransition) {
24608fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            final int count = getChildCount();
24618fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            for (int i = 0; i < count; i++) {
24628fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                final View child = getChildAt(i);
24638fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                enterTransition.addTarget(child);
24648fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                child.setVisibility(View.INVISIBLE);
24658fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
24668fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
24678fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            TransitionManager.beginDelayedTransition(this, enterTransition);
24688fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
24698fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            for (int i = 0; i < count; i++) {
24708fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                final View child = getChildAt(i);
24718fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                child.setVisibility(View.VISIBLE);
24728fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
24738fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
24748fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
24758fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        /**
24768fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * Starts an exit transition immediately.
24778fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * <p>
24788fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * <strong>Note:</strong> The transition listener is guaranteed to have
24798fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * its {@code onTransitionEnd} method called even if the transition
24807e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette         * never starts.
24818fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         */
2482054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette        public void startExitTransition(@NonNull Transition transition,
2483054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette                @Nullable final View anchorRoot, @Nullable final Rect epicenter,
2484054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette                @NonNull final TransitionListener listener) {
24858fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            if (transition == null) {
24868fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                return;
24878fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
24888fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
2489634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            // The anchor view's window may go away while we're executing our
2490634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            // transition, in which case we need to end the transition
2491634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            // immediately and execute the listener to remove the popup.
2492054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette            if (anchorRoot != null) {
2493054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette                anchorRoot.addOnAttachStateChangeListener(mOnAnchorRootDetachedListener);
2494054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette            }
2495634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
24967e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette            // The cleanup runnable MUST be called even if the transition is
24977e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette            // canceled before it starts (and thus can't call onTransitionEnd).
24987e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette            mCleanupAfterExit = () -> {
24997e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette                listener.onTransitionEnd(transition);
25008fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
25017e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette                if (anchorRoot != null) {
25027e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette                    anchorRoot.removeOnAttachStateChangeListener(mOnAnchorRootDetachedListener);
25038fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                }
25047e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette
25057e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette                // The listener was called. Our job here is done.
25067e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette                mCleanupAfterExit = null;
25078fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            };
25088fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
25098fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            final Transition exitTransition = transition.clone();
25107e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette            exitTransition.addListener(new TransitionListenerAdapter() {
25117e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette                @Override
25127e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette                public void onTransitionEnd(Transition t) {
25137e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette                    t.removeListener(this);
25147e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette
25157e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette                    // This null check shouldn't be necessary, but it's easier
25167e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette                    // to check here than it is to test every possible case.
25177e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette                    if (mCleanupAfterExit != null) {
25187e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette                        mCleanupAfterExit.run();
25197e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette                    }
25207e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette                }
25217e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette            });
2522054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette            exitTransition.setEpicenterCallback(new EpicenterCallback() {
2523054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette                @Override
2524054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette                public Rect onGetEpicenter(Transition transition) {
2525054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette                    return epicenter;
2526054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette                }
2527054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette            });
25288fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
25298fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            final int count = getChildCount();
25308fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            for (int i = 0; i < count; i++) {
25318fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                final View child = getChildAt(i);
25328fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                exitTransition.addTarget(child);
25338fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
25348fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
25358fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            TransitionManager.beginDelayedTransition(this, exitTransition);
25368fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
25378fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            for (int i = 0; i < count; i++) {
25388fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                final View child = getChildAt(i);
25398fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                child.setVisibility(View.INVISIBLE);
25408fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
25418fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
25428fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
25438fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        /**
25448fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * Cancels all pending or current transitions.
25458fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         */
25468fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        public void cancelTransitions() {
25478fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            TransitionManager.endTransitions(this);
25488fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
25497e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette            // If the cleanup runnable is still around, that means the
25507e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette            // transition never started. We should run it now to clean up.
25517e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette            if (mCleanupAfterExit != null) {
25527e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette                mCleanupAfterExit.run();
25538fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
25548fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
2555634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
2556634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        private final OnAttachStateChangeListener mOnAnchorRootDetachedListener =
2557634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                new OnAttachStateChangeListener() {
2558634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    @Override
2559634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    public void onViewAttachedToWindow(View v) {}
2560634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
2561634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    @Override
2562634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    public void onViewDetachedFromWindow(View v) {
2563634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                        v.removeOnAttachStateChangeListener(this);
2564634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
2565634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                        TransitionManager.endTransitions(PopupDecorView.this);
2566634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    }
2567634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                };
256850db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal
256950db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal        @Override
257050db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal        public void requestKeyboardShortcuts(List<KeyboardShortcutGroup> list, int deviceId) {
257150db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal            if (mParentRootView != null) {
257250db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal                View parentRoot = mParentRootView.get();
257350db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal                if (parentRoot != null) {
257450db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal                    parentRoot.requestKeyboardShortcuts(list, deviceId);
257550db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal                }
257650db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal            }
257750db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal        }
25785435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
25795435a30ae552391f14009c4459731ae149675b18Alan Viverette
25805435a30ae552391f14009c4459731ae149675b18Alan Viverette    private class PopupBackgroundView extends FrameLayout {
25815435a30ae552391f14009c4459731ae149675b18Alan Viverette        public PopupBackgroundView(Context context) {
25825435a30ae552391f14009c4459731ae149675b18Alan Viverette            super(context);
25835435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
258475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
258575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        @Override
25865435a30ae552391f14009c4459731ae149675b18Alan Viverette        protected int[] onCreateDrawableState(int extraSpace) {
25875435a30ae552391f14009c4459731ae149675b18Alan Viverette            if (mAboveAnchor) {
25885435a30ae552391f14009c4459731ae149675b18Alan Viverette                final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
25895435a30ae552391f14009c4459731ae149675b18Alan Viverette                View.mergeDrawableStates(drawableState, ABOVE_ANCHOR_STATE_SET);
25905435a30ae552391f14009c4459731ae149675b18Alan Viverette                return drawableState;
259175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            } else {
25925435a30ae552391f14009c4459731ae149675b18Alan Viverette                return super.onCreateDrawableState(extraSpace);
259375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            }
259475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
25959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
25969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2597