PopupWindow.java revision 7970894a9c446a6c8260d28b5b5ec922cc3e7010
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
198216eb2221ad5ad6615d3966f43844268756f3c8Wale Ogunwaleimport static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME;
20a1eb439eee65138280c560f96e2a6896f9c9112cRobert Carrimport static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH;
21a1eb439eee65138280c560f96e2a6896f9c9112cRobert Carr
22a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport com.android.internal.R;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viveretteimport android.annotation.NonNull;
2575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.Context;
26a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport android.content.res.Resources;
2775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.res.TypedArray;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PixelFormat;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.Drawable;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.StateListDrawable;
3246e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brownimport android.os.Build;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder;
345435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.Transition;
355435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.Transition.EpicenterCallback;
368fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.transition.Transition.TransitionListener;
378fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.transition.Transition.TransitionListenerAdapter;
385435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.TransitionInflater;
395435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.TransitionManager;
405435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.TransitionSet;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet;
42c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.Gravity;
43c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.KeyEvent;
44c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.MotionEvent;
45c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.View;
46634a808226cc5d00bd6897bdc881cafe064e37acAlan Viveretteimport android.view.View.OnAttachStateChangeListener;
47a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport android.view.View.OnTouchListener;
48c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.ViewGroup;
498fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.view.ViewParent;
50c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.ViewTreeObserver;
518fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.view.ViewTreeObserver.OnGlobalLayoutListener;
52c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.ViewTreeObserver.OnScrollChangedListener;
53a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport android.view.WindowManager;
54259c2840691a79634ffd8f63291ec21c21819542Alan Viveretteimport android.view.WindowManager.LayoutParams;
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
56a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport java.lang.ref.WeakReference;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>A popup window that can be used to display an arbitrary view. The popup
607ed189e457b16c06b0425bd28aeeb1df5c8ff5b8Scott Kennedy * window is a floating container that appears on top of the current
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * activity.</p>
625435a30ae552391f14009c4459731ae149675b18Alan Viverette *
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.widget.AutoCompleteTextView
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.widget.Spinner
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class PopupWindow {
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
68e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     * Mode for {@link #setInputMethodMode(int)}: the requirements for the
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * input method should be based on the focusability of the popup.  That is
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if it is focusable than it needs to work with the input method, else
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * it doesn't.
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int INPUT_METHOD_FROM_FOCUSABLE = 0;
745435a30ae552391f14009c4459731ae149675b18Alan Viverette
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
76e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     * Mode for {@link #setInputMethodMode(int)}: this popup always needs to
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * work with an input method, regardless of whether it is focusable.  This
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * means that it will always be displayed so that the user can also operate
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the input method while it is shown.
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int INPUT_METHOD_NEEDED = 1;
825435a30ae552391f14009c4459731ae149675b18Alan Viverette
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
84e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     * Mode for {@link #setInputMethodMode(int)}: this popup never needs to
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * work with an input method, regardless of whether it is focusable.  This
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * means that it will always be displayed to use as much space on the
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * screen as needed, regardless of whether this covers the input method.
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int INPUT_METHOD_NOT_NEEDED = 2;
9054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell
9154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell    private static final int DEFAULT_ANCHORED_GRAVITY = Gravity.TOP | Gravity.START;
9254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell
935435a30ae552391f14009c4459731ae149675b18Alan Viverette    /**
945435a30ae552391f14009c4459731ae149675b18Alan Viverette     * Default animation style indicating that separate animations should be
955435a30ae552391f14009c4459731ae149675b18Alan Viverette     * used for top/bottom anchoring states.
965435a30ae552391f14009c4459731ae149675b18Alan Viverette     */
975435a30ae552391f14009c4459731ae149675b18Alan Viverette    private static final int ANIMATION_STYLE_DEFAULT = -1;
985435a30ae552391f14009c4459731ae149675b18Alan Viverette
995435a30ae552391f14009c4459731ae149675b18Alan Viverette    private final int[] mDrawingLocation = new int[2];
1005435a30ae552391f14009c4459731ae149675b18Alan Viverette    private final int[] mScreenLocation = new int[2];
1015435a30ae552391f14009c4459731ae149675b18Alan Viverette    private final Rect mTempRect = new Rect();
1025435a30ae552391f14009c4459731ae149675b18Alan Viverette
103448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy    private Context mContext;
104448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy    private WindowManager mWindowManager;
1055435a30ae552391f14009c4459731ae149675b18Alan Viverette
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mIsShowing;
1078fd949e680c15d397084430d4907c16cedfacddaAlan Viverette    private boolean mIsTransitioningToDismiss;
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mIsDropdown;
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1105435a30ae552391f14009c4459731ae149675b18Alan Viverette    /** View that handles event dispatch and content transitions. */
1115435a30ae552391f14009c4459731ae149675b18Alan Viverette    private PopupDecorView mDecorView;
1125435a30ae552391f14009c4459731ae149675b18Alan Viverette
113697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette    /** View that holds the background and may animate during a transition. */
114697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette    private View mBackgroundView;
115697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette
116697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette    /** The contents of the popup. May be identical to the background view. */
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private View mContentView;
1185435a30ae552391f14009c4459731ae149675b18Alan Viverette
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mFocusable;
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mInputMethodMode = INPUT_METHOD_FROM_FOCUSABLE;
1217eab094722af54717859b7dcce3cc050f059e00bDianne Hackborn    private int mSoftInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED;
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mTouchable = true;
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mOutsideTouchable = false;
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mClippingEnabled = true;
12546e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown    private int mSplitTouchEnabled = -1;
126ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    private boolean mLayoutInScreen;
12756c2d337e02a275397fc9d0460dca90977f199acAdam Powell    private boolean mClipToScreen;
128348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell    private boolean mAllowScrollingAnchorParent = true;
1290bd1d0a15294345bf88b20df28466907f982cec7Adam Powell    private boolean mLayoutInsetDecor = false;
130e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell    private boolean mNotTouchModal;
131393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    private boolean mAttachedInDecor = true;
132393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    private boolean mAttachedInDecorSet = false;
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private OnTouchListener mTouchInterceptor;
135393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mWidthMode;
137259c2840691a79634ffd8f63291ec21c21819542Alan Viverette    private int mWidth = LayoutParams.WRAP_CONTENT;
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mLastWidth;
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mHeightMode;
140259c2840691a79634ffd8f63291ec21c21819542Alan Viverette    private int mHeight = LayoutParams.WRAP_CONTENT;
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mLastHeight;
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mPopupWidth;
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mPopupHeight;
14556c2d337e02a275397fc9d0460dca90977f199acAdam Powell
146ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    private float mElevation;
147ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mBackground;
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mAboveAnchorBackgroundDrawable;
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mBelowAnchorBackgroundDrawable;
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1525435a30ae552391f14009c4459731ae149675b18Alan Viverette    private Transition mEnterTransition;
1535435a30ae552391f14009c4459731ae149675b18Alan Viverette    private Transition mExitTransition;
15491098574f90277128415e9593cce1e495cc51465Alan Viverette    private Rect mEpicenterBounds;
155560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mAboveAnchor;
157574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    private int mWindowLayoutType = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
1585435a30ae552391f14009c4459731ae149675b18Alan Viverette
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private OnDismissListener mOnDismissListener;
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mIgnoreCheekPress = false;
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1625435a30ae552391f14009c4459731ae149675b18Alan Viverette    private int mAnimationStyle = ANIMATION_STYLE_DEFAULT;
1635435a30ae552391f14009c4459731ae149675b18Alan Viverette
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int[] ABOVE_ANCHOR_STATE_SET = new int[] {
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        com.android.internal.R.attr.state_above_anchor
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
168634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette    private final OnAttachStateChangeListener mOnAnchorRootDetachedListener =
169634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            new OnAttachStateChangeListener() {
170634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                @Override
171634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                public void onViewAttachedToWindow(View v) {}
172634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
173634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                @Override
174634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                public void onViewDetachedFromWindow(View v) {
175634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    mIsAnchorRootAttached = false;
176634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                }
177634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            };
178634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private WeakReference<View> mAnchor;
180634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette    private WeakReference<View> mAnchorRoot;
181634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette    private boolean mIsAnchorRootAttached;
182560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
1835435a30ae552391f14009c4459731ae149675b18Alan Viverette    private final OnScrollChangedListener mOnScrollChangedListener = new OnScrollChangedListener() {
1845435a30ae552391f14009c4459731ae149675b18Alan Viverette        @Override
1855435a30ae552391f14009c4459731ae149675b18Alan Viverette        public void onScrollChanged() {
1865435a30ae552391f14009c4459731ae149675b18Alan Viverette            final View anchor = mAnchor != null ? mAnchor.get() : null;
1875435a30ae552391f14009c4459731ae149675b18Alan Viverette            if (anchor != null && mDecorView != null) {
1885435a30ae552391f14009c4459731ae149675b18Alan Viverette                final WindowManager.LayoutParams p = (WindowManager.LayoutParams)
1895435a30ae552391f14009c4459731ae149675b18Alan Viverette                        mDecorView.getLayoutParams();
1905435a30ae552391f14009c4459731ae149675b18Alan Viverette
1915435a30ae552391f14009c4459731ae149675b18Alan Viverette                updateAboveAnchor(findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff,
1925435a30ae552391f14009c4459731ae149675b18Alan Viverette                        mAnchoredGravity));
1935435a30ae552391f14009c4459731ae149675b18Alan Viverette                update(p.x, p.y, -1, -1, true);
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1955435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
1965435a30ae552391f14009c4459731ae149675b18Alan Viverette    };
197560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
1985435a30ae552391f14009c4459731ae149675b18Alan Viverette    private int mAnchorXoff;
1995435a30ae552391f14009c4459731ae149675b18Alan Viverette    private int mAnchorYoff;
2005435a30ae552391f14009c4459731ae149675b18Alan Viverette    private int mAnchoredGravity;
201560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette    private boolean mOverlapAnchor;
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
203b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio    private boolean mPopupViewInitialLayoutDirectionInherited;
204b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window of dimension (0,0).</p>
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does provide a background.</p>
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(Context context) {
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(context, null);
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window of dimension (0,0).</p>
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does provide a background.</p>
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(Context context, AttributeSet attrs) {
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(context, attrs, com.android.internal.R.attr.popupWindowStyle);
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window of dimension (0,0).</p>
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does provide a background.</p>
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
228617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr) {
229617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        this(context, attrs, defStyleAttr, 0);
230c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
2315435a30ae552391f14009c4459731ae149675b18Alan Viverette
232c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
233c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * <p>Create a new, empty, non focusable popup window of dimension (0,0).</p>
2345435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
235c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * <p>The popup does not provide a background.</p>
236c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
237c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext = context;
23975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
241617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        final TypedArray a = context.obtainStyledAttributes(
242ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                attrs, R.styleable.PopupWindow, defStyleAttr, defStyleRes);
243ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        final Drawable bg = a.getDrawable(R.styleable.PopupWindow_popupBackground);
244ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        mElevation = a.getDimension(R.styleable.PopupWindow_popupElevation, 0);
245560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        mOverlapAnchor = a.getBoolean(R.styleable.PopupWindow_overlapAnchor, false);
246c3808b5dc7d5873d04e8a0a247b179b2757764baAdam Powell
2475435a30ae552391f14009c4459731ae149675b18Alan Viverette        // Preserve default behavior from Gingerbread. If the animation is
2485435a30ae552391f14009c4459731ae149675b18Alan Viverette        // undefined or explicitly specifies the Gingerbread animation style,
2495435a30ae552391f14009c4459731ae149675b18Alan Viverette        // use a sentinel value.
2505435a30ae552391f14009c4459731ae149675b18Alan Viverette        if (a.hasValueOrEmpty(R.styleable.PopupWindow_popupAnimationStyle)) {
2515435a30ae552391f14009c4459731ae149675b18Alan Viverette            final int animStyle = a.getResourceId(R.styleable.PopupWindow_popupAnimationStyle, 0);
2525435a30ae552391f14009c4459731ae149675b18Alan Viverette            if (animStyle == R.style.Animation_PopupWindow) {
2535435a30ae552391f14009c4459731ae149675b18Alan Viverette                mAnimationStyle = ANIMATION_STYLE_DEFAULT;
2545435a30ae552391f14009c4459731ae149675b18Alan Viverette            } else {
2555435a30ae552391f14009c4459731ae149675b18Alan Viverette                mAnimationStyle = animStyle;
2565435a30ae552391f14009c4459731ae149675b18Alan Viverette            }
2575435a30ae552391f14009c4459731ae149675b18Alan Viverette        } else {
2585435a30ae552391f14009c4459731ae149675b18Alan Viverette            mAnimationStyle = ANIMATION_STYLE_DEFAULT;
2595435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
2605435a30ae552391f14009c4459731ae149675b18Alan Viverette
2615435a30ae552391f14009c4459731ae149675b18Alan Viverette        final Transition enterTransition = getTransition(a.getResourceId(
2625435a30ae552391f14009c4459731ae149675b18Alan Viverette                R.styleable.PopupWindow_popupEnterTransition, 0));
2635435a30ae552391f14009c4459731ae149675b18Alan Viverette        final Transition exitTransition;
2645435a30ae552391f14009c4459731ae149675b18Alan Viverette        if (a.hasValueOrEmpty(R.styleable.PopupWindow_popupExitTransition)) {
2655435a30ae552391f14009c4459731ae149675b18Alan Viverette            exitTransition = getTransition(a.getResourceId(
2665435a30ae552391f14009c4459731ae149675b18Alan Viverette                    R.styleable.PopupWindow_popupExitTransition, 0));
2675435a30ae552391f14009c4459731ae149675b18Alan Viverette        } else {
2685435a30ae552391f14009c4459731ae149675b18Alan Viverette            exitTransition = enterTransition == null ? null : enterTransition.clone();
2695435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        a.recycle();
272ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette
2735435a30ae552391f14009c4459731ae149675b18Alan Viverette        setEnterTransition(enterTransition);
2745435a30ae552391f14009c4459731ae149675b18Alan Viverette        setExitTransition(exitTransition);
275ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        setBackgroundDrawable(bg);
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window of dimension (0,0).</p>
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow() {
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(null, 0, 0);
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new non focusable popup window which can display the
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <tt>contentView</tt>. The dimension of the window are (0,0).</p>
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param contentView the popup's content
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(View contentView) {
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(contentView, 0, 0);
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new empty, non focusable popup window. The dimension of the
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window must be passed to this constructor.</p>
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width the popup's width
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height the popup's height
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(int width, int height) {
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(null, width, height);
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new non focusable popup window which can display the
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <tt>contentView</tt>. The dimension of the window must be passed to
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this constructor.</p>
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param contentView the popup's content
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width the popup's width
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height the popup's height
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PopupWindow(View contentView, int width, int height) {
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(contentView, width, height, false);
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Create a new popup window which can display the <tt>contentView</tt>.
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The dimension of the window must be passed to this constructor.</p>
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The popup does not provide any background. This should be handled
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by the content view.</p>
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param contentView the popup's content
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width the popup's width
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height the popup's height
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param focusable true if the popup can be focused, false otherwise
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
343448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy    public PopupWindow(View contentView, int width, int height, boolean focusable) {
344448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        if (contentView != null) {
345448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy            mContext = contentView.getContext();
346448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy            mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
347448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        }
348393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setContentView(contentView);
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setWidth(width);
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setHeight(height);
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setFocusable(focusable);
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3555435a30ae552391f14009c4459731ae149675b18Alan Viverette    public void setEnterTransition(Transition enterTransition) {
3565435a30ae552391f14009c4459731ae149675b18Alan Viverette        mEnterTransition = enterTransition;
3575435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
3585435a30ae552391f14009c4459731ae149675b18Alan Viverette
3595435a30ae552391f14009c4459731ae149675b18Alan Viverette    public void setExitTransition(Transition exitTransition) {
3605435a30ae552391f14009c4459731ae149675b18Alan Viverette        mExitTransition = exitTransition;
3615435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
3625435a30ae552391f14009c4459731ae149675b18Alan Viverette
36391098574f90277128415e9593cce1e495cc51465Alan Viverette    /**
36491098574f90277128415e9593cce1e495cc51465Alan Viverette     * Sets the bounds used as the epicenter of the enter and exit transitions.
36591098574f90277128415e9593cce1e495cc51465Alan Viverette     * <p>
36691098574f90277128415e9593cce1e495cc51465Alan Viverette     * Transitions use a point or Rect, referred to as the epicenter, to orient
36791098574f90277128415e9593cce1e495cc51465Alan Viverette     * the direction of travel. For popup windows, the anchor view bounds are
36891098574f90277128415e9593cce1e495cc51465Alan Viverette     * used as the default epicenter.
36991098574f90277128415e9593cce1e495cc51465Alan Viverette     * <p>
37091098574f90277128415e9593cce1e495cc51465Alan Viverette     * See {@link Transition#setEpicenterCallback(EpicenterCallback)} for more
37191098574f90277128415e9593cce1e495cc51465Alan Viverette     * information about how transition epicenters.
37291098574f90277128415e9593cce1e495cc51465Alan Viverette     *
37391098574f90277128415e9593cce1e495cc51465Alan Viverette     * @param bounds the epicenter bounds relative to the anchor view, or
37491098574f90277128415e9593cce1e495cc51465Alan Viverette     *               {@code null} to use the default epicenter
37591098574f90277128415e9593cce1e495cc51465Alan Viverette     * @see #getTransitionEpicenter()
37691098574f90277128415e9593cce1e495cc51465Alan Viverette     * @hide
37791098574f90277128415e9593cce1e495cc51465Alan Viverette     */
37891098574f90277128415e9593cce1e495cc51465Alan Viverette    public void setEpicenterBounds(Rect bounds) {
37991098574f90277128415e9593cce1e495cc51465Alan Viverette        mEpicenterBounds = bounds;
38091098574f90277128415e9593cce1e495cc51465Alan Viverette    }
38191098574f90277128415e9593cce1e495cc51465Alan Viverette
3825435a30ae552391f14009c4459731ae149675b18Alan Viverette    private Transition getTransition(int resId) {
3835435a30ae552391f14009c4459731ae149675b18Alan Viverette        if (resId != 0 && resId != R.transition.no_transition) {
3845435a30ae552391f14009c4459731ae149675b18Alan Viverette            final TransitionInflater inflater = TransitionInflater.from(mContext);
3855435a30ae552391f14009c4459731ae149675b18Alan Viverette            final Transition transition = inflater.inflateTransition(resId);
3865435a30ae552391f14009c4459731ae149675b18Alan Viverette            if (transition != null) {
3875435a30ae552391f14009c4459731ae149675b18Alan Viverette                final boolean isEmpty = transition instanceof TransitionSet
3885435a30ae552391f14009c4459731ae149675b18Alan Viverette                        && ((TransitionSet) transition).getTransitionCount() == 0;
3895435a30ae552391f14009c4459731ae149675b18Alan Viverette                if (!isEmpty) {
3905435a30ae552391f14009c4459731ae149675b18Alan Viverette                    return transition;
3915435a30ae552391f14009c4459731ae149675b18Alan Viverette                }
3925435a30ae552391f14009c4459731ae149675b18Alan Viverette            }
3935435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
3945435a30ae552391f14009c4459731ae149675b18Alan Viverette        return null;
3955435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
3965435a30ae552391f14009c4459731ae149675b18Alan Viverette
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
398ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * Return the drawable used as the popup window's background.
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
400ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @return the background drawable or {@code null} if not set
401ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @see #setBackgroundDrawable(Drawable)
402ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @attr ref android.R.styleable#PopupWindow_popupBackground
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Drawable getBackground() {
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mBackground;
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
409ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * Specifies the background drawable for this popup window. The background
410ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * can be set to {@code null}.
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param background the popup's background
413ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @see #getBackground()
414ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @attr ref android.R.styleable#PopupWindow_popupBackground
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setBackgroundDrawable(Drawable background) {
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBackground = background;
418ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette
419ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // If this is a StateListDrawable, try to find and store the drawable to be
420ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // used when the drop-down is placed above its anchor view, and the one to be
421ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // used when the drop-down is placed below its anchor view. We extract
422ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // the drawables ourselves to work around a problem with using refreshDrawableState
423ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // that it will take into account the padding of all drawables specified in a
424ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // StateListDrawable, thus adding superfluous padding to drop-down views.
425ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        //
426ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // We assume a StateListDrawable will have a drawable for ABOVE_ANCHOR_STATE_SET and
427ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        // at least one other drawable, intended for the 'below-anchor state'.
428ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        if (mBackground instanceof StateListDrawable) {
429ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            StateListDrawable stateList = (StateListDrawable) mBackground;
430ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette
431ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            // Find the above-anchor view - this one's easy, it should be labeled as such.
432ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            int aboveAnchorStateIndex = stateList.getStateDrawableIndex(ABOVE_ANCHOR_STATE_SET);
433ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette
434ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            // Now, for the below-anchor view, look for any other drawable specified in the
435ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            // StateListDrawable which is not for the above-anchor state and use that.
436ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            int count = stateList.getStateCount();
437ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            int belowAnchorStateIndex = -1;
438ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            for (int i = 0; i < count; i++) {
439ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                if (i != aboveAnchorStateIndex) {
440ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                    belowAnchorStateIndex = i;
441ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                    break;
442ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                }
443ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            }
444ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette
445ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            // Store the drawables we found, if we found them. Otherwise, set them both
446ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            // to null so that we'll just use refreshDrawableState.
447ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            if (aboveAnchorStateIndex != -1 && belowAnchorStateIndex != -1) {
448ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                mAboveAnchorBackgroundDrawable = stateList.getStateDrawable(aboveAnchorStateIndex);
449ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                mBelowAnchorBackgroundDrawable = stateList.getStateDrawable(belowAnchorStateIndex);
450ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            } else {
451ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                mBelowAnchorBackgroundDrawable = null;
452ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette                mAboveAnchorBackgroundDrawable = null;
453ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette            }
454ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette        }
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
458ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @return the elevation for this popup window in pixels
459ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @see #setElevation(float)
460ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @attr ref android.R.styleable#PopupWindow_popupElevation
461ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     */
462ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    public float getElevation() {
463ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        return mElevation;
464ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    }
465ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
466ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    /**
467ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * Specifies the elevation for this popup window.
468ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     *
469ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @param elevation the popup's elevation in pixels
470ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @see #getElevation()
471ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     * @attr ref android.R.styleable#PopupWindow_popupElevation
472ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette     */
473ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    public void setElevation(float elevation) {
474ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        mElevation = elevation;
475ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    }
476ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
477ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    /**
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Return the animation style to use the popup appears and disappears</p>
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the animation style to use the popup appears and disappears
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getAnimationStyle() {
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mAnimationStyle;
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
485393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
48754ec76d81ac38284caa6d00ad5f2d2207206b9ceShuhrat Dehkanov     * Set the flag on popup to ignore cheek press events; by default this flag
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is set to false
48954ec76d81ac38284caa6d00ad5f2d2207206b9ceShuhrat Dehkanov     * which means the popup will not ignore cheek press dispatch events.
4905435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
494393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setIgnoreCheekPress() {
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIgnoreCheekPress = true;
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5005435a30ae552391f14009c4459731ae149675b18Alan Viverette
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Change the animation style resource for this popup.</p>
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param animationStyle animation style to use when the popup appears
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *      and disappears.  Set to -1 for the default animation, 0 for no
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *      animation, or a resource identifier for an explicit animation.
5125435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setAnimationStyle(int animationStyle) {
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAnimationStyle = animationStyle;
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5185435a30ae552391f14009c4459731ae149675b18Alan Viverette
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Return the view used as the content of the popup window.</p>
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a {@link android.view.View} representing the popup's content
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setContentView(android.view.View)
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View getContentView() {
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mContentView;
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Change the popup's content. The content is represented by an instance
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of {@link android.view.View}.</p>
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
53481f08086b44a117097960195d2c9072e29644962Gilles Debunne     * <p>This method has no effect if called when the popup is showing.</p>
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param contentView the new content for the popup
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getContentView()
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isShowing()
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setContentView(View contentView) {
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isShowing()) {
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContentView = contentView;
547448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy
5480c0b768e1514280812321854db6dfba723c3d169Romain Guy        if (mContext == null && mContentView != null) {
549448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy            mContext = mContentView.getContext();
550448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        }
551448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy
5520c0b768e1514280812321854db6dfba723c3d169Romain Guy        if (mWindowManager == null && mContentView != null) {
553448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy            mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
554448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        }
555393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
556393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        // Setting the default for attachedInDecor based on SDK version here
557393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        // instead of in the constructor since we might not have the context
558393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        // object in the constructor. We only want to set default here if the
559393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        // app hasn't already set the attachedInDecor.
560393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        if (mContext != null && !mAttachedInDecorSet) {
561393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale            // Attach popup window in decor frame of parent window by default for
562393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale            // {@link Build.VERSION_CODES.LOLLIPOP_MR1} or greater. Keep current
563393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale            // behavior of not attaching to decor frame for older SDKs.
564393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale            setAttachedInDecor(mContext.getApplicationInfo().targetSdkVersion
565393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale                    >= Build.VERSION_CODES.LOLLIPOP_MR1);
566393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        }
567393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set a callback for all touch events being dispatched to the popup
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window.
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setTouchInterceptor(OnTouchListener l) {
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTouchInterceptor = l;
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
577393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicate whether the popup window can grab the focus.</p>
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is focusable, false otherwise
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setFocusable(boolean)
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isFocusable() {
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mFocusable;
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Changes the focusability of the popup window. When focusable, the
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window will grab the focus from the current focused widget if the popup
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * contains a focusable {@link android.view.View}.  By default a popup
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window is not focusable.</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 focusable true if the popup should grab focus, false otherwise.
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isFocusable()
6025435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #isShowing()
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setFocusable(boolean focusable) {
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFocusable = focusable;
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the current value in {@link #setInputMethodMode(int)}.
6115435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setInputMethodMode(int)
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getInputMethodMode() {
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mInputMethodMode;
6165435a30ae552391f14009c4459731ae149675b18Alan Viverette
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6185435a30ae552391f14009c4459731ae149675b18Alan Viverette
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Control how the popup operates with an input method: one of
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #INPUT_METHOD_FROM_FOCUSABLE}, {@link #INPUT_METHOD_NEEDED},
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or {@link #INPUT_METHOD_NOT_NEEDED}.
6235435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
6275435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getInputMethodMode()
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setInputMethodMode(int mode) {
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputMethodMode = mode;
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
634374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy
635374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy    /**
636374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * Sets the operating mode for the soft input area.
637374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     *
638374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * @param mode The desired mode, see
639374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     *        {@link android.view.WindowManager.LayoutParams#softInputMode}
640374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     *        for the full list
641374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     *
642374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * @see android.view.WindowManager.LayoutParams#softInputMode
643374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * @see #getSoftInputMode()
644374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     */
645374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy    public void setSoftInputMode(int mode) {
646374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy        mSoftInputMode = mode;
647374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy    }
648374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy
649374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy    /**
650374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * Returns the current value in {@link #setSoftInputMode(int)}.
651374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     *
652374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * @see #setSoftInputMode(int)
653374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     * @see android.view.WindowManager.LayoutParams#softInputMode
654374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy     */
655374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy    public int getSoftInputMode() {
656374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy        return mSoftInputMode;
657374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy    }
6585435a30ae552391f14009c4459731ae149675b18Alan Viverette
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicates whether the popup window receives touch events.</p>
6615435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is touchable, false otherwise
6635435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setTouchable(boolean)
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isTouchable() {
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mTouchable;
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Changes the touchability of the popup window. When touchable, the
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window will receive touch events, otherwise touch events will go to the
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window below it. By default the window is touchable.</p>
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param touchable true if the popup should receive touch events, false otherwise
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isTouchable()
6825435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #isShowing()
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setTouchable(boolean touchable) {
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTouchable = touchable;
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicates whether the popup window will be informed of touch events
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * outside of its window.</p>
6925435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is outside touchable, false otherwise
6945435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setOutsideTouchable(boolean)
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isOutsideTouchable() {
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mOutsideTouchable;
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Controls whether the pop-up will be informed of touch events outside
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of its window.  This only makes sense for pop-ups that are touchable
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * but not focusable, which means touches outside of the window will
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be delivered to the window behind.  The default is false.</p>
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param touchable true if the popup should receive outside
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * touch events, false otherwise
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isOutsideTouchable()
7155435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #isShowing()
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setOutsideTouchable(boolean touchable) {
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOutsideTouchable = touchable;
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicates whether clipping of the popup window is enabled.</p>
7245435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the clipping is enabled, false otherwise
7265435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setClippingEnabled(boolean)
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isClippingEnabled() {
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mClippingEnabled;
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Allows the popup window to extend beyond the bounds of the screen. By default the
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window is clipped to the screen boundaries. Setting this to false will allow windows to be
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * accurately positioned.</p>
7375435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown or through a manual call to one of
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the {@link #update()} methods.</p>
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param enabled false if the window should be allowed to extend outside of the screen
7435435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #isShowing()
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isClippingEnabled()
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #update()
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setClippingEnabled(boolean enabled) {
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mClippingEnabled = enabled;
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
75256c2d337e02a275397fc9d0460dca90977f199acAdam Powell     * Clip this popup window to the screen, but not to the containing window.
75356c2d337e02a275397fc9d0460dca90977f199acAdam Powell     *
75456c2d337e02a275397fc9d0460dca90977f199acAdam Powell     * @param enabled True to clip to the screen.
75556c2d337e02a275397fc9d0460dca90977f199acAdam Powell     * @hide
75656c2d337e02a275397fc9d0460dca90977f199acAdam Powell     */
75756c2d337e02a275397fc9d0460dca90977f199acAdam Powell    public void setClipToScreenEnabled(boolean enabled) {
75856c2d337e02a275397fc9d0460dca90977f199acAdam Powell        mClipToScreen = enabled;
75956c2d337e02a275397fc9d0460dca90977f199acAdam Powell        setClippingEnabled(!enabled);
76056c2d337e02a275397fc9d0460dca90977f199acAdam Powell    }
761348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell
762348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell    /**
763348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     * Allow PopupWindow to scroll the anchor's parent to provide more room
764348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     * for the popup. Enabled by default.
765348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     *
766348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     * @param enabled True to scroll the anchor's parent when more room is desired by the popup.
767348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     */
768348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell    void setAllowScrollingAnchorParent(boolean enabled) {
769348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell        mAllowScrollingAnchorParent = enabled;
770348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell    }
7715435a30ae552391f14009c4459731ae149675b18Alan Viverette
77256c2d337e02a275397fc9d0460dca90977f199acAdam Powell    /**
77301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * <p>Indicates whether the popup window supports splitting touches.</p>
7745435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
77501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * @return true if the touch splitting is enabled, false otherwise
7765435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
77701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * @see #setSplitTouchEnabled(boolean)
77801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     */
77901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    public boolean isSplitTouchEnabled() {
78046e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown        if (mSplitTouchEnabled < 0 && mContext != null) {
78146e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown            return mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB;
78246e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown        }
78346e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown        return mSplitTouchEnabled == 1;
78401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
78501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
78601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    /**
78701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * <p>Allows the popup window to split touches across other windows that also
78846e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown     * support split touch.  When this flag is false, the first pointer
78901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * that goes down determines the window to which all subsequent touches
79046e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown     * go until all pointers go up.  When this flag is true, each pointer
79101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * (not necessarily the first) that goes down determines the window
79201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * to which all subsequent touches of that pointer will go until that
79301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * pointer goes up thereby enabling touches with multiple pointers
79401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * to be split across multiple windows.</p>
79501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     *
79601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * @param enabled true if the split touches should be enabled, false otherwise
79701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     * @see #isSplitTouchEnabled()
79801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown     */
79901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    public void setSplitTouchEnabled(boolean enabled) {
80046e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown        mSplitTouchEnabled = enabled ? 1 : 0;
80101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
80201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
80301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    /**
804ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * <p>Indicates whether the popup window will be forced into using absolute screen coordinates
805ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * for positioning.</p>
806ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     *
807ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * @return true if the window will always be positioned in screen coordinates.
808ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * @hide
809ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     */
810ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    public boolean isLayoutInScreenEnabled() {
811ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell        return mLayoutInScreen;
812ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    }
813ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell
814ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    /**
815ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * <p>Allows the popup window to force the flag
816ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * {@link WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN}, overriding default behavior.
817ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * This will cause the popup to be positioned in absolute screen coordinates.</p>
818ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     *
819ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * @param enabled true if the popup should always be positioned in screen coordinates
820ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     * @hide
821ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell     */
822ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    public void setLayoutInScreenEnabled(boolean enabled) {
823ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell        mLayoutInScreen = enabled;
824ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    }
825ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell
826ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell    /**
827393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * <p>Indicates whether the popup window will be attached in the decor frame of its parent
828393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * window.
829393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
830393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * @return true if the window will be attached to the decor frame of its parent window.
831393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
832393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * @see #setAttachedInDecor(boolean)
833393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR
834393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     */
835393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    public boolean isAttachedInDecor() {
836393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        return mAttachedInDecor;
837393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    }
838393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
839393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    /**
840393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * <p>This will attach the popup window to the decor frame of the parent window to avoid
841393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * overlaping with screen decorations like the navigation bar. Overrides the default behavior of
842393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * the flag {@link WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR}.
843393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
844393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * <p>By default the flag is set on SDK version {@link Build.VERSION_CODES#LOLLIPOP_MR1} or
845393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * greater and cleared on lesser SDK versions.
846393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
847393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * @param enabled true if the popup should be attached to the decor frame of its parent window.
848393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     *
849393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     * @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR
850393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale     */
851393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    public void setAttachedInDecor(boolean enabled) {
852393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        mAttachedInDecor = enabled;
853393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        mAttachedInDecorSet = true;
854393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    }
855393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
856393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale    /**
8570bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * Allows the popup window to force the flag
8580bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * {@link WindowManager.LayoutParams#FLAG_LAYOUT_INSET_DECOR}, overriding default behavior.
8590bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * This will cause the popup to inset its content to account for system windows overlaying
8600bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * the screen, such as the status bar.
8610bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     *
8620bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * <p>This will often be combined with {@link #setLayoutInScreenEnabled(boolean)}.
8630bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     *
8640bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * @param enabled true if the popup's views should inset content to account for system windows,
8650bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     *                the way that decor views behave for full-screen windows.
8660bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     * @hide
8670bd1d0a15294345bf88b20df28466907f982cec7Adam Powell     */
8680bd1d0a15294345bf88b20df28466907f982cec7Adam Powell    public void setLayoutInsetDecor(boolean enabled) {
8690bd1d0a15294345bf88b20df28466907f982cec7Adam Powell        mLayoutInsetDecor = enabled;
8700bd1d0a15294345bf88b20df28466907f982cec7Adam Powell    }
8710bd1d0a15294345bf88b20df28466907f982cec7Adam Powell
8720bd1d0a15294345bf88b20df28466907f982cec7Adam Powell    /**
87380ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette     * Set the layout type for this window.
87480ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette     * <p>
87580ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette     * See {@link WindowManager.LayoutParams#type} for possible values.
876574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell     *
877574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell     * @param layoutType Layout type for this window.
87836344a90c226c90243e4e02bfb13589e120431ddChris Banes     *
87936344a90c226c90243e4e02bfb13589e120431ddChris Banes     * @see WindowManager.LayoutParams#type
880574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell     */
881574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    public void setWindowLayoutType(int layoutType) {
882574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell        mWindowLayoutType = layoutType;
883574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    }
884574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell
885574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    /**
88636344a90c226c90243e4e02bfb13589e120431ddChris Banes     * Returns the layout type for this window.
88736344a90c226c90243e4e02bfb13589e120431ddChris Banes     *
88836344a90c226c90243e4e02bfb13589e120431ddChris Banes     * @see #setWindowLayoutType(int)
889574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell     */
890574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    public int getWindowLayoutType() {
891574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell        return mWindowLayoutType;
892574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    }
893574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell
894574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell    /**
895e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell     * Set whether this window is touch modal or if outside touches will be sent to
896e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell     * other windows behind it.
897e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell     * @hide
898e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell     */
899e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell    public void setTouchModal(boolean touchModal) {
900e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell        mNotTouchModal = !touchModal;
901e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell    }
902e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell
903e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell    /**
9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Change the width and height measure specs that are given to the
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window manager by the popup.  By default these are 0, meaning that
9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the current width or height is requested as an explicit size from
9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the window manager.  You can supply
9085435a30ae552391f14009c4459731ae149675b18Alan Viverette     * {@link ViewGroup.LayoutParams#WRAP_CONTENT} or
909980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy     * {@link ViewGroup.LayoutParams#MATCH_PARENT} to have that measure
9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * spec supplied instead, replacing the absolute width and height that
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * has been set in the popup.</p>
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If the popup is showing, calling this method will take effect only
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the next time the popup is shown.</p>
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param widthSpec an explicit width measure spec mode, either
9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ViewGroup.LayoutParams#WRAP_CONTENT},
918980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy     * {@link ViewGroup.LayoutParams#MATCH_PARENT}, or 0 to use the absolute
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * width.
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param heightSpec an explicit height measure spec mode, either
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ViewGroup.LayoutParams#WRAP_CONTENT},
922980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy     * {@link ViewGroup.LayoutParams#MATCH_PARENT}, or 0 to use the absolute
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * height.
924259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *
925259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @deprecated Use {@link #setWidth(int)} and {@link #setHeight(int)}.
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
927259c2840691a79634ffd8f63291ec21c21819542Alan Viverette    @Deprecated
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setWindowLayoutMode(int widthSpec, int heightSpec) {
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWidthMode = widthSpec;
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHeightMode = heightSpec;
9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9325435a30ae552391f14009c4459731ae149675b18Alan Viverette
9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
934259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Returns the popup's height MeasureSpec.
9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the height MeasureSpec of the popup
9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setHeight(int)
9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getHeight() {
9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mHeight;
9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
944259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Sets the popup's height MeasureSpec.
945259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
946259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * If the popup is showing, calling this method will take effect the next
947259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * time the popup is shown.
9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param height the height MeasureSpec of the popup
9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getHeight()
9515435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #isShowing()
9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setHeight(int height) {
9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHeight = height;
9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
958259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Returns the popup's width MeasureSpec.
9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the width MeasureSpec of the popup
9615435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #setWidth(int)
9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getWidth() {
9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mWidth;
9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
968259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Sets the popup's width MeasureSpec.
969259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
970259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * If the popup is showing, calling this method will take effect the next
971259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * time the popup is shown.
9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width the width MeasureSpec of the popup
9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getWidth()
9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #isShowing()
9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setWidth(int width) {
9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWidth = width;
9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
98275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * Sets whether the popup window should overlap its anchor view when
98375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * displayed as a drop-down.
98475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * <p>
98575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * If the popup is showing, calling this method will take effect only
98675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * the next time the popup is shown.
98775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     *
98875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * @param overlapAnchor Whether the popup should overlap its anchor.
98975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     *
99075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * @see #getOverlapAnchor()
99175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * @see #isShowing()
99275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     */
99375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    public void setOverlapAnchor(boolean overlapAnchor) {
99475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        mOverlapAnchor = overlapAnchor;
99575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    }
99675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette
99775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    /**
99875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * Returns whether the popup window should overlap its anchor view when
99975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * displayed as a drop-down.
100075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     *
100175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * @return Whether the popup should overlap its anchor.
100275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     *
100375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * @see #setOverlapAnchor(boolean)
100475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     */
100575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    public boolean getOverlapAnchor() {
100675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        return mOverlapAnchor;
100775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    }
100875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette
100975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette    /**
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicate whether this popup window is showing on screen.</p>
10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is showing, false otherwise
10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isShowing() {
10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mIsShowing;
10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Display the content view in a popup window at the specified location. If the popup window
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * cannot fit on screen, it will be clipped. See {@link android.view.WindowManager.LayoutParams}
10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * for more information on how gravity and the x and y parameters are related. Specifying
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a gravity of {@link android.view.Gravity#NO_GRAVITY} is similar to specifying
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <code>Gravity.LEFT | Gravity.TOP</code>.
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * </p>
10265435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param parent a parent view to get the {@link android.view.View#getWindowToken()} token from
10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param gravity the gravity which controls the placement of the popup window
10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x the popup's x location offset
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y the popup's y location offset
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void showAtLocation(View parent, int gravity, int x, int y) {
10338ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell        showAtLocation(parent.getWindowToken(), gravity, x, y);
10348ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell    }
10358ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell
10368ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell    /**
10378ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * Display the content view in a popup window at the specified location.
10388ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     *
10398ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * @param token Window token to use for creating the new window
10408ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * @param gravity the gravity which controls the placement of the popup window
10418ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * @param x the popup's x location offset
10428ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * @param y the popup's y location offset
10438ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     *
10448ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     * @hide Internal use only. Applications should use
10458ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     *       {@link #showAtLocation(View, int, int, int)} instead.
10468ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell     */
10478ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell    public void showAtLocation(IBinder token, int gravity, int x, int y) {
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isShowing() || mContentView == null) {
10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1052e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        TransitionManager.endTransitions(mDecorView);
1053e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
1054634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        unregisterForViewTreeChanges();
10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsShowing = true;
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsDropdown = false;
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1059e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        final WindowManager.LayoutParams p = createPopupLayoutParams(token);
10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        preparePopup(p);
1061e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
1062e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        // Only override the default if some gravity was specified.
1063e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        if (gravity != Gravity.NO_GRAVITY) {
1064e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            p.gravity = gravity;
10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1066e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.x = x;
10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.y = y;
1069e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        invokePopup(p);
10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
107475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * Display the content view in a popup window anchored to the bottom-left
10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * corner of the anchor view. If there is not enough room on screen to show
10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the popup in its entirety, this method tries to find a parent scroll
107775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * view to scroll. If no parent scroll view can be scrolled, the
107875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * bottom-left corner of the popup is pinned at the top left corner of the
107975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * anchor view.
10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the view on which to pin the popup window
10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #dismiss()
10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void showAsDropDown(View anchor) {
10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        showAsDropDown(anchor, 0, 0);
10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
109075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * Display the content view in a popup window anchored to the bottom-left
10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * corner of the anchor view offset by the specified x and y coordinates.
109275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * If there is not enough room on screen to show the popup in its entirety,
109375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * this method tries to find a parent scroll view to scroll. If no parent
109475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * scroll view can be scrolled, the bottom-left corner of the popup is
109575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * pinned at the top left corner of the anchor view.
109675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * <p>
109775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * If the view later scrolls to move <code>anchor</code> to a different
109875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * location, the popup will be moved correspondingly.
10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the view on which to pin the popup window
110154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param xoff A horizontal offset from the anchor in pixels
110254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param yoff A vertical offset from the anchor in pixels
11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #dismiss()
11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void showAsDropDown(View anchor, int xoff, int yoff) {
110754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell        showAsDropDown(anchor, xoff, yoff, DEFAULT_ANCHORED_GRAVITY);
110854c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell    }
110954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell
111054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell    /**
111175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * Displays the content view in a popup window anchored to the corner of
111275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * another view. The window is positioned according to the specified
111375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * gravity and offset by the specified x and y coordinates.
111475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * <p>
111575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * If there is not enough room on screen to show the popup in its entirety,
111675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * this method tries to find a parent scroll view to scroll. If no parent
111775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * view can be scrolled, the specified vertical gravity will be ignored and
111875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * the popup will anchor itself such that it is visible.
111975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * <p>
112075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * If the view later scrolls to move <code>anchor</code> to a different
112175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette     * location, the popup will be moved correspondingly.
112254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     *
112354c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param anchor the view on which to pin the popup window
112454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param xoff A horizontal offset from the anchor in pixels
112554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param yoff A vertical offset from the anchor in pixels
112654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @param gravity Alignment of the popup relative to the anchor
112754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     *
112854c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     * @see #dismiss()
112954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell     */
113054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell    public void showAsDropDown(View anchor, int xoff, int yoff, int gravity) {
11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isShowing() || mContentView == null) {
11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1135e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        TransitionManager.endTransitions(mDecorView);
1136e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
1137634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        registerForViewTreeChanges(anchor, xoff, yoff, gravity);
11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsShowing = true;
11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsDropdown = true;
11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1142e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        final WindowManager.LayoutParams p = createPopupLayoutParams(anchor.getWindowToken());
11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        preparePopup(p);
11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1145e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        final boolean aboveAnchor = findDropDownPosition(anchor, p, xoff, yoff, gravity);
1146e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        updateAboveAnchor(aboveAnchor);
11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        invokePopup(p);
11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11513e141685003939a9addce21ba2492ea3a8aebee6Romain Guy    private void updateAboveAnchor(boolean aboveAnchor) {
11523e141685003939a9addce21ba2492ea3a8aebee6Romain Guy        if (aboveAnchor != mAboveAnchor) {
11533e141685003939a9addce21ba2492ea3a8aebee6Romain Guy            mAboveAnchor = aboveAnchor;
11543e141685003939a9addce21ba2492ea3a8aebee6Romain Guy
1155697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette            if (mBackground != null && mBackgroundView != null) {
1156697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette                // If the background drawable provided was a StateListDrawable
1157697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette                // with above-anchor and below-anchor states, use those.
1158697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette                // Otherwise, rely on refreshDrawableState to do the job.
11593e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                if (mAboveAnchorBackgroundDrawable != null) {
11603e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                    if (mAboveAnchor) {
1161697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette                        mBackgroundView.setBackground(mAboveAnchorBackgroundDrawable);
11623e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                    } else {
1163697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette                        mBackgroundView.setBackground(mBelowAnchorBackgroundDrawable);
11643e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                    }
11653e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                } else {
1166697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette                    mBackgroundView.refreshDrawableState();
11673e141685003939a9addce21ba2492ea3a8aebee6Romain Guy                }
11683e141685003939a9addce21ba2492ea3a8aebee6Romain Guy            }
11693e141685003939a9addce21ba2492ea3a8aebee6Romain Guy        }
11703e141685003939a9addce21ba2492ea3a8aebee6Romain Guy    }
11713e141685003939a9addce21ba2492ea3a8aebee6Romain Guy
11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Indicates whether the popup is showing above (the y coordinate of the popup's bottom
11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is less than the y coordinate of the anchor) or below the anchor view (the y coordinate
11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of the popup is greater than y coordinate of the anchor's bottom).
11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The value returned
11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by this method is meaningful only after {@link #showAsDropDown(android.view.View)}
11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or {@link #showAsDropDown(android.view.View, int, int)} was invoked.
11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return True if this popup is showing above the anchor view, false otherwise.
11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isAboveAnchor() {
11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mAboveAnchor;
11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1188e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette     * Prepare the popup by embedding it into a new ViewGroup if the background
1189e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette     * drawable is not null. If embedding is required, the layout parameters'
1190e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette     * height is modified to take into account the background's padding.
11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param p the layout parameters of the popup's content view
11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void preparePopup(WindowManager.LayoutParams p) {
1195448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        if (mContentView == null || mContext == null || mWindowManager == null) {
1196448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy            throw new IllegalStateException("You must specify a valid content view by "
1197448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy                    + "calling setContentView() before attempting to show the popup.");
1198448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy        }
1199448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy
12008fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // The old decor view may be transitioning out. Make sure it finishes
12018fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // and cleans up before we try to create another one.
12028fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        if (mDecorView != null) {
12038fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            mDecorView.cancelTransitions();
12048fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
12058fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
12065435a30ae552391f14009c4459731ae149675b18Alan Viverette        // When a background is available, we embed the content view within
12075435a30ae552391f14009c4459731ae149675b18Alan Viverette        // another view that owns the background drawable.
12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBackground != null) {
1209697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette            mBackgroundView = createBackgroundView(mContentView);
1210697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette            mBackgroundView.setBackground(mBackground);
12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1212697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette            mBackgroundView = mContentView;
12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1214ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
1215697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette        mDecorView = createDecorView(mBackgroundView);
12165435a30ae552391f14009c4459731ae149675b18Alan Viverette
12175435a30ae552391f14009c4459731ae149675b18Alan Viverette        // The background owner should be elevated so that it casts a shadow.
1218697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette        mBackgroundView.setElevation(mElevation);
12195435a30ae552391f14009c4459731ae149675b18Alan Viverette
12205435a30ae552391f14009c4459731ae149675b18Alan Viverette        // We may wrap that in another view, so we'll need to manually specify
12215435a30ae552391f14009c4459731ae149675b18Alan Viverette        // the surface insets.
1222697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette        final int surfaceInset = (int) Math.ceil(mBackgroundView.getZ() * 2);
12235435a30ae552391f14009c4459731ae149675b18Alan Viverette        p.surfaceInsets.set(surfaceInset, surfaceInset, surfaceInset, surfaceInset);
12245435a30ae552391f14009c4459731ae149675b18Alan Viverette        p.hasManualSurfaceInsets = true;
12255435a30ae552391f14009c4459731ae149675b18Alan Viverette
1226b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio        mPopupViewInitialLayoutDirectionInherited =
12275435a30ae552391f14009c4459731ae149675b18Alan Viverette                (mContentView.getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT);
12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPopupWidth = p.width;
12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPopupHeight = p.height;
12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12335435a30ae552391f14009c4459731ae149675b18Alan Viverette     * Wraps a content view in a PopupViewContainer.
12345435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
12355435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @param contentView the content view to wrap
12365435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @return a PopupViewContainer that wraps the content view
12375435a30ae552391f14009c4459731ae149675b18Alan Viverette     */
12385435a30ae552391f14009c4459731ae149675b18Alan Viverette    private PopupBackgroundView createBackgroundView(View contentView) {
12395435a30ae552391f14009c4459731ae149675b18Alan Viverette        final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams();
12405435a30ae552391f14009c4459731ae149675b18Alan Viverette        final int height;
12415435a30ae552391f14009c4459731ae149675b18Alan Viverette        if (layoutParams != null && layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
12425435a30ae552391f14009c4459731ae149675b18Alan Viverette            height = ViewGroup.LayoutParams.WRAP_CONTENT;
12435435a30ae552391f14009c4459731ae149675b18Alan Viverette        } else {
12445435a30ae552391f14009c4459731ae149675b18Alan Viverette            height = ViewGroup.LayoutParams.MATCH_PARENT;
12455435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
12465435a30ae552391f14009c4459731ae149675b18Alan Viverette
12475435a30ae552391f14009c4459731ae149675b18Alan Viverette        final PopupBackgroundView backgroundView = new PopupBackgroundView(mContext);
12485435a30ae552391f14009c4459731ae149675b18Alan Viverette        final PopupBackgroundView.LayoutParams listParams = new PopupBackgroundView.LayoutParams(
12495435a30ae552391f14009c4459731ae149675b18Alan Viverette                ViewGroup.LayoutParams.MATCH_PARENT, height);
12505435a30ae552391f14009c4459731ae149675b18Alan Viverette        backgroundView.addView(contentView, listParams);
12515435a30ae552391f14009c4459731ae149675b18Alan Viverette
12525435a30ae552391f14009c4459731ae149675b18Alan Viverette        return backgroundView;
12535435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
12545435a30ae552391f14009c4459731ae149675b18Alan Viverette
12555435a30ae552391f14009c4459731ae149675b18Alan Viverette    /**
12565435a30ae552391f14009c4459731ae149675b18Alan Viverette     * Wraps a content view in a FrameLayout.
12575435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
12585435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @param contentView the content view to wrap
12595435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @return a FrameLayout that wraps the content view
12605435a30ae552391f14009c4459731ae149675b18Alan Viverette     */
12615435a30ae552391f14009c4459731ae149675b18Alan Viverette    private PopupDecorView createDecorView(View contentView) {
12625435a30ae552391f14009c4459731ae149675b18Alan Viverette        final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams();
12635435a30ae552391f14009c4459731ae149675b18Alan Viverette        final int height;
12645435a30ae552391f14009c4459731ae149675b18Alan Viverette        if (layoutParams != null && layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
12655435a30ae552391f14009c4459731ae149675b18Alan Viverette            height = ViewGroup.LayoutParams.WRAP_CONTENT;
12665435a30ae552391f14009c4459731ae149675b18Alan Viverette        } else {
12675435a30ae552391f14009c4459731ae149675b18Alan Viverette            height = ViewGroup.LayoutParams.MATCH_PARENT;
12685435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
12695435a30ae552391f14009c4459731ae149675b18Alan Viverette
12705435a30ae552391f14009c4459731ae149675b18Alan Viverette        final PopupDecorView decorView = new PopupDecorView(mContext);
12715435a30ae552391f14009c4459731ae149675b18Alan Viverette        decorView.addView(contentView, ViewGroup.LayoutParams.MATCH_PARENT, height);
12725435a30ae552391f14009c4459731ae149675b18Alan Viverette        decorView.setClipChildren(false);
12735435a30ae552391f14009c4459731ae149675b18Alan Viverette        decorView.setClipToPadding(false);
12745435a30ae552391f14009c4459731ae149675b18Alan Viverette
12755435a30ae552391f14009c4459731ae149675b18Alan Viverette        return decorView;
12765435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
12775435a30ae552391f14009c4459731ae149675b18Alan Viverette
12785435a30ae552391f14009c4459731ae149675b18Alan Viverette    /**
12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Invoke the popup window by adding the content view to the window
12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * manager.</p>
12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The content view must be non-null when this method is invoked.</p>
12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param p the layout parameters of the popup's content view
12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void invokePopup(WindowManager.LayoutParams p) {
12870c0b768e1514280812321854db6dfba723c3d169Romain Guy        if (mContext != null) {
12880c0b768e1514280812321854db6dfba723c3d169Romain Guy            p.packageName = mContext.getPackageName();
12890c0b768e1514280812321854db6dfba723c3d169Romain Guy        }
12905435a30ae552391f14009c4459731ae149675b18Alan Viverette
12918fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        final PopupDecorView decorView = mDecorView;
12928fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        decorView.setFitsSystemWindows(mLayoutInsetDecor);
12935435a30ae552391f14009c4459731ae149675b18Alan Viverette
12948fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        setLayoutDirectionFromAnchor();
12955435a30ae552391f14009c4459731ae149675b18Alan Viverette
12968fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        mWindowManager.addView(decorView, p);
129795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette
129895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        if (mEnterTransition != null) {
129995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            decorView.requestEnterTransition(mEnterTransition);
130095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        }
13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1303b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio    private void setLayoutDirectionFromAnchor() {
1304b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio        if (mAnchor != null) {
1305b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio            View anchor = mAnchor.get();
1306b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio            if (anchor != null && mPopupViewInitialLayoutDirectionInherited) {
13075435a30ae552391f14009c4459731ae149675b18Alan Viverette                mDecorView.setLayoutDirection(anchor.getLayoutDirection());
1308b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio            }
1309b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio        }
1310b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio    }
1311b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio
13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Generate the layout parameters for the popup window.</p>
13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param token the window token used to bind the popup's window
13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the layout parameters to pass to the window manager
13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1319e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette    private WindowManager.LayoutParams createPopupLayoutParams(IBinder token) {
1320e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        final WindowManager.LayoutParams p = new WindowManager.LayoutParams();
1321e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
1322e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        // These gravity settings put the view at the top left corner of the
1323e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        // screen. The view is then positioned to the appropriate location by
1324e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        // setting the x and y offsets to match the anchor's bottom-left
1325e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        // corner.
1326aac0d4ed026d1cfbcf3fa81c6e4eb96f4347ca17Fabrice Di Meglio        p.gravity = Gravity.START | Gravity.TOP;
1327e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        p.flags = computeFlags(p.flags);
1328e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        p.type = mWindowLayoutType;
1329e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        p.token = token;
1330e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        p.softInputMode = mSoftInputMode;
1331e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        p.windowAnimations = computeAnimationResource();
1332e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBackground != null) {
13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.format = mBackground.getOpacity();
13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.format = PixelFormat.TRANSLUCENT;
13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1338e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
1339e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        if (mHeightMode < 0) {
1340e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            p.height = mLastHeight = mHeightMode;
1341e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        } else {
1342e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            p.height = mLastHeight = mHeight;
1343e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        }
1344e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
1345e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        if (mWidthMode < 0) {
1346e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            p.width = mLastWidth = mWidthMode;
1347e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        } else {
1348e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            p.width = mLastWidth = mWidth;
1349e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        }
1350e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
13518216eb2221ad5ad6615d3966f43844268756f3c8Wale Ogunwale        p.privateFlags = PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH
13528216eb2221ad5ad6615d3966f43844268756f3c8Wale Ogunwale                | PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME;
1353a1eb439eee65138280c560f96e2a6896f9c9112cRobert Carr
1354e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        // Used for debugging.
13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.setTitle("PopupWindow:" + Integer.toHexString(hashCode()));
13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return p;
13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int computeFlags(int curFlags) {
13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        curFlags &= ~(
13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES |
13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |
1367ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell                WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
1368ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell                WindowManager.LayoutParams.FLAG_SPLIT_TOUCH);
13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if(mIgnoreCheekPress) {
13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES;
13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mFocusable) {
13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mInputMethodMode == INPUT_METHOD_NEEDED) {
13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (mInputMethodMode == INPUT_METHOD_NOT_NEEDED) {
13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mTouchable) {
13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1383c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project        if (mOutsideTouchable) {
13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mClippingEnabled) {
13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
138946e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown        if (isSplitTouchEnabled()) {
139001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            curFlags |= WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
139101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        }
1392ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell        if (mLayoutInScreen) {
1393ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell            curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
1394ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell        }
13950bd1d0a15294345bf88b20df28466907f982cec7Adam Powell        if (mLayoutInsetDecor) {
13960bd1d0a15294345bf88b20df28466907f982cec7Adam Powell            curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
13970bd1d0a15294345bf88b20df28466907f982cec7Adam Powell        }
1398e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell        if (mNotTouchModal) {
1399e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell            curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
1400e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell        }
1401393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        if (mAttachedInDecor) {
1402393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale          curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR;
1403393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale        }
14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return curFlags;
14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1406393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale
14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int computeAnimationResource() {
14085435a30ae552391f14009c4459731ae149675b18Alan Viverette        if (mAnimationStyle == ANIMATION_STYLE_DEFAULT) {
14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mIsDropdown) {
14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return mAboveAnchor
14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ? com.android.internal.R.style.Animation_DropDownUp
14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        : com.android.internal.R.style.Animation_DropDownDown;
14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mAnimationStyle;
14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1418560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1420560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * Positions the popup window on screen. When the popup window is too tall
1421560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * to fit under the anchor, a parent scroll view is seeked and scrolled up
1422560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * to reclaim space. If scrolling is not possible or not enough, the popup
1423560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * window gets moved on top of the anchor.
1424560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * <p>
1425560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * The height must have been set on the layout parameters prior to calling
1426560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * this method.
14275435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the view on which the popup window must be anchored
14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param p the layout parameters used to display the drop down
1430560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * @param xoff horizontal offset used to adjust for background padding
1431560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * @param yoff vertical offset used to adjust for background padding
1432560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette     * @param gravity horizontal gravity specifying popup alignment
14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup is translated upwards to fit on screen
14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1435560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette    private boolean findDropDownPosition(View anchor, WindowManager.LayoutParams p, int xoff,
1436560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            int yoff, int gravity) {
143762e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell        final int anchorHeight = anchor.getHeight();
1438560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        final int anchorWidth = anchor.getWidth();
1439560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        if (mOverlapAnchor) {
1440560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            yoff -= anchorHeight;
1441560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        }
1442560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        anchor.getLocationInWindow(mDrawingLocation);
14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.x = mDrawingLocation[0] + xoff;
144562e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell        p.y = mDrawingLocation[1] + anchorHeight + yoff;
144654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell
1447560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        final int hgrav = Gravity.getAbsoluteGravity(gravity, anchor.getLayoutDirection())
1448560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette                & Gravity.HORIZONTAL_GRAVITY_MASK;
144954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell        if (hgrav == Gravity.RIGHT) {
1450560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            // Flip the location to align the right sides of the popup and
1451560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            // anchor instead of left.
1452560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            p.x -= mPopupWidth - anchorWidth;
145354c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell        }
1454560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean onTop = false;
14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
145754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell        p.gravity = Gravity.LEFT | Gravity.TOP;
145854c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell
14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        anchor.getLocationOnScreen(mScreenLocation);
14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Rect displayFrame = new Rect();
14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        anchor.getWindowVisibleDisplayFrame(displayFrame);
146262e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell
1463560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        final int screenY = mScreenLocation[1] + anchorHeight + yoff;
14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View root = anchor.getRootView();
1465560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette        if (screenY + mPopupHeight > displayFrame.bottom
1466560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette                || p.x + mPopupWidth - root.getWidth() > 0) {
1467560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            // If the drop down disappears at the bottom of the screen, we try
1468560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            // to scroll a parent scrollview or move the drop down back up on
1469560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            // top of the edit box.
1470b7c1b20c8a5a4d4378ae91b4a1f12a34100df452Adam Powell            if (mAllowScrollingAnchorParent) {
1471560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette                final int scrollX = anchor.getScrollX();
1472560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette                final int scrollY = anchor.getScrollY();
1473560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette                final Rect r = new Rect(scrollX, scrollY, scrollX + mPopupWidth + xoff,
1474560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette                        scrollY + mPopupHeight + anchorHeight + yoff);
1475b7c1b20c8a5a4d4378ae91b4a1f12a34100df452Adam Powell                anchor.requestRectangleOnScreen(r, true);
1476b7c1b20c8a5a4d4378ae91b4a1f12a34100df452Adam Powell            }
14773e141685003939a9addce21ba2492ea3a8aebee6Romain Guy
1478560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            // Now we re-evaluate the space available, and decide from that
14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // whether the pop-up will go above or below the anchor.
14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            anchor.getLocationInWindow(mDrawingLocation);
14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.x = mDrawingLocation[0] + xoff;
1482560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            p.y = mDrawingLocation[1] + anchorHeight + yoff;
148354c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell
1484560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            // Preserve the gravity adjustment.
148554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell            if (hgrav == Gravity.RIGHT) {
1486560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette                p.x -= mPopupWidth - anchorWidth;
148754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell            }
1488560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
1489560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            // Determine whether there is more space above or below the anchor.
14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            anchor.getLocationOnScreen(mScreenLocation);
1491560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            onTop = (displayFrame.bottom - mScreenLocation[1] - anchorHeight - yoff) <
14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    (mScreenLocation[1] - yoff - displayFrame.top);
1493ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg            if (!mOverlapAnchor) {
1494ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg                if (onTop) {
1495ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg                    p.gravity = Gravity.LEFT | Gravity.BOTTOM;
1496ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg                    p.y = root.getHeight() - mDrawingLocation[1] + yoff;
1497ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg                } else {
1498ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg                    p.y = mDrawingLocation[1] + anchorHeight + yoff;
1499ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg                }
15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
150356c2d337e02a275397fc9d0460dca90977f199acAdam Powell        if (mClipToScreen) {
15047c9732db0e450785f70d634fee4037b5e887d911Chong Zhang            final int winOffsetX = mScreenLocation[0] - mDrawingLocation[0];
15057c9732db0e450785f70d634fee4037b5e887d911Chong Zhang            final int winOffsetY = mScreenLocation[1] - mDrawingLocation[1];
15067c9732db0e450785f70d634fee4037b5e887d911Chong Zhang            p.x += winOffsetX;
15077c9732db0e450785f70d634fee4037b5e887d911Chong Zhang            p.y += winOffsetY;
150856c2d337e02a275397fc9d0460dca90977f199acAdam Powell            final int displayFrameWidth = displayFrame.right - displayFrame.left;
1509560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette            final int right = p.x + p.width;
15107c9732db0e450785f70d634fee4037b5e887d911Chong Zhang            if (right > displayFrame.right) {
15117c9732db0e450785f70d634fee4037b5e887d911Chong Zhang                p.x -= right - displayFrame.right;
151256c2d337e02a275397fc9d0460dca90977f199acAdam Powell            }
1513560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
151456c2d337e02a275397fc9d0460dca90977f199acAdam Powell            if (p.x < displayFrame.left) {
151556c2d337e02a275397fc9d0460dca90977f199acAdam Powell                p.x = displayFrame.left;
151656c2d337e02a275397fc9d0460dca90977f199acAdam Powell                p.width = Math.min(p.width, displayFrameWidth);
151756c2d337e02a275397fc9d0460dca90977f199acAdam Powell            }
151856c2d337e02a275397fc9d0460dca90977f199acAdam Powell
1519ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg            if (mOverlapAnchor) {
1520ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg                final int bottom = p.y + p.height;
1521ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg                if (bottom > displayFrame.bottom) {
15227c9732db0e450785f70d634fee4037b5e887d911Chong Zhang                    p.y -= bottom - displayFrame.bottom;
15235f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell                }
15245f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell            } else {
1525ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg                if (onTop) {
1526ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg                    final int popupTop = mScreenLocation[1] + yoff - mPopupHeight;
1527ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg                    if (popupTop < 0) {
1528ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg                        p.y += popupTop;
1529ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg                    }
1530ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg                } else {
1531ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg                    p.y = Math.max(p.y, displayFrame.top);
1532ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg                }
15335f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell            }
15347c9732db0e450785f70d634fee4037b5e887d911Chong Zhang            p.x -= winOffsetX;
15357c9732db0e450785f70d634fee4037b5e887d911Chong Zhang            p.y -= winOffsetY;
153656c2d337e02a275397fc9d0460dca90977f199acAdam Powell        }
153756c2d337e02a275397fc9d0460dca90977f199acAdam Powell
15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.gravity |= Gravity.DISPLAY_CLIP_VERTICAL;
1539560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette
15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return onTop;
15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15425435a30ae552391f14009c4459731ae149675b18Alan Viverette
15439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the maximum height that is available for the popup to be
15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * completely shown. It is recommended that this height be the maximum for
15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the popup's height, otherwise it is possible that the popup will be
15479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * clipped.
15485435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
15499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor The view on which the popup window must be anchored.
15509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The maximum available height for the popup to be completely
15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         shown.
15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1553b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette    public int getMaxAvailableHeight(@NonNull View anchor) {
15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return getMaxAvailableHeight(anchor, 0);
15559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the maximum height that is available for the popup to be
15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * completely shown. It is recommended that this height be the maximum for
15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the popup's height, otherwise it is possible that the popup will be
15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * clipped.
15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor The view on which the popup window must be anchored.
15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param yOffset y offset from the view's bottom edge
15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The maximum available height for the popup to be completely
15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         shown.
15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1568b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette    public int getMaxAvailableHeight(@NonNull View anchor, int yOffset) {
156998acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau        return getMaxAvailableHeight(anchor, yOffset, false);
157098acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau    }
15715435a30ae552391f14009c4459731ae149675b18Alan Viverette
157298acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau    /**
157398acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * Returns the maximum height that is available for the popup to be
157498acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * completely shown, optionally ignoring any bottom decorations such as
157598acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * the input method. It is recommended that this height be the maximum for
157698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * the popup's height, otherwise it is possible that the popup will be
157798acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * clipped.
15785435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
157998acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * @param anchor The view on which the popup window must be anchored.
158098acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * @param yOffset y offset from the view's bottom edge
158198acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * @param ignoreBottomDecorations if true, the height returned will be
158298acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     *        all the way to the bottom of the display, ignoring any
158398acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     *        bottom decorations
158498acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     * @return The maximum available height for the popup to be completely
158598acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     *         shown.
158698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau     */
1587b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette    public int getMaxAvailableHeight(
1588b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette            @NonNull View anchor, int yOffset, boolean ignoreBottomDecorations) {
15899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Rect displayFrame = new Rect();
15909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        anchor.getWindowVisibleDisplayFrame(displayFrame);
15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int[] anchorPos = mDrawingLocation;
15939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        anchor.getLocationOnScreen(anchorPos);
15945435a30ae552391f14009c4459731ae149675b18Alan Viverette
1595b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette        final int bottomEdge;
159698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau        if (ignoreBottomDecorations) {
1597b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette            final Resources res = anchor.getContext().getResources();
15983f4a764cf400aa209c1f8f76a1c73143eefc4905Adam Powell            bottomEdge = res.getDisplayMetrics().heightPixels;
1599b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette        } else {
1600b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette            bottomEdge = displayFrame.bottom;
160198acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau        }
1602ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg
1603ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg        final int distanceToBottom;
1604ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg        if (mOverlapAnchor) {
1605ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg            distanceToBottom = bottomEdge - anchorPos[1] - yOffset;
1606ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg        } else {
1607ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg            distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset;
1608ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg        }
16099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset;
16109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // anchorPos[1] is distance from anchor to top of screen
16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int returnedHeight = Math.max(distanceToBottom, distanceToTop);
16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBackground != null) {
16149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mBackground.getPadding(mTempRect);
16155435a30ae552391f14009c4459731ae149675b18Alan Viverette            returnedHeight -= mTempRect.top + mTempRect.bottom;
16169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16175435a30ae552391f14009c4459731ae149675b18Alan Viverette
16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return returnedHeight;
16199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16205435a30ae552391f14009c4459731ae149675b18Alan Viverette
16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
16227878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette     * Disposes of the popup window. This method can be invoked only after
16237878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette     * {@link #showAsDropDown(android.view.View)} has been executed. Failing
16247878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette     * that, calling this method will have no effect.
16259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
16265435a30ae552391f14009c4459731ae149675b18Alan Viverette     * @see #showAsDropDown(android.view.View)
16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void dismiss() {
16298fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        if (!isShowing() || mIsTransitioningToDismiss) {
1630e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            return;
1631e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        }
163206f938e8aa56cd89ab0bdb04c8b946392c428dd1Svetoslav Ganov
16338fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        final PopupDecorView decorView = mDecorView;
16348fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        final View contentView = mContentView;
16358fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
16368fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        final ViewGroup contentHolder;
16378fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        final ViewParent contentParent = contentView.getParent();
16388fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        if (contentParent instanceof ViewGroup) {
16398fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            contentHolder = ((ViewGroup) contentParent);
16408fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        } else {
16418fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            contentHolder = null;
16428fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
16438fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
16448fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // Ensure any ongoing or pending transitions are canceled.
16458fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        decorView.cancelTransitions();
16468fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
1647e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        mIsShowing = false;
16488fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        mIsTransitioningToDismiss = true;
1649b82d074038f4c8d86e1bd4f3fa4d3780bd4bcba5Craig Mautner
1650634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        // This method may be called as part of window detachment, in which
1651634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        // case the anchor view (and its root) will still return true from
1652634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        // isAttachedToWindow() during execution of this method; however, we
1653634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        // can expect the OnAttachStateChangeListener to have been called prior
1654634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        // to executing this method, so we can rely on that instead.
165595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final Transition exitTransition = mExitTransition;
165621d361806c9e2dce5bae5b30f44be5ad87f32c22Alan Viverette        if (mIsAnchorRootAttached && exitTransition != null && decorView.isLaidOut()) {
165795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            // The decor view is non-interactive during exit transitions.
165895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            final LayoutParams p = (LayoutParams) decorView.getLayoutParams();
165995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            p.flags |= LayoutParams.FLAG_NOT_TOUCHABLE;
166095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            p.flags |= LayoutParams.FLAG_NOT_FOCUSABLE;
166195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            mWindowManager.updateViewLayout(decorView, p);
166295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette
1663634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            // Once we start dismissing the decor view, all state (including
1664634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            // the anchor root) needs to be moved to the decor view since we
1665634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            // may open another popup while it's busy exiting.
1666634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            final View anchorRoot = mAnchorRoot != null ? mAnchorRoot.get() : null;
166791098574f90277128415e9593cce1e495cc51465Alan Viverette            final Rect epicenter = getTransitionEpicenter();
166895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            exitTransition.setEpicenterCallback(new EpicenterCallback() {
166995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                @Override
167095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                public Rect onGetEpicenter(Transition transition) {
167195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                    return epicenter;
167295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                }
167395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            });
1674634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            decorView.startExitTransition(exitTransition, anchorRoot,
1675634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    new TransitionListenerAdapter() {
1676634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                        @Override
1677634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                        public void onTransitionEnd(Transition transition) {
16787970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette                            dismissImmediate(decorView, contentHolder, contentView);
1679634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                        }
1680634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    });
1681e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        } else {
16827970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette            dismissImmediate(decorView, contentHolder, contentView);
16837878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette        }
16847878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette
168595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        // Clears the anchor view.
1686634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        unregisterForViewTreeChanges();
16877970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette
16887970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette        if (mOnDismissListener != null) {
16897970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette            mOnDismissListener.onDismiss();
16907970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette        }
16915435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
16925435a30ae552391f14009c4459731ae149675b18Alan Viverette
169391098574f90277128415e9593cce1e495cc51465Alan Viverette    /**
169491098574f90277128415e9593cce1e495cc51465Alan Viverette     * Returns the window-relative epicenter bounds to be used by enter and
169591098574f90277128415e9593cce1e495cc51465Alan Viverette     * exit transitions.
169691098574f90277128415e9593cce1e495cc51465Alan Viverette     * <p>
169791098574f90277128415e9593cce1e495cc51465Alan Viverette     * <strong>Note:</strong> This is distinct from the rect passed to
169891098574f90277128415e9593cce1e495cc51465Alan Viverette     * {@link #setEpicenterBounds(Rect)}, which is anchor-relative.
169991098574f90277128415e9593cce1e495cc51465Alan Viverette     *
170091098574f90277128415e9593cce1e495cc51465Alan Viverette     * @return the window-relative epicenter bounds to be used by enter and
170191098574f90277128415e9593cce1e495cc51465Alan Viverette     *         exit transitions
170291098574f90277128415e9593cce1e495cc51465Alan Viverette     */
170391098574f90277128415e9593cce1e495cc51465Alan Viverette    private Rect getTransitionEpicenter() {
170495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final View anchor = mAnchor != null ? mAnchor.get() : null;
170595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final View decor = mDecorView;
170695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        if (anchor == null || decor == null) {
170795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette            return null;
170895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        }
170995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette
171095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final int[] anchorLocation = anchor.getLocationOnScreen();
171195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final int[] popupLocation = mDecorView.getLocationOnScreen();
171295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette
171395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        // Compute the position of the anchor relative to the popup.
171495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        final Rect bounds = new Rect(0, 0, anchor.getWidth(), anchor.getHeight());
171595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        bounds.offset(anchorLocation[0] - popupLocation[0], anchorLocation[1] - popupLocation[1]);
171691098574f90277128415e9593cce1e495cc51465Alan Viverette
171791098574f90277128415e9593cce1e495cc51465Alan Viverette        // Use anchor-relative epicenter, if specified.
171891098574f90277128415e9593cce1e495cc51465Alan Viverette        if (mEpicenterBounds != null) {
171991098574f90277128415e9593cce1e495cc51465Alan Viverette            final int offsetX = bounds.left;
172091098574f90277128415e9593cce1e495cc51465Alan Viverette            final int offsetY = bounds.top;
172191098574f90277128415e9593cce1e495cc51465Alan Viverette            bounds.set(mEpicenterBounds);
172291098574f90277128415e9593cce1e495cc51465Alan Viverette            bounds.offset(offsetX, offsetY);
172391098574f90277128415e9593cce1e495cc51465Alan Viverette        }
172491098574f90277128415e9593cce1e495cc51465Alan Viverette
172595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette        return bounds;
172695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette    }
172795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette
17285435a30ae552391f14009c4459731ae149675b18Alan Viverette    /**
17295435a30ae552391f14009c4459731ae149675b18Alan Viverette     * Removes the popup from the window manager and tears down the supporting
17305435a30ae552391f14009c4459731ae149675b18Alan Viverette     * view hierarchy, if necessary.
17315435a30ae552391f14009c4459731ae149675b18Alan Viverette     */
17327970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette    private void dismissImmediate(View decorView, ViewGroup contentHolder, View contentView) {
17338fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // If this method gets called and the decor view doesn't have a parent,
17348fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // then it was either never added or was already removed. That should
17358fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // never happen, but it's worth checking to avoid potential crashes.
17368fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        if (decorView.getParent() != null) {
17378fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            mWindowManager.removeViewImmediate(decorView);
1738df4639a0135ea643b493067b3f7cd1e092346c78Alan Viverette        }
1739df4639a0135ea643b493067b3f7cd1e092346c78Alan Viverette
17408fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        if (contentHolder != null) {
17418fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            contentHolder.removeView(contentView);
17429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17438fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
17448fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // This needs to stay until after all transitions have ended since we
17458fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        // need the reference to cancel transitions in preparePopup().
17468fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        mDecorView = null;
1747697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette        mBackgroundView = null;
17488fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        mIsTransitioningToDismiss = false;
17499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the listener to be called when the window is dismissed.
17535435a30ae552391f14009c4459731ae149675b18Alan Viverette     *
17549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param onDismissListener The listener.
17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setOnDismissListener(OnDismissListener onDismissListener) {
17579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOnDismissListener = onDismissListener;
17589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17595435a30ae552391f14009c4459731ae149675b18Alan Viverette
17609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Updates the state of the popup window, if it is currently being displayed,
1762259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * from the currently set state.
1763259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
1764259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * This includes:
1765259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <ul>
1766259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setClippingEnabled(boolean)}</li>
1767259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setFocusable(boolean)}</li>
1768259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setIgnoreCheekPress()}</li>
1769259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setInputMethodMode(int)}</li>
1770259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setTouchable(boolean)}</li>
1771259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *     <li>{@link #setAnimationStyle(int)}</li>
1772259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * </ul>
17739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update() {
17759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!isShowing() || mContentView == null) {
17769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
17779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17785435a30ae552391f14009c4459731ae149675b18Alan Viverette
17795435a30ae552391f14009c4459731ae149675b18Alan Viverette        final WindowManager.LayoutParams p =
17805435a30ae552391f14009c4459731ae149675b18Alan Viverette                (WindowManager.LayoutParams) mDecorView.getLayoutParams();
17815435a30ae552391f14009c4459731ae149675b18Alan Viverette
17829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean update = false;
17835435a30ae552391f14009c4459731ae149675b18Alan Viverette
17849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int newAnim = computeAnimationResource();
17859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newAnim != p.windowAnimations) {
17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.windowAnimations = newAnim;
17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
17889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int newFlags = computeFlags(p.flags);
17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newFlags != p.flags) {
17929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.flags = newFlags;
17939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
17949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1795b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio
17969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (update) {
1797b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio            setLayoutDirectionFromAnchor();
17985435a30ae552391f14009c4459731ae149675b18Alan Viverette            mWindowManager.updateViewLayout(mDecorView, p);
17999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1801d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy
1802d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy    /**
1803259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Updates the dimension of the popup window.
1804259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
1805259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Calling this function also updates the window with the current popup
1806259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * state as described for {@link #update()}.
1807d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy     *
1808259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param width the new width, must be >= 0 or -1 to ignore
1809259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param height the new height, must be >= 0 or -1 to ignore
1810d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy     */
1811d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy    public void update(int width, int height) {
18125435a30ae552391f14009c4459731ae149675b18Alan Viverette        final WindowManager.LayoutParams p =
18135435a30ae552391f14009c4459731ae149675b18Alan Viverette                (WindowManager.LayoutParams) mDecorView.getLayoutParams();
1814d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy        update(p.x, p.y, width, height, false);
1815d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy    }
18165435a30ae552391f14009c4459731ae149675b18Alan Viverette
18179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1818259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Updates the position and the dimension of the popup window.
1819259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
1820259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Width and height can be set to -1 to update location only. Calling this
1821259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * function also updates the window with the current popup state as
1822259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * described for {@link #update()}.
18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x the new x location
18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y the new y location
1826259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param width the new width, must be >= 0 or -1 to ignore
1827259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param height the new height, must be >= 0 or -1 to ignore
18289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update(int x, int y, int width, int height) {
18309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        update(x, y, width, height, false);
18319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1834259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Updates the position and the dimension of the popup window.
1835259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
1836259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Width and height can be set to -1 to update location only. Calling this
1837259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * function also updates the window with the current popup state as
1838259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * described for {@link #update()}.
18399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param x the new x location
18419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param y the new y location
1842259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param width the new width, must be >= 0 or -1 to ignore
1843259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param height the new height, must be >= 0 or -1 to ignore
1844259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param force {@code true} to reposition the window even if the specified
1845259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *              position already seems to correspond to the LayoutParams,
1846259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     *              {@code false} to only reposition if needed
18479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update(int x, int y, int width, int height, boolean force) {
1849259c2840691a79634ffd8f63291ec21c21819542Alan Viverette        if (width >= 0) {
18509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mLastWidth = width;
18519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setWidth(width);
18529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1854259c2840691a79634ffd8f63291ec21c21819542Alan Viverette        if (height >= 0) {
18559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mLastHeight = height;
18569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setHeight(height);
18579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!isShowing() || mContentView == null) {
18609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
18619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18635435a30ae552391f14009c4459731ae149675b18Alan Viverette        final WindowManager.LayoutParams p =
18645435a30ae552391f14009c4459731ae149675b18Alan Viverette                (WindowManager.LayoutParams) mDecorView.getLayoutParams();
18659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean update = force;
18679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int finalWidth = mWidthMode < 0 ? mWidthMode : mLastWidth;
18699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (width != -1 && p.width != finalWidth) {
18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.width = mLastWidth = finalWidth;
18719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
18729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int finalHeight = mHeightMode < 0 ? mHeightMode : mLastHeight;
18759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (height != -1 && p.height != finalHeight) {
18769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.height = mLastHeight = finalHeight;
18779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
18789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p.x != x) {
18819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.x = x;
18829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
18839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (p.y != y) {
18869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.y = y;
18879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
18889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int newAnim = computeAnimationResource();
18919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newAnim != p.windowAnimations) {
18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.windowAnimations = newAnim;
18939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int newFlags = computeFlags(p.flags);
18979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newFlags != p.flags) {
18989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.flags = newFlags;
18999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            update = true;
19009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
190198acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau
19029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (update) {
1903b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio            setLayoutDirectionFromAnchor();
19045435a30ae552391f14009c4459731ae149675b18Alan Viverette            mWindowManager.updateViewLayout(mDecorView, p);
19059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1909259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Updates the position and the dimension of the popup window.
1910259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
1911259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Calling this function also updates the window with the current popup
1912259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * state as described for {@link #update()}.
19139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
19149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the popup's anchor view
1915259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param width the new width, must be >= 0 or -1 to ignore
1916259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param height the new height, must be >= 0 or -1 to ignore
19179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update(View anchor, int width, int height) {
191975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        update(anchor, false, 0, 0, true, width, height);
19209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1923259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Updates the position and the dimension of the popup window.
1924259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
1925259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * Width and height can be set to -1 to update location only. Calling this
1926259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * function also updates the window with the current popup state as
1927259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * described for {@link #update()}.
1928259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * <p>
1929259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * If the view later scrolls to move {@code anchor} to a different
1930259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * location, the popup will be moved correspondingly.
19319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
19329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param anchor the popup's anchor view
19339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param xoff x offset from the view's left edge
19349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param yoff y offset from the view's bottom edge
1935259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param width the new width, must be >= 0 or -1 to ignore
1936259c2840691a79634ffd8f63291ec21c21819542Alan Viverette     * @param height the new height, must be >= 0 or -1 to ignore
19379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void update(View anchor, int xoff, int yoff, int width, int height) {
193975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        update(anchor, true, xoff, yoff, true, width, height);
1940105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
1941105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
1942105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    private void update(View anchor, boolean updateLocation, int xoff, int yoff,
194375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette            boolean updateDimension, int width, int height) {
1944105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
19459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!isShowing() || mContentView == null) {
19469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
19479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
194975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        final WeakReference<View> oldAnchor = mAnchor;
195075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        final boolean needsUpdate = updateLocation && (mAnchorXoff != xoff || mAnchorYoff != yoff);
195181f08086b44a117097960195d2c9072e29644962Gilles Debunne        if (oldAnchor == null || oldAnchor.get() != anchor || (needsUpdate && !mIsDropdown)) {
1952634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            registerForViewTreeChanges(anchor, xoff, yoff, mAnchoredGravity);
195381f08086b44a117097960195d2c9072e29644962Gilles Debunne        } else if (needsUpdate) {
195481f08086b44a117097960195d2c9072e29644962Gilles Debunne            // No need to register again if this is a DropDown, showAsDropDown already did.
195581f08086b44a117097960195d2c9072e29644962Gilles Debunne            mAnchorXoff = xoff;
195681f08086b44a117097960195d2c9072e29644962Gilles Debunne            mAnchorYoff = yoff;
19579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1959105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (updateDimension) {
1960105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            if (width == -1) {
1961105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                width = mPopupWidth;
1962105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            } else {
1963105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                mPopupWidth = width;
1964105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            }
1965105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            if (height == -1) {
1966105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                height = mPopupHeight;
1967105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            } else {
1968105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                mPopupHeight = height;
1969105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            }
19709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1971105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
197275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        final WindowManager.LayoutParams p =
19735435a30ae552391f14009c4459731ae149675b18Alan Viverette                (WindowManager.LayoutParams) mDecorView.getLayoutParams();
197475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        final int x = p.x;
197575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette        final int y = p.y;
1976105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (updateLocation) {
197775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette            updateAboveAnchor(findDropDownPosition(anchor, p, xoff, yoff, mAnchoredGravity));
19789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
197954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell            updateAboveAnchor(findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff,
198054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell                    mAnchoredGravity));
19819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1982b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio
19833e141685003939a9addce21ba2492ea3a8aebee6Romain Guy        update(p.x, p.y, width, height, x != p.x || y != p.y);
19849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Listener that is called when this popup window is dismissed.
19889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface OnDismissListener {
19909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
19919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Called when this popup window is dismissed.
19929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
19939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onDismiss();
19949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1996634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette    private void unregisterForViewTreeChanges() {
1997634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        final View anchor = mAnchor != null ? mAnchor.get() : null;
19989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (anchor != null) {
1999e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette            final ViewTreeObserver vto = anchor.getViewTreeObserver();
20009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            vto.removeOnScrollChangedListener(mOnScrollChangedListener);
20019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2002e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
2003634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        final View anchorRoot = mAnchorRoot != null ? mAnchorRoot.get() : null;
2004634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        if (anchorRoot != null) {
2005634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            anchorRoot.removeOnAttachStateChangeListener(mOnAnchorRootDetachedListener);
2006634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        }
2007634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
20089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAnchor = null;
2009634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        mAnchorRoot = null;
2010634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        mIsAnchorRootAttached = false;
20119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2013634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette    private void registerForViewTreeChanges(View anchor, int xoff, int yoff, int gravity) {
2014634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        unregisterForViewTreeChanges();
2015e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette
2016e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette        final ViewTreeObserver vto = anchor.getViewTreeObserver();
20179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (vto != null) {
20189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            vto.addOnScrollChangedListener(mOnScrollChangedListener);
20199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2021634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        final View anchorRoot = anchor.getRootView();
2022634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        anchorRoot.addOnAttachStateChangeListener(mOnAnchorRootDetachedListener);
2023634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
2024634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        mAnchor = new WeakReference<>(anchor);
2025634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        mAnchorRoot = new WeakReference<>(anchorRoot);
2026634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        mIsAnchorRootAttached = anchorRoot.isAttachedToWindow();
2027634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
20289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAnchorXoff = xoff;
20299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAnchorYoff = yoff;
203054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell        mAnchoredGravity = gravity;
20319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20335435a30ae552391f14009c4459731ae149675b18Alan Viverette    private class PopupDecorView extends FrameLayout {
20348fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        private TransitionListenerAdapter mPendingExitListener;
20358fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
20365435a30ae552391f14009c4459731ae149675b18Alan Viverette        public PopupDecorView(Context context) {
20375435a30ae552391f14009c4459731ae149675b18Alan Viverette            super(context);
20385435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
20399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
20419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean dispatchKeyEvent(KeyEvent event) {
20429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
20434ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson                if (getKeyDispatcherState() == null) {
20444ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson                    return super.dispatchKeyEvent(event);
20454ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson                }
20464ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson
20475435a30ae552391f14009c4459731ae149675b18Alan Viverette                if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
20485435a30ae552391f14009c4459731ae149675b18Alan Viverette                    final KeyEvent.DispatcherState state = getKeyDispatcherState();
2049b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                    if (state != null) {
2050b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                        state.startTracking(event, this);
2051b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                    }
20528d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                    return true;
2053b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                } else if (event.getAction() == KeyEvent.ACTION_UP) {
20545435a30ae552391f14009c4459731ae149675b18Alan Viverette                    final KeyEvent.DispatcherState state = getKeyDispatcherState();
2055b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                    if (state != null && state.isTracking(event) && !event.isCanceled()) {
2056b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                        dismiss();
2057b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                        return true;
2058b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                    }
20598d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                }
20608d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                return super.dispatchKeyEvent(event);
20619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
20629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return super.dispatchKeyEvent(event);
20639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
20649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
20679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean dispatchTouchEvent(MotionEvent ev) {
20689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mTouchInterceptor != null && mTouchInterceptor.onTouch(this, ev)) {
20699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
20709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
20719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return super.dispatchTouchEvent(ev);
20729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
20759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean onTouchEvent(MotionEvent event) {
20769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int x = (int) event.getX();
20779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int y = (int) event.getY();
20785435a30ae552391f14009c4459731ae149675b18Alan Viverette
20799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((event.getAction() == MotionEvent.ACTION_DOWN)
20809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    && ((x < 0) || (x >= getWidth()) || (y < 0) || (y >= getHeight()))) {
20819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dismiss();
20829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
20839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
20849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dismiss();
20859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
20869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
20879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return super.onTouchEvent(event);
20889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
20899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20908fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
20918fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        /**
20928fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * Requests that an enter transition run after the next layout pass.
20938fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         */
20948fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        public void requestEnterTransition(Transition transition) {
20958fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            final ViewTreeObserver observer = getViewTreeObserver();
20968fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            if (observer != null && transition != null) {
20978fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                final Transition enterTransition = transition.clone();
20988fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
20998fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                // Postpone the enter transition after the first layout pass.
21008fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
21018fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                    @Override
21028fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                    public void onGlobalLayout() {
21038fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                        final ViewTreeObserver observer = getViewTreeObserver();
21048fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                        if (observer != null) {
21058fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                            observer.removeOnGlobalLayoutListener(this);
21068fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                        }
21078fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
210891098574f90277128415e9593cce1e495cc51465Alan Viverette                        final Rect epicenter = getTransitionEpicenter();
210995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                        enterTransition.setEpicenterCallback(new EpicenterCallback() {
211095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                            @Override
211195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                            public Rect onGetEpicenter(Transition transition) {
211295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                                return epicenter;
211395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                            }
211495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette                        });
21158fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                        startEnterTransition(enterTransition);
21168fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                    }
21178fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                });
21188fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
21198fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
21208fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
21218fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        /**
21228fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * Starts the pending enter transition, if one is set.
21238fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         */
21248fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        private void startEnterTransition(Transition enterTransition) {
21258fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            final int count = getChildCount();
21268fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            for (int i = 0; i < count; i++) {
21278fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                final View child = getChildAt(i);
21288fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                enterTransition.addTarget(child);
21298fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                child.setVisibility(View.INVISIBLE);
21308fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
21318fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
21328fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            TransitionManager.beginDelayedTransition(this, enterTransition);
21338fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
21348fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            for (int i = 0; i < count; i++) {
21358fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                final View child = getChildAt(i);
21368fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                child.setVisibility(View.VISIBLE);
21378fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
21388fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
21398fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
21408fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        /**
21418fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * Starts an exit transition immediately.
21428fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * <p>
21438fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * <strong>Note:</strong> The transition listener is guaranteed to have
21448fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * its {@code onTransitionEnd} method called even if the transition
21458fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * never starts; however, it may be called with a {@code null} argument.
21468fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         */
2147634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        public void startExitTransition(Transition transition, final View anchorRoot,
2148634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                final TransitionListener listener) {
21498fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            if (transition == null) {
21508fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                return;
21518fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
21528fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
2153634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            // The anchor view's window may go away while we're executing our
2154634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            // transition, in which case we need to end the transition
2155634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            // immediately and execute the listener to remove the popup.
2156634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette            anchorRoot.addOnAttachStateChangeListener(mOnAnchorRootDetachedListener);
2157634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
21588fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            // The exit listener MUST be called for cleanup, even if the
21598fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            // transition never starts or ends. Stash it for later.
21608fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            mPendingExitListener = new TransitionListenerAdapter() {
21618fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                @Override
21628fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                public void onTransitionEnd(Transition transition) {
2163634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    anchorRoot.removeOnAttachStateChangeListener(mOnAnchorRootDetachedListener);
21648fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                    listener.onTransitionEnd(transition);
21658fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
21668fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                    // The listener was called. Our job here is done.
21678fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                    mPendingExitListener = null;
21688fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                }
21698fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            };
21708fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
21718fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            final Transition exitTransition = transition.clone();
21728fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            exitTransition.addListener(mPendingExitListener);
21738fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
21748fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            final int count = getChildCount();
21758fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            for (int i = 0; i < count; i++) {
21768fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                final View child = getChildAt(i);
21778fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                exitTransition.addTarget(child);
21788fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
21798fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
21808fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            TransitionManager.beginDelayedTransition(this, exitTransition);
21818fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
21828fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            for (int i = 0; i < count; i++) {
21838fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                final View child = getChildAt(i);
21848fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                child.setVisibility(View.INVISIBLE);
21858fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
21868fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
21878fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
21888fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        /**
21898fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         * Cancels all pending or current transitions.
21908fd949e680c15d397084430d4907c16cedfacddaAlan Viverette         */
21918fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        public void cancelTransitions() {
21928fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            TransitionManager.endTransitions(this);
21938fd949e680c15d397084430d4907c16cedfacddaAlan Viverette
21948fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            if (mPendingExitListener != null) {
21958fd949e680c15d397084430d4907c16cedfacddaAlan Viverette                mPendingExitListener.onTransitionEnd(null);
21968fd949e680c15d397084430d4907c16cedfacddaAlan Viverette            }
21978fd949e680c15d397084430d4907c16cedfacddaAlan Viverette        }
2198634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
2199634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette        private final OnAttachStateChangeListener mOnAnchorRootDetachedListener =
2200634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                new OnAttachStateChangeListener() {
2201634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    @Override
2202634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    public void onViewAttachedToWindow(View v) {}
2203634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
2204634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    @Override
2205634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    public void onViewDetachedFromWindow(View v) {
2206634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                        v.removeOnAttachStateChangeListener(this);
2207634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette
2208634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                        TransitionManager.endTransitions(PopupDecorView.this);
2209634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                    }
2210634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette                };
22115435a30ae552391f14009c4459731ae149675b18Alan Viverette    }
22125435a30ae552391f14009c4459731ae149675b18Alan Viverette
22135435a30ae552391f14009c4459731ae149675b18Alan Viverette    private class PopupBackgroundView extends FrameLayout {
22145435a30ae552391f14009c4459731ae149675b18Alan Viverette        public PopupBackgroundView(Context context) {
22155435a30ae552391f14009c4459731ae149675b18Alan Viverette            super(context);
22165435a30ae552391f14009c4459731ae149675b18Alan Viverette        }
221775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov
221875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        @Override
22195435a30ae552391f14009c4459731ae149675b18Alan Viverette        protected int[] onCreateDrawableState(int extraSpace) {
22205435a30ae552391f14009c4459731ae149675b18Alan Viverette            if (mAboveAnchor) {
22215435a30ae552391f14009c4459731ae149675b18Alan Viverette                final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
22225435a30ae552391f14009c4459731ae149675b18Alan Viverette                View.mergeDrawableStates(drawableState, ABOVE_ANCHOR_STATE_SET);
22235435a30ae552391f14009c4459731ae149675b18Alan Viverette                return drawableState;
222475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            } else {
22255435a30ae552391f14009c4459731ae149675b18Alan Viverette                return super.onCreateDrawableState(extraSpace);
222675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov            }
222775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov        }
22289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2230