PopupWindow.java revision 1e940dc2d165fa6cdedb6945811988502f87ddce
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport com.android.internal.R; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viveretteimport android.annotation.NonNull; 221e940dc2d165fa6cdedb6945811988502f87ddceAlan Viveretteimport android.annotation.Nullable; 2375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.Context; 2475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.res.TypedArray; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PixelFormat; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.Drawable; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.StateListDrawable; 2946e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brownimport android.os.Build; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 315435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.Transition; 325435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.Transition.EpicenterCallback; 338fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.transition.Transition.TransitionListener; 348fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.transition.Transition.TransitionListenerAdapter; 355435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.TransitionInflater; 365435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.TransitionManager; 375435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.TransitionSet; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 39c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.Gravity; 40c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.KeyEvent; 41c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.MotionEvent; 42c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.View; 43634a808226cc5d00bd6897bdc881cafe064e37acAlan Viveretteimport android.view.View.OnAttachStateChangeListener; 44a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport android.view.View.OnTouchListener; 45c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.ViewGroup; 468fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.view.ViewParent; 47c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.ViewTreeObserver; 488fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.view.ViewTreeObserver.OnGlobalLayoutListener; 49c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.ViewTreeObserver.OnScrollChangedListener; 50a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport android.view.WindowManager; 51259c2840691a79634ffd8f63291ec21c21819542Alan Viveretteimport android.view.WindowManager.LayoutParams; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 53a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport java.lang.ref.WeakReference; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 551e940dc2d165fa6cdedb6945811988502f87ddceAlan Viveretteimport static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME; 561e940dc2d165fa6cdedb6945811988502f87ddceAlan Viveretteimport static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH; 571e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 591e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <p> 601e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * This class represents a popup window that can be used to display an 611e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * arbitrary view. The popup window is a floating container that appears on top 621e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * of the current activity. 631e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </p> 641e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <a name="Animation"></a> 651e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <h3>Animation</h3> 661e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <p> 671e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * On all versions of Android, popup window enter and exit animations may be 681e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * specified by calling {@link #setAnimationStyle(int)} and passing the 691e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * resource ID for an animation style that defines {@code windowEnterAnimation} 701e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * and {@code windowExitAnimation}. For example, passing 711e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * {@link android.R.style#Animation_Dialog} will give a scale and alpha 721e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * animation. 731e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </br> 741e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * A window animation style may also be specified in the popup window's style 751e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * XML via the {@link android.R.styleable#PopupWindow_popupAnimationStyle popupAnimationStyle} 761e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * attribute. 771e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </p> 781e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <p> 791e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * Starting with API 23, more complex popup window enter and exit transitions 801e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * may be specified by calling either {@link #setEnterTransition(Transition)} 811e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * or {@link #setExitTransition(Transition)} and passing a {@link Transition}. 821e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </br> 831e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * Popup enter and exit transitions may also be specified in the popup window's 841e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * style XML via the {@link android.R.styleable#PopupWindow_popupEnterTransition popupEnterTransition} 851e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * and {@link android.R.styleable#PopupWindow_popupExitTransition popupExitTransition} 861e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * attributes, respectively. 871e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </p> 881e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * 891e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_overlapAnchor 901e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupAnimationStyle 911e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupBackground 921e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupElevation 931e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupEnterTransition 941e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupExitTransition 955435a30ae552391f14009c4459731ae149675b18Alan Viverette * 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.widget.AutoCompleteTextView 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.widget.Spinner 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class PopupWindow { 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 101e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * Mode for {@link #setInputMethodMode(int)}: the requirements for the 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * input method should be based on the focusability of the popup. That is 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if it is focusable than it needs to work with the input method, else 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * it doesn't. 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int INPUT_METHOD_FROM_FOCUSABLE = 0; 1075435a30ae552391f14009c4459731ae149675b18Alan Viverette 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 109e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * Mode for {@link #setInputMethodMode(int)}: this popup always needs to 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * work with an input method, regardless of whether it is focusable. This 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * means that it will always be displayed so that the user can also operate 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the input method while it is shown. 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int INPUT_METHOD_NEEDED = 1; 1155435a30ae552391f14009c4459731ae149675b18Alan Viverette 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 117e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * Mode for {@link #setInputMethodMode(int)}: this popup never needs to 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * work with an input method, regardless of whether it is focusable. This 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * means that it will always be displayed to use as much space on the 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * screen as needed, regardless of whether this covers the input method. 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int INPUT_METHOD_NOT_NEEDED = 2; 12354c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 12454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell private static final int DEFAULT_ANCHORED_GRAVITY = Gravity.TOP | Gravity.START; 12554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 1265435a30ae552391f14009c4459731ae149675b18Alan Viverette /** 1275435a30ae552391f14009c4459731ae149675b18Alan Viverette * Default animation style indicating that separate animations should be 1285435a30ae552391f14009c4459731ae149675b18Alan Viverette * used for top/bottom anchoring states. 1295435a30ae552391f14009c4459731ae149675b18Alan Viverette */ 1305435a30ae552391f14009c4459731ae149675b18Alan Viverette private static final int ANIMATION_STYLE_DEFAULT = -1; 1315435a30ae552391f14009c4459731ae149675b18Alan Viverette 1325435a30ae552391f14009c4459731ae149675b18Alan Viverette private final int[] mDrawingLocation = new int[2]; 1335435a30ae552391f14009c4459731ae149675b18Alan Viverette private final int[] mScreenLocation = new int[2]; 1345435a30ae552391f14009c4459731ae149675b18Alan Viverette private final Rect mTempRect = new Rect(); 1355435a30ae552391f14009c4459731ae149675b18Alan Viverette 136448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy private Context mContext; 137448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy private WindowManager mWindowManager; 1385435a30ae552391f14009c4459731ae149675b18Alan Viverette 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mIsShowing; 1408fd949e680c15d397084430d4907c16cedfacddaAlan Viverette private boolean mIsTransitioningToDismiss; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mIsDropdown; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1435435a30ae552391f14009c4459731ae149675b18Alan Viverette /** View that handles event dispatch and content transitions. */ 1445435a30ae552391f14009c4459731ae149675b18Alan Viverette private PopupDecorView mDecorView; 1455435a30ae552391f14009c4459731ae149675b18Alan Viverette 146697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette /** View that holds the background and may animate during a transition. */ 147697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette private View mBackgroundView; 148697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette 149697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette /** The contents of the popup. May be identical to the background view. */ 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View mContentView; 1515435a30ae552391f14009c4459731ae149675b18Alan Viverette 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mFocusable; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mInputMethodMode = INPUT_METHOD_FROM_FOCUSABLE; 1547eab094722af54717859b7dcce3cc050f059e00bDianne Hackborn private int mSoftInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED; 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mTouchable = true; 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mOutsideTouchable = false; 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mClippingEnabled = true; 15846e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown private int mSplitTouchEnabled = -1; 159ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell private boolean mLayoutInScreen; 16056c2d337e02a275397fc9d0460dca90977f199acAdam Powell private boolean mClipToScreen; 161348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell private boolean mAllowScrollingAnchorParent = true; 1620bd1d0a15294345bf88b20df28466907f982cec7Adam Powell private boolean mLayoutInsetDecor = false; 163e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell private boolean mNotTouchModal; 164393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale private boolean mAttachedInDecor = true; 165393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale private boolean mAttachedInDecorSet = false; 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnTouchListener mTouchInterceptor; 168393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mWidthMode; 170259c2840691a79634ffd8f63291ec21c21819542Alan Viverette private int mWidth = LayoutParams.WRAP_CONTENT; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLastWidth; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mHeightMode; 173259c2840691a79634ffd8f63291ec21c21819542Alan Viverette private int mHeight = LayoutParams.WRAP_CONTENT; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLastHeight; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mPopupWidth; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mPopupHeight; 17856c2d337e02a275397fc9d0460dca90977f199acAdam Powell 179ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette private float mElevation; 180ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Drawable mBackground; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Drawable mAboveAnchorBackgroundDrawable; 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Drawable mBelowAnchorBackgroundDrawable; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1855435a30ae552391f14009c4459731ae149675b18Alan Viverette private Transition mEnterTransition; 1865435a30ae552391f14009c4459731ae149675b18Alan Viverette private Transition mExitTransition; 18791098574f90277128415e9593cce1e495cc51465Alan Viverette private Rect mEpicenterBounds; 188560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mAboveAnchor; 190574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell private int mWindowLayoutType = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; 1915435a30ae552391f14009c4459731ae149675b18Alan Viverette 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnDismissListener mOnDismissListener; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mIgnoreCheekPress = false; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1955435a30ae552391f14009c4459731ae149675b18Alan Viverette private int mAnimationStyle = ANIMATION_STYLE_DEFAULT; 1965435a30ae552391f14009c4459731ae149675b18Alan Viverette 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int[] ABOVE_ANCHOR_STATE_SET = new int[] { 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.attr.state_above_anchor 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 201634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette private final OnAttachStateChangeListener mOnAnchorRootDetachedListener = 202634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette new OnAttachStateChangeListener() { 203634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette @Override 204634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette public void onViewAttachedToWindow(View v) {} 205634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 206634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette @Override 207634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette public void onViewDetachedFromWindow(View v) { 208634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette mIsAnchorRootAttached = false; 209634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette } 210634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette }; 211634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private WeakReference<View> mAnchor; 213634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette private WeakReference<View> mAnchorRoot; 214634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette private boolean mIsAnchorRootAttached; 215560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 2165435a30ae552391f14009c4459731ae149675b18Alan Viverette private final OnScrollChangedListener mOnScrollChangedListener = new OnScrollChangedListener() { 2175435a30ae552391f14009c4459731ae149675b18Alan Viverette @Override 2185435a30ae552391f14009c4459731ae149675b18Alan Viverette public void onScrollChanged() { 2195435a30ae552391f14009c4459731ae149675b18Alan Viverette final View anchor = mAnchor != null ? mAnchor.get() : null; 2205435a30ae552391f14009c4459731ae149675b18Alan Viverette if (anchor != null && mDecorView != null) { 2215435a30ae552391f14009c4459731ae149675b18Alan Viverette final WindowManager.LayoutParams p = (WindowManager.LayoutParams) 2225435a30ae552391f14009c4459731ae149675b18Alan Viverette mDecorView.getLayoutParams(); 2235435a30ae552391f14009c4459731ae149675b18Alan Viverette 2245435a30ae552391f14009c4459731ae149675b18Alan Viverette updateAboveAnchor(findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff, 2255435a30ae552391f14009c4459731ae149675b18Alan Viverette mAnchoredGravity)); 2265435a30ae552391f14009c4459731ae149675b18Alan Viverette update(p.x, p.y, -1, -1, true); 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2285435a30ae552391f14009c4459731ae149675b18Alan Viverette } 2295435a30ae552391f14009c4459731ae149675b18Alan Viverette }; 230560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 2315435a30ae552391f14009c4459731ae149675b18Alan Viverette private int mAnchorXoff; 2325435a30ae552391f14009c4459731ae149675b18Alan Viverette private int mAnchorYoff; 2335435a30ae552391f14009c4459731ae149675b18Alan Viverette private int mAnchoredGravity; 234560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette private boolean mOverlapAnchor; 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 236b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio private boolean mPopupViewInitialLayoutDirectionInherited; 237b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window of dimension (0,0).</p> 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does provide a background.</p> 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(Context context) { 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, null); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window of dimension (0,0).</p> 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does provide a background.</p> 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(Context context, AttributeSet attrs) { 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, attrs, com.android.internal.R.attr.popupWindowStyle); 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window of dimension (0,0).</p> 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does provide a background.</p> 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 261617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr) { 262617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette this(context, attrs, defStyleAttr, 0); 263c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 2645435a30ae552391f14009c4459731ae149675b18Alan Viverette 265c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 266c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>Create a new, empty, non focusable popup window of dimension (0,0).</p> 2675435a30ae552391f14009c4459731ae149675b18Alan Viverette * 268c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>The popup does not provide a background.</p> 269c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 270c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 27275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 274617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette final TypedArray a = context.obtainStyledAttributes( 275ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette attrs, R.styleable.PopupWindow, defStyleAttr, defStyleRes); 276ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette final Drawable bg = a.getDrawable(R.styleable.PopupWindow_popupBackground); 277ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette mElevation = a.getDimension(R.styleable.PopupWindow_popupElevation, 0); 278560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette mOverlapAnchor = a.getBoolean(R.styleable.PopupWindow_overlapAnchor, false); 279c3808b5dc7d5873d04e8a0a247b179b2757764baAdam Powell 2805435a30ae552391f14009c4459731ae149675b18Alan Viverette // Preserve default behavior from Gingerbread. If the animation is 2815435a30ae552391f14009c4459731ae149675b18Alan Viverette // undefined or explicitly specifies the Gingerbread animation style, 2825435a30ae552391f14009c4459731ae149675b18Alan Viverette // use a sentinel value. 2835435a30ae552391f14009c4459731ae149675b18Alan Viverette if (a.hasValueOrEmpty(R.styleable.PopupWindow_popupAnimationStyle)) { 2845435a30ae552391f14009c4459731ae149675b18Alan Viverette final int animStyle = a.getResourceId(R.styleable.PopupWindow_popupAnimationStyle, 0); 2855435a30ae552391f14009c4459731ae149675b18Alan Viverette if (animStyle == R.style.Animation_PopupWindow) { 2865435a30ae552391f14009c4459731ae149675b18Alan Viverette mAnimationStyle = ANIMATION_STYLE_DEFAULT; 2875435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 2885435a30ae552391f14009c4459731ae149675b18Alan Viverette mAnimationStyle = animStyle; 2895435a30ae552391f14009c4459731ae149675b18Alan Viverette } 2905435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 2915435a30ae552391f14009c4459731ae149675b18Alan Viverette mAnimationStyle = ANIMATION_STYLE_DEFAULT; 2925435a30ae552391f14009c4459731ae149675b18Alan Viverette } 2935435a30ae552391f14009c4459731ae149675b18Alan Viverette 2945435a30ae552391f14009c4459731ae149675b18Alan Viverette final Transition enterTransition = getTransition(a.getResourceId( 2955435a30ae552391f14009c4459731ae149675b18Alan Viverette R.styleable.PopupWindow_popupEnterTransition, 0)); 2965435a30ae552391f14009c4459731ae149675b18Alan Viverette final Transition exitTransition; 2975435a30ae552391f14009c4459731ae149675b18Alan Viverette if (a.hasValueOrEmpty(R.styleable.PopupWindow_popupExitTransition)) { 2985435a30ae552391f14009c4459731ae149675b18Alan Viverette exitTransition = getTransition(a.getResourceId( 2995435a30ae552391f14009c4459731ae149675b18Alan Viverette R.styleable.PopupWindow_popupExitTransition, 0)); 3005435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 3015435a30ae552391f14009c4459731ae149675b18Alan Viverette exitTransition = enterTransition == null ? null : enterTransition.clone(); 3025435a30ae552391f14009c4459731ae149675b18Alan Viverette } 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 305ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 3065435a30ae552391f14009c4459731ae149675b18Alan Viverette setEnterTransition(enterTransition); 3075435a30ae552391f14009c4459731ae149675b18Alan Viverette setExitTransition(exitTransition); 308ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette setBackgroundDrawable(bg); 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window of dimension (0,0).</p> 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow() { 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(null, 0, 0); 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new non focusable popup window which can display the 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tt>contentView</tt>. The dimension of the window are (0,0).</p> 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param contentView the popup's content 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(View contentView) { 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(contentView, 0, 0); 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window. The dimension of the 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window must be passed to this constructor.</p> 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param width the popup's width 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param height the popup's height 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(int width, int height) { 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(null, width, height); 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new non focusable popup window which can display the 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tt>contentView</tt>. The dimension of the window must be passed to 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this constructor.</p> 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param contentView the popup's content 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param width the popup's width 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param height the popup's height 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(View contentView, int width, int height) { 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(contentView, width, height, false); 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new popup window which can display the <tt>contentView</tt>. 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The dimension of the window must be passed to this constructor.</p> 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param contentView the popup's content 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param width the popup's width 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param height the popup's height 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param focusable true if the popup can be focused, false otherwise 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 376448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy public PopupWindow(View contentView, int width, int height, boolean focusable) { 377448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy if (contentView != null) { 378448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy mContext = contentView.getContext(); 379448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); 380448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy } 381393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setContentView(contentView); 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setWidth(width); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setHeight(height); 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setFocusable(focusable); 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3881e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette /** 3891e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * Sets the enter transition to be used when the popup window is shown. 3901e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * 3911e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @param enterTransition the enter transition, or {@code null} to clear 3921e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @see #getEnterTransition() 3931e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupEnterTransition 3941e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette */ 3951e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette public void setEnterTransition(@Nullable Transition enterTransition) { 3965435a30ae552391f14009c4459731ae149675b18Alan Viverette mEnterTransition = enterTransition; 3975435a30ae552391f14009c4459731ae149675b18Alan Viverette } 3985435a30ae552391f14009c4459731ae149675b18Alan Viverette 3991e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette /** 4001e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * Returns the enter transition to be used when the popup window is shown. 4011e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * 4021e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @return the enter transition, or {@code null} if not set 4031e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @see #setEnterTransition(Transition) 4041e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupEnterTransition 4051e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette */ 4061e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette @Nullable 4071e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette public Transition getEnterTransition() { 4081e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette return mEnterTransition; 4091e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette } 4101e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette 4111e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette /** 4121e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * Sets the exit transition to be used when the popup window is dismissed. 4131e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * 4141e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @param exitTransition the exit transition, or {@code null} to clear 4151e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @see #getExitTransition() 4161e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupExitTransition 4171e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette */ 4181e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette public void setExitTransition(@Nullable Transition exitTransition) { 4195435a30ae552391f14009c4459731ae149675b18Alan Viverette mExitTransition = exitTransition; 4205435a30ae552391f14009c4459731ae149675b18Alan Viverette } 4215435a30ae552391f14009c4459731ae149675b18Alan Viverette 42291098574f90277128415e9593cce1e495cc51465Alan Viverette /** 4231e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * Returns the exit transition to be used when the popup window is 4241e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * dismissed. 4251e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * 4261e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @return the exit transition, or {@code null} if not set 4271e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @see #setExitTransition(Transition) 4281e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupExitTransition 4291e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette */ 4301e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette @Nullable 4311e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette public Transition getExitTransition() { 4321e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette return mExitTransition; 4331e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette } 4341e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette 4351e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette /** 43691098574f90277128415e9593cce1e495cc51465Alan Viverette * Sets the bounds used as the epicenter of the enter and exit transitions. 43791098574f90277128415e9593cce1e495cc51465Alan Viverette * <p> 43891098574f90277128415e9593cce1e495cc51465Alan Viverette * Transitions use a point or Rect, referred to as the epicenter, to orient 43991098574f90277128415e9593cce1e495cc51465Alan Viverette * the direction of travel. For popup windows, the anchor view bounds are 44091098574f90277128415e9593cce1e495cc51465Alan Viverette * used as the default epicenter. 44191098574f90277128415e9593cce1e495cc51465Alan Viverette * <p> 44291098574f90277128415e9593cce1e495cc51465Alan Viverette * See {@link Transition#setEpicenterCallback(EpicenterCallback)} for more 44391098574f90277128415e9593cce1e495cc51465Alan Viverette * information about how transition epicenters. 44491098574f90277128415e9593cce1e495cc51465Alan Viverette * 44591098574f90277128415e9593cce1e495cc51465Alan Viverette * @param bounds the epicenter bounds relative to the anchor view, or 44691098574f90277128415e9593cce1e495cc51465Alan Viverette * {@code null} to use the default epicenter 44791098574f90277128415e9593cce1e495cc51465Alan Viverette * @see #getTransitionEpicenter() 44891098574f90277128415e9593cce1e495cc51465Alan Viverette * @hide 44991098574f90277128415e9593cce1e495cc51465Alan Viverette */ 45091098574f90277128415e9593cce1e495cc51465Alan Viverette public void setEpicenterBounds(Rect bounds) { 45191098574f90277128415e9593cce1e495cc51465Alan Viverette mEpicenterBounds = bounds; 45291098574f90277128415e9593cce1e495cc51465Alan Viverette } 45391098574f90277128415e9593cce1e495cc51465Alan Viverette 4545435a30ae552391f14009c4459731ae149675b18Alan Viverette private Transition getTransition(int resId) { 4555435a30ae552391f14009c4459731ae149675b18Alan Viverette if (resId != 0 && resId != R.transition.no_transition) { 4565435a30ae552391f14009c4459731ae149675b18Alan Viverette final TransitionInflater inflater = TransitionInflater.from(mContext); 4575435a30ae552391f14009c4459731ae149675b18Alan Viverette final Transition transition = inflater.inflateTransition(resId); 4585435a30ae552391f14009c4459731ae149675b18Alan Viverette if (transition != null) { 4595435a30ae552391f14009c4459731ae149675b18Alan Viverette final boolean isEmpty = transition instanceof TransitionSet 4605435a30ae552391f14009c4459731ae149675b18Alan Viverette && ((TransitionSet) transition).getTransitionCount() == 0; 4615435a30ae552391f14009c4459731ae149675b18Alan Viverette if (!isEmpty) { 4625435a30ae552391f14009c4459731ae149675b18Alan Viverette return transition; 4635435a30ae552391f14009c4459731ae149675b18Alan Viverette } 4645435a30ae552391f14009c4459731ae149675b18Alan Viverette } 4655435a30ae552391f14009c4459731ae149675b18Alan Viverette } 4665435a30ae552391f14009c4459731ae149675b18Alan Viverette return null; 4675435a30ae552391f14009c4459731ae149675b18Alan Viverette } 4685435a30ae552391f14009c4459731ae149675b18Alan Viverette 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 470ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * Return the drawable used as the popup window's background. 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 472ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @return the background drawable or {@code null} if not set 473ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @see #setBackgroundDrawable(Drawable) 474ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @attr ref android.R.styleable#PopupWindow_popupBackground 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable getBackground() { 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBackground; 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 481ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * Specifies the background drawable for this popup window. The background 482ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * can be set to {@code null}. 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param background the popup's background 485ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @see #getBackground() 486ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @attr ref android.R.styleable#PopupWindow_popupBackground 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setBackgroundDrawable(Drawable background) { 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBackground = background; 490ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 491ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // If this is a StateListDrawable, try to find and store the drawable to be 492ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // used when the drop-down is placed above its anchor view, and the one to be 493ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // used when the drop-down is placed below its anchor view. We extract 494ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // the drawables ourselves to work around a problem with using refreshDrawableState 495ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // that it will take into account the padding of all drawables specified in a 496ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // StateListDrawable, thus adding superfluous padding to drop-down views. 497ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // 498ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // We assume a StateListDrawable will have a drawable for ABOVE_ANCHOR_STATE_SET and 499ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // at least one other drawable, intended for the 'below-anchor state'. 500ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette if (mBackground instanceof StateListDrawable) { 501ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette StateListDrawable stateList = (StateListDrawable) mBackground; 502ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 503ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // Find the above-anchor view - this one's easy, it should be labeled as such. 504ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette int aboveAnchorStateIndex = stateList.getStateDrawableIndex(ABOVE_ANCHOR_STATE_SET); 505ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 506ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // Now, for the below-anchor view, look for any other drawable specified in the 507ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // StateListDrawable which is not for the above-anchor state and use that. 508ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette int count = stateList.getStateCount(); 509ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette int belowAnchorStateIndex = -1; 510ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette for (int i = 0; i < count; i++) { 511ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette if (i != aboveAnchorStateIndex) { 512ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette belowAnchorStateIndex = i; 513ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette break; 514ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } 515ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } 516ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 517ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // Store the drawables we found, if we found them. Otherwise, set them both 518ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // to null so that we'll just use refreshDrawableState. 519ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette if (aboveAnchorStateIndex != -1 && belowAnchorStateIndex != -1) { 520ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette mAboveAnchorBackgroundDrawable = stateList.getStateDrawable(aboveAnchorStateIndex); 521ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette mBelowAnchorBackgroundDrawable = stateList.getStateDrawable(belowAnchorStateIndex); 522ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } else { 523ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette mBelowAnchorBackgroundDrawable = null; 524ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette mAboveAnchorBackgroundDrawable = null; 525ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } 526ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 530ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @return the elevation for this popup window in pixels 531ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @see #setElevation(float) 532ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @attr ref android.R.styleable#PopupWindow_popupElevation 533ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette */ 534ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette public float getElevation() { 535ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette return mElevation; 536ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette } 537ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette 538ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette /** 539ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * Specifies the elevation for this popup window. 540ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * 541ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @param elevation the popup's elevation in pixels 542ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @see #getElevation() 543ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @attr ref android.R.styleable#PopupWindow_popupElevation 544ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette */ 545ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette public void setElevation(float elevation) { 546ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette mElevation = elevation; 547ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette } 548ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette 549ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette /** 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Return the animation style to use the popup appears and disappears</p> 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the animation style to use the popup appears and disappears 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getAnimationStyle() { 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAnimationStyle; 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 557393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 55954ec76d81ac38284caa6d00ad5f2d2207206b9ceShuhrat Dehkanov * Set the flag on popup to ignore cheek press events; by default this flag 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is set to false 56154ec76d81ac38284caa6d00ad5f2d2207206b9ceShuhrat Dehkanov * which means the popup will not ignore cheek press dispatch events. 5625435a30ae552391f14009c4459731ae149675b18Alan Viverette * 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 566393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setIgnoreCheekPress() { 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIgnoreCheekPress = true; 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5725435a30ae552391f14009c4459731ae149675b18Alan Viverette 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Change the animation style resource for this popup.</p> 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param animationStyle animation style to use when the popup appears 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and disappears. Set to -1 for the default animation, 0 for no 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * animation, or a resource identifier for an explicit animation. 5845435a30ae552391f14009c4459731ae149675b18Alan Viverette * 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAnimationStyle(int animationStyle) { 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimationStyle = animationStyle; 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5905435a30ae552391f14009c4459731ae149675b18Alan Viverette 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Return the view used as the content of the popup window.</p> 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return a {@link android.view.View} representing the popup's content 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setContentView(android.view.View) 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public View getContentView() { 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mContentView; 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Change the popup's content. The content is represented by an instance 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of {@link android.view.View}.</p> 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 60681f08086b44a117097960195d2c9072e29644962Gilles Debunne * <p>This method has no effect if called when the popup is showing.</p> 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param contentView the new content for the popup 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getContentView() 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isShowing() 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setContentView(View contentView) { 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isShowing()) { 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentView = contentView; 619448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy 6200c0b768e1514280812321854db6dfba723c3d169Romain Guy if (mContext == null && mContentView != null) { 621448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy mContext = mContentView.getContext(); 622448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy } 623448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy 6240c0b768e1514280812321854db6dfba723c3d169Romain Guy if (mWindowManager == null && mContentView != null) { 625448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); 626448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy } 627393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 628393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // Setting the default for attachedInDecor based on SDK version here 629393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // instead of in the constructor since we might not have the context 630393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // object in the constructor. We only want to set default here if the 631393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // app hasn't already set the attachedInDecor. 632393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale if (mContext != null && !mAttachedInDecorSet) { 633393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // Attach popup window in decor frame of parent window by default for 634393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // {@link Build.VERSION_CODES.LOLLIPOP_MR1} or greater. Keep current 635393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // behavior of not attaching to decor frame for older SDKs. 636393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale setAttachedInDecor(mContext.getApplicationInfo().targetSdkVersion 637393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale >= Build.VERSION_CODES.LOLLIPOP_MR1); 638393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale } 639393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set a callback for all touch events being dispatched to the popup 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window. 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTouchInterceptor(OnTouchListener l) { 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTouchInterceptor = l; 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 649393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicate whether the popup window can grab the focus.</p> 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is focusable, false otherwise 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setFocusable(boolean) 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isFocusable() { 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFocusable; 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Changes the focusability of the popup window. When focusable, the 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window will grab the focus from the current focused widget if the popup 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * contains a focusable {@link android.view.View}. By default a popup 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window is not focusable.</p> 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param focusable true if the popup should grab focus, false otherwise. 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isFocusable() 6745435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setFocusable(boolean focusable) { 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFocusable = focusable; 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the current value in {@link #setInputMethodMode(int)}. 6835435a30ae552391f14009c4459731ae149675b18Alan Viverette * 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setInputMethodMode(int) 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getInputMethodMode() { 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mInputMethodMode; 6885435a30ae552391f14009c4459731ae149675b18Alan Viverette 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6905435a30ae552391f14009c4459731ae149675b18Alan Viverette 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Control how the popup operates with an input method: one of 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #INPUT_METHOD_FROM_FOCUSABLE}, {@link #INPUT_METHOD_NEEDED}, 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or {@link #INPUT_METHOD_NOT_NEEDED}. 6955435a30ae552391f14009c4459731ae149675b18Alan Viverette * 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 6995435a30ae552391f14009c4459731ae149675b18Alan Viverette * 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getInputMethodMode() 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setInputMethodMode(int mode) { 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mInputMethodMode = mode; 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 706374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy 707374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy /** 708374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * Sets the operating mode for the soft input area. 709374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * 710374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @param mode The desired mode, see 711374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * {@link android.view.WindowManager.LayoutParams#softInputMode} 712374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * for the full list 713374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * 714374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @see android.view.WindowManager.LayoutParams#softInputMode 715374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @see #getSoftInputMode() 716374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy */ 717374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy public void setSoftInputMode(int mode) { 718374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy mSoftInputMode = mode; 719374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy } 720374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy 721374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy /** 722374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * Returns the current value in {@link #setSoftInputMode(int)}. 723374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * 724374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @see #setSoftInputMode(int) 725374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @see android.view.WindowManager.LayoutParams#softInputMode 726374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy */ 727374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy public int getSoftInputMode() { 728374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy return mSoftInputMode; 729374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy } 7305435a30ae552391f14009c4459731ae149675b18Alan Viverette 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicates whether the popup window receives touch events.</p> 7335435a30ae552391f14009c4459731ae149675b18Alan Viverette * 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is touchable, false otherwise 7355435a30ae552391f14009c4459731ae149675b18Alan Viverette * 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setTouchable(boolean) 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isTouchable() { 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mTouchable; 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Changes the touchability of the popup window. When touchable, the 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window will receive touch events, otherwise touch events will go to the 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window below it. By default the window is touchable.</p> 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param touchable true if the popup should receive touch events, false otherwise 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isTouchable() 7545435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTouchable(boolean touchable) { 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTouchable = touchable; 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicates whether the popup window will be informed of touch events 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * outside of its window.</p> 7645435a30ae552391f14009c4459731ae149675b18Alan Viverette * 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is outside touchable, false otherwise 7665435a30ae552391f14009c4459731ae149675b18Alan Viverette * 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setOutsideTouchable(boolean) 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isOutsideTouchable() { 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mOutsideTouchable; 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Controls whether the pop-up will be informed of touch events outside 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of its window. This only makes sense for pop-ups that are touchable 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * but not focusable, which means touches outside of the window will 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be delivered to the window behind. The default is false.</p> 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param touchable true if the popup should receive outside 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * touch events, false otherwise 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isOutsideTouchable() 7875435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setOutsideTouchable(boolean touchable) { 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOutsideTouchable = touchable; 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicates whether clipping of the popup window is enabled.</p> 7965435a30ae552391f14009c4459731ae149675b18Alan Viverette * 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the clipping is enabled, false otherwise 7985435a30ae552391f14009c4459731ae149675b18Alan Viverette * 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setClippingEnabled(boolean) 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isClippingEnabled() { 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mClippingEnabled; 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Allows the popup window to extend beyond the bounds of the screen. By default the 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window is clipped to the screen boundaries. Setting this to false will allow windows to be 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * accurately positioned.</p> 8095435a30ae552391f14009c4459731ae149675b18Alan Viverette * 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param enabled false if the window should be allowed to extend outside of the screen 8155435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isClippingEnabled() 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setClippingEnabled(boolean enabled) { 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mClippingEnabled = enabled; 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 82456c2d337e02a275397fc9d0460dca90977f199acAdam Powell * Clip this popup window to the screen, but not to the containing window. 82556c2d337e02a275397fc9d0460dca90977f199acAdam Powell * 82656c2d337e02a275397fc9d0460dca90977f199acAdam Powell * @param enabled True to clip to the screen. 82756c2d337e02a275397fc9d0460dca90977f199acAdam Powell * @hide 82856c2d337e02a275397fc9d0460dca90977f199acAdam Powell */ 82956c2d337e02a275397fc9d0460dca90977f199acAdam Powell public void setClipToScreenEnabled(boolean enabled) { 83056c2d337e02a275397fc9d0460dca90977f199acAdam Powell mClipToScreen = enabled; 83156c2d337e02a275397fc9d0460dca90977f199acAdam Powell setClippingEnabled(!enabled); 83256c2d337e02a275397fc9d0460dca90977f199acAdam Powell } 833348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell 834348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell /** 835348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * Allow PopupWindow to scroll the anchor's parent to provide more room 836348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * for the popup. Enabled by default. 837348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * 838348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * @param enabled True to scroll the anchor's parent when more room is desired by the popup. 839348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell */ 840348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell void setAllowScrollingAnchorParent(boolean enabled) { 841348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell mAllowScrollingAnchorParent = enabled; 842348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell } 8435435a30ae552391f14009c4459731ae149675b18Alan Viverette 84456c2d337e02a275397fc9d0460dca90977f199acAdam Powell /** 84501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * <p>Indicates whether the popup window supports splitting touches.</p> 8465435a30ae552391f14009c4459731ae149675b18Alan Viverette * 84701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * @return true if the touch splitting is enabled, false otherwise 8485435a30ae552391f14009c4459731ae149675b18Alan Viverette * 84901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * @see #setSplitTouchEnabled(boolean) 85001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown */ 85101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown public boolean isSplitTouchEnabled() { 85246e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown if (mSplitTouchEnabled < 0 && mContext != null) { 85346e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown return mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB; 85446e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown } 85546e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown return mSplitTouchEnabled == 1; 85601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown } 85701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown 85801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown /** 85901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * <p>Allows the popup window to split touches across other windows that also 86046e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown * support split touch. When this flag is false, the first pointer 86101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * that goes down determines the window to which all subsequent touches 86246e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown * go until all pointers go up. When this flag is true, each pointer 86301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * (not necessarily the first) that goes down determines the window 86401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * to which all subsequent touches of that pointer will go until that 86501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * pointer goes up thereby enabling touches with multiple pointers 86601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * to be split across multiple windows.</p> 86701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * 86801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * @param enabled true if the split touches should be enabled, false otherwise 86901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * @see #isSplitTouchEnabled() 87001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown */ 87101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown public void setSplitTouchEnabled(boolean enabled) { 87246e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown mSplitTouchEnabled = enabled ? 1 : 0; 87301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown } 87401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown 87501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown /** 876ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * <p>Indicates whether the popup window will be forced into using absolute screen coordinates 877ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * for positioning.</p> 878ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * 879ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * @return true if the window will always be positioned in screen coordinates. 880ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * @hide 881ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell */ 882ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell public boolean isLayoutInScreenEnabled() { 883ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell return mLayoutInScreen; 884ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell } 885ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell 886ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell /** 887ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * <p>Allows the popup window to force the flag 888ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * {@link WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN}, overriding default behavior. 889ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * This will cause the popup to be positioned in absolute screen coordinates.</p> 890ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * 891ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * @param enabled true if the popup should always be positioned in screen coordinates 892ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * @hide 893ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell */ 894ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell public void setLayoutInScreenEnabled(boolean enabled) { 895ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell mLayoutInScreen = enabled; 896ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell } 897ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell 898ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell /** 899393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * <p>Indicates whether the popup window will be attached in the decor frame of its parent 900393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * window. 901393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 902393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @return true if the window will be attached to the decor frame of its parent window. 903393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 904393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @see #setAttachedInDecor(boolean) 905393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR 906393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale */ 907393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale public boolean isAttachedInDecor() { 908393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale return mAttachedInDecor; 909393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale } 910393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 911393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale /** 912393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * <p>This will attach the popup window to the decor frame of the parent window to avoid 913393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * overlaping with screen decorations like the navigation bar. Overrides the default behavior of 914393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * the flag {@link WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR}. 915393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 916393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * <p>By default the flag is set on SDK version {@link Build.VERSION_CODES#LOLLIPOP_MR1} or 917393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * greater and cleared on lesser SDK versions. 918393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 919393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @param enabled true if the popup should be attached to the decor frame of its parent window. 920393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 921393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR 922393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale */ 923393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale public void setAttachedInDecor(boolean enabled) { 924393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale mAttachedInDecor = enabled; 925393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale mAttachedInDecorSet = true; 926393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale } 927393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 928393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale /** 9290bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * Allows the popup window to force the flag 9300bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * {@link WindowManager.LayoutParams#FLAG_LAYOUT_INSET_DECOR}, overriding default behavior. 9310bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * This will cause the popup to inset its content to account for system windows overlaying 9320bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * the screen, such as the status bar. 9330bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * 9340bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * <p>This will often be combined with {@link #setLayoutInScreenEnabled(boolean)}. 9350bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * 9360bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * @param enabled true if the popup's views should inset content to account for system windows, 9370bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * the way that decor views behave for full-screen windows. 9380bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * @hide 9390bd1d0a15294345bf88b20df28466907f982cec7Adam Powell */ 9400bd1d0a15294345bf88b20df28466907f982cec7Adam Powell public void setLayoutInsetDecor(boolean enabled) { 9410bd1d0a15294345bf88b20df28466907f982cec7Adam Powell mLayoutInsetDecor = enabled; 9420bd1d0a15294345bf88b20df28466907f982cec7Adam Powell } 9430bd1d0a15294345bf88b20df28466907f982cec7Adam Powell 9440bd1d0a15294345bf88b20df28466907f982cec7Adam Powell /** 94580ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette * Set the layout type for this window. 94680ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette * <p> 94780ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette * See {@link WindowManager.LayoutParams#type} for possible values. 948574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell * 949574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell * @param layoutType Layout type for this window. 95036344a90c226c90243e4e02bfb13589e120431ddChris Banes * 95136344a90c226c90243e4e02bfb13589e120431ddChris Banes * @see WindowManager.LayoutParams#type 952574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell */ 953574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell public void setWindowLayoutType(int layoutType) { 954574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell mWindowLayoutType = layoutType; 955574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell } 956574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell 957574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell /** 95836344a90c226c90243e4e02bfb13589e120431ddChris Banes * Returns the layout type for this window. 95936344a90c226c90243e4e02bfb13589e120431ddChris Banes * 96036344a90c226c90243e4e02bfb13589e120431ddChris Banes * @see #setWindowLayoutType(int) 961574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell */ 962574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell public int getWindowLayoutType() { 963574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell return mWindowLayoutType; 964574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell } 965574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell 966574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell /** 967e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell * Set whether this window is touch modal or if outside touches will be sent to 968e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell * other windows behind it. 969e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell * @hide 970e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell */ 971e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell public void setTouchModal(boolean touchModal) { 972e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell mNotTouchModal = !touchModal; 973e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell } 974e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell 975e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell /** 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Change the width and height measure specs that are given to the 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window manager by the popup. By default these are 0, meaning that 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the current width or height is requested as an explicit size from 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the window manager. You can supply 9805435a30ae552391f14009c4459731ae149675b18Alan Viverette * {@link ViewGroup.LayoutParams#WRAP_CONTENT} or 981980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * {@link ViewGroup.LayoutParams#MATCH_PARENT} to have that measure 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * spec supplied instead, replacing the absolute width and height that 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * has been set in the popup.</p> 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown.</p> 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param widthSpec an explicit width measure spec mode, either 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link ViewGroup.LayoutParams#WRAP_CONTENT}, 990980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * {@link ViewGroup.LayoutParams#MATCH_PARENT}, or 0 to use the absolute 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * width. 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param heightSpec an explicit height measure spec mode, either 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link ViewGroup.LayoutParams#WRAP_CONTENT}, 994980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * {@link ViewGroup.LayoutParams#MATCH_PARENT}, or 0 to use the absolute 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * height. 996259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * 997259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @deprecated Use {@link #setWidth(int)} and {@link #setHeight(int)}. 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 999259c2840691a79634ffd8f63291ec21c21819542Alan Viverette @Deprecated 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setWindowLayoutMode(int widthSpec, int heightSpec) { 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWidthMode = widthSpec; 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeightMode = heightSpec; 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10045435a30ae552391f14009c4459731ae149675b18Alan Viverette 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1006259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Returns the popup's height MeasureSpec. 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the height MeasureSpec of the popup 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setHeight(int) 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getHeight() { 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mHeight; 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1016259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Sets the popup's height MeasureSpec. 1017259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1018259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * If the popup is showing, calling this method will take effect the next 1019259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * time the popup is shown. 10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param height the height MeasureSpec of the popup 10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getHeight() 10235435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setHeight(int height) { 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeight = height; 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1030259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Returns the popup's width MeasureSpec. 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the width MeasureSpec of the popup 10335435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #setWidth(int) 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getWidth() { 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mWidth; 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1040259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Sets the popup's width MeasureSpec. 1041259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1042259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * If the popup is showing, calling this method will take effect the next 1043259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * time the popup is shown. 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param width the width MeasureSpec of the popup 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getWidth() 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isShowing() 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setWidth(int width) { 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWidth = width; 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 105475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Sets whether the popup window should overlap its anchor view when 105575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * displayed as a drop-down. 105675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * <p> 105775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If the popup is showing, calling this method will take effect only 105875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * the next time the popup is shown. 105975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * 106075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @param overlapAnchor Whether the popup should overlap its anchor. 106175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * 106275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @see #getOverlapAnchor() 106375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @see #isShowing() 106475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette */ 106575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette public void setOverlapAnchor(boolean overlapAnchor) { 106675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette mOverlapAnchor = overlapAnchor; 106775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette } 106875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette 106975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette /** 107075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Returns whether the popup window should overlap its anchor view when 107175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * displayed as a drop-down. 107275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * 107375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @return Whether the popup should overlap its anchor. 107475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * 107575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @see #setOverlapAnchor(boolean) 107675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette */ 107775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette public boolean getOverlapAnchor() { 107875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette return mOverlapAnchor; 107975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette } 108075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette 108175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette /** 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicate whether this popup window is showing on screen.</p> 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is showing, false otherwise 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isShowing() { 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mIsShowing; 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Display the content view in a popup window at the specified location. If the popup window 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cannot fit on screen, it will be clipped. See {@link android.view.WindowManager.LayoutParams} 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for more information on how gravity and the x and y parameters are related. Specifying 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a gravity of {@link android.view.Gravity#NO_GRAVITY} is similar to specifying 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>Gravity.LEFT | Gravity.TOP</code>. 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p> 10985435a30ae552391f14009c4459731ae149675b18Alan Viverette * 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param parent a parent view to get the {@link android.view.View#getWindowToken()} token from 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param gravity the gravity which controls the placement of the popup window 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x the popup's x location offset 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y the popup's y location offset 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void showAtLocation(View parent, int gravity, int x, int y) { 11058ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell showAtLocation(parent.getWindowToken(), gravity, x, y); 11068ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell } 11078ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell 11088ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell /** 11098ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * Display the content view in a popup window at the specified location. 11108ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * 11118ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @param token Window token to use for creating the new window 11128ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @param gravity the gravity which controls the placement of the popup window 11138ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @param x the popup's x location offset 11148ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @param y the popup's y location offset 11158ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * 11168ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @hide Internal use only. Applications should use 11178ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * {@link #showAtLocation(View, int, int, int)} instead. 11188ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell */ 11198ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell public void showAtLocation(IBinder token, int gravity, int x, int y) { 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isShowing() || mContentView == null) { 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1124e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette TransitionManager.endTransitions(mDecorView); 1125e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1126634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette unregisterForViewTreeChanges(); 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsShowing = true; 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsDropdown = false; 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1131e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final WindowManager.LayoutParams p = createPopupLayoutParams(token); 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project preparePopup(p); 1133e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1134e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // Only override the default if some gravity was specified. 1135e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette if (gravity != Gravity.NO_GRAVITY) { 1136e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.gravity = gravity; 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1138e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.x = x; 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.y = y; 1141e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokePopup(p); 11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 114675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Display the content view in a popup window anchored to the bottom-left 11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * corner of the anchor view. If there is not enough room on screen to show 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the popup in its entirety, this method tries to find a parent scroll 114975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * view to scroll. If no parent scroll view can be scrolled, the 115075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * bottom-left corner of the popup is pinned at the top left corner of the 115175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * anchor view. 11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the view on which to pin the popup window 11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #dismiss() 11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void showAsDropDown(View anchor) { 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project showAsDropDown(anchor, 0, 0); 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 116275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Display the content view in a popup window anchored to the bottom-left 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * corner of the anchor view offset by the specified x and y coordinates. 116475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If there is not enough room on screen to show the popup in its entirety, 116575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * this method tries to find a parent scroll view to scroll. If no parent 116675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * scroll view can be scrolled, the bottom-left corner of the popup is 116775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * pinned at the top left corner of the anchor view. 116875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * <p> 116975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If the view later scrolls to move <code>anchor</code> to a different 117075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * location, the popup will be moved correspondingly. 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the view on which to pin the popup window 117354c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param xoff A horizontal offset from the anchor in pixels 117454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param yoff A vertical offset from the anchor in pixels 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #dismiss() 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void showAsDropDown(View anchor, int xoff, int yoff) { 117954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell showAsDropDown(anchor, xoff, yoff, DEFAULT_ANCHORED_GRAVITY); 118054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell } 118154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 118254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell /** 118375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Displays the content view in a popup window anchored to the corner of 118475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * another view. The window is positioned according to the specified 118575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * gravity and offset by the specified x and y coordinates. 118675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * <p> 118775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If there is not enough room on screen to show the popup in its entirety, 118875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * this method tries to find a parent scroll view to scroll. If no parent 118975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * view can be scrolled, the specified vertical gravity will be ignored and 119075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * the popup will anchor itself such that it is visible. 119175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * <p> 119275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If the view later scrolls to move <code>anchor</code> to a different 119375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * location, the popup will be moved correspondingly. 119454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * 119554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param anchor the view on which to pin the popup window 119654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param xoff A horizontal offset from the anchor in pixels 119754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param yoff A vertical offset from the anchor in pixels 119854c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param gravity Alignment of the popup relative to the anchor 119954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * 120054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @see #dismiss() 120154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell */ 120254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell public void showAsDropDown(View anchor, int xoff, int yoff, int gravity) { 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isShowing() || mContentView == null) { 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1207e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette TransitionManager.endTransitions(mDecorView); 1208e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1209634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette registerForViewTreeChanges(anchor, xoff, yoff, gravity); 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsShowing = true; 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsDropdown = true; 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1214e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final WindowManager.LayoutParams p = createPopupLayoutParams(anchor.getWindowToken()); 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project preparePopup(p); 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1217e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final boolean aboveAnchor = findDropDownPosition(anchor, p, xoff, yoff, gravity); 1218e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette updateAboveAnchor(aboveAnchor); 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokePopup(p); 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12233e141685003939a9addce21ba2492ea3a8aebee6Romain Guy private void updateAboveAnchor(boolean aboveAnchor) { 12243e141685003939a9addce21ba2492ea3a8aebee6Romain Guy if (aboveAnchor != mAboveAnchor) { 12253e141685003939a9addce21ba2492ea3a8aebee6Romain Guy mAboveAnchor = aboveAnchor; 12263e141685003939a9addce21ba2492ea3a8aebee6Romain Guy 1227697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette if (mBackground != null && mBackgroundView != null) { 1228697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette // If the background drawable provided was a StateListDrawable 1229697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette // with above-anchor and below-anchor states, use those. 1230697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette // Otherwise, rely on refreshDrawableState to do the job. 12313e141685003939a9addce21ba2492ea3a8aebee6Romain Guy if (mAboveAnchorBackgroundDrawable != null) { 12323e141685003939a9addce21ba2492ea3a8aebee6Romain Guy if (mAboveAnchor) { 1233697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView.setBackground(mAboveAnchorBackgroundDrawable); 12343e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } else { 1235697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView.setBackground(mBelowAnchorBackgroundDrawable); 12363e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 12373e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } else { 1238697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView.refreshDrawableState(); 12393e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 12403e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 12413e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 12423e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 12433e141685003939a9addce21ba2492ea3a8aebee6Romain Guy 12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Indicates whether the popup is showing above (the y coordinate of the popup's bottom 12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is less than the y coordinate of the anchor) or below the anchor view (the y coordinate 12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the popup is greater than y coordinate of the anchor's bottom). 12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The value returned 12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by this method is meaningful only after {@link #showAsDropDown(android.view.View)} 12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or {@link #showAsDropDown(android.view.View, int, int)} was invoked. 12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return True if this popup is showing above the anchor view, false otherwise. 12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isAboveAnchor() { 12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAboveAnchor; 12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1260e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette * Prepare the popup by embedding it into a new ViewGroup if the background 1261e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette * drawable is not null. If embedding is required, the layout parameters' 1262e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette * height is modified to take into account the background's padding. 12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param p the layout parameters of the popup's content view 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void preparePopup(WindowManager.LayoutParams p) { 1267448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy if (mContentView == null || mContext == null || mWindowManager == null) { 1268448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy throw new IllegalStateException("You must specify a valid content view by " 1269448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy + "calling setContentView() before attempting to show the popup."); 1270448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy } 1271448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy 12728fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // The old decor view may be transitioning out. Make sure it finishes 12738fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // and cleans up before we try to create another one. 12748fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (mDecorView != null) { 12758fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mDecorView.cancelTransitions(); 12768fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 12778fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 12785435a30ae552391f14009c4459731ae149675b18Alan Viverette // When a background is available, we embed the content view within 12795435a30ae552391f14009c4459731ae149675b18Alan Viverette // another view that owns the background drawable. 12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBackground != null) { 1281697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView = createBackgroundView(mContentView); 1282697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView.setBackground(mBackground); 12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1284697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView = mContentView; 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1286ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette 1287697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mDecorView = createDecorView(mBackgroundView); 12885435a30ae552391f14009c4459731ae149675b18Alan Viverette 12895435a30ae552391f14009c4459731ae149675b18Alan Viverette // The background owner should be elevated so that it casts a shadow. 1290697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView.setElevation(mElevation); 12915435a30ae552391f14009c4459731ae149675b18Alan Viverette 12925435a30ae552391f14009c4459731ae149675b18Alan Viverette // We may wrap that in another view, so we'll need to manually specify 12935435a30ae552391f14009c4459731ae149675b18Alan Viverette // the surface insets. 1294697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette final int surfaceInset = (int) Math.ceil(mBackgroundView.getZ() * 2); 12955435a30ae552391f14009c4459731ae149675b18Alan Viverette p.surfaceInsets.set(surfaceInset, surfaceInset, surfaceInset, surfaceInset); 12965435a30ae552391f14009c4459731ae149675b18Alan Viverette p.hasManualSurfaceInsets = true; 12975435a30ae552391f14009c4459731ae149675b18Alan Viverette 1298b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio mPopupViewInitialLayoutDirectionInherited = 12995435a30ae552391f14009c4459731ae149675b18Alan Viverette (mContentView.getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT); 13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPopupWidth = p.width; 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPopupHeight = p.height; 13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13055435a30ae552391f14009c4459731ae149675b18Alan Viverette * Wraps a content view in a PopupViewContainer. 13065435a30ae552391f14009c4459731ae149675b18Alan Viverette * 13075435a30ae552391f14009c4459731ae149675b18Alan Viverette * @param contentView the content view to wrap 13085435a30ae552391f14009c4459731ae149675b18Alan Viverette * @return a PopupViewContainer that wraps the content view 13095435a30ae552391f14009c4459731ae149675b18Alan Viverette */ 13105435a30ae552391f14009c4459731ae149675b18Alan Viverette private PopupBackgroundView createBackgroundView(View contentView) { 13115435a30ae552391f14009c4459731ae149675b18Alan Viverette final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams(); 13125435a30ae552391f14009c4459731ae149675b18Alan Viverette final int height; 13135435a30ae552391f14009c4459731ae149675b18Alan Viverette if (layoutParams != null && layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) { 13145435a30ae552391f14009c4459731ae149675b18Alan Viverette height = ViewGroup.LayoutParams.WRAP_CONTENT; 13155435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 13165435a30ae552391f14009c4459731ae149675b18Alan Viverette height = ViewGroup.LayoutParams.MATCH_PARENT; 13175435a30ae552391f14009c4459731ae149675b18Alan Viverette } 13185435a30ae552391f14009c4459731ae149675b18Alan Viverette 13195435a30ae552391f14009c4459731ae149675b18Alan Viverette final PopupBackgroundView backgroundView = new PopupBackgroundView(mContext); 13205435a30ae552391f14009c4459731ae149675b18Alan Viverette final PopupBackgroundView.LayoutParams listParams = new PopupBackgroundView.LayoutParams( 13215435a30ae552391f14009c4459731ae149675b18Alan Viverette ViewGroup.LayoutParams.MATCH_PARENT, height); 13225435a30ae552391f14009c4459731ae149675b18Alan Viverette backgroundView.addView(contentView, listParams); 13235435a30ae552391f14009c4459731ae149675b18Alan Viverette 13245435a30ae552391f14009c4459731ae149675b18Alan Viverette return backgroundView; 13255435a30ae552391f14009c4459731ae149675b18Alan Viverette } 13265435a30ae552391f14009c4459731ae149675b18Alan Viverette 13275435a30ae552391f14009c4459731ae149675b18Alan Viverette /** 13285435a30ae552391f14009c4459731ae149675b18Alan Viverette * Wraps a content view in a FrameLayout. 13295435a30ae552391f14009c4459731ae149675b18Alan Viverette * 13305435a30ae552391f14009c4459731ae149675b18Alan Viverette * @param contentView the content view to wrap 13315435a30ae552391f14009c4459731ae149675b18Alan Viverette * @return a FrameLayout that wraps the content view 13325435a30ae552391f14009c4459731ae149675b18Alan Viverette */ 13335435a30ae552391f14009c4459731ae149675b18Alan Viverette private PopupDecorView createDecorView(View contentView) { 13345435a30ae552391f14009c4459731ae149675b18Alan Viverette final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams(); 13355435a30ae552391f14009c4459731ae149675b18Alan Viverette final int height; 13365435a30ae552391f14009c4459731ae149675b18Alan Viverette if (layoutParams != null && layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) { 13375435a30ae552391f14009c4459731ae149675b18Alan Viverette height = ViewGroup.LayoutParams.WRAP_CONTENT; 13385435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 13395435a30ae552391f14009c4459731ae149675b18Alan Viverette height = ViewGroup.LayoutParams.MATCH_PARENT; 13405435a30ae552391f14009c4459731ae149675b18Alan Viverette } 13415435a30ae552391f14009c4459731ae149675b18Alan Viverette 13425435a30ae552391f14009c4459731ae149675b18Alan Viverette final PopupDecorView decorView = new PopupDecorView(mContext); 13435435a30ae552391f14009c4459731ae149675b18Alan Viverette decorView.addView(contentView, ViewGroup.LayoutParams.MATCH_PARENT, height); 13445435a30ae552391f14009c4459731ae149675b18Alan Viverette decorView.setClipChildren(false); 13455435a30ae552391f14009c4459731ae149675b18Alan Viverette decorView.setClipToPadding(false); 13465435a30ae552391f14009c4459731ae149675b18Alan Viverette 13475435a30ae552391f14009c4459731ae149675b18Alan Viverette return decorView; 13485435a30ae552391f14009c4459731ae149675b18Alan Viverette } 13495435a30ae552391f14009c4459731ae149675b18Alan Viverette 13505435a30ae552391f14009c4459731ae149675b18Alan Viverette /** 13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Invoke the popup window by adding the content view to the window 13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * manager.</p> 13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The content view must be non-null when this method is invoked.</p> 13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param p the layout parameters of the popup's content view 13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void invokePopup(WindowManager.LayoutParams p) { 13590c0b768e1514280812321854db6dfba723c3d169Romain Guy if (mContext != null) { 13600c0b768e1514280812321854db6dfba723c3d169Romain Guy p.packageName = mContext.getPackageName(); 13610c0b768e1514280812321854db6dfba723c3d169Romain Guy } 13625435a30ae552391f14009c4459731ae149675b18Alan Viverette 13638fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final PopupDecorView decorView = mDecorView; 13648fd949e680c15d397084430d4907c16cedfacddaAlan Viverette decorView.setFitsSystemWindows(mLayoutInsetDecor); 13655435a30ae552391f14009c4459731ae149675b18Alan Viverette 13668fd949e680c15d397084430d4907c16cedfacddaAlan Viverette setLayoutDirectionFromAnchor(); 13675435a30ae552391f14009c4459731ae149675b18Alan Viverette 13688fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mWindowManager.addView(decorView, p); 136995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 137095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette if (mEnterTransition != null) { 137195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette decorView.requestEnterTransition(mEnterTransition); 137295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette } 13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1375b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio private void setLayoutDirectionFromAnchor() { 1376b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio if (mAnchor != null) { 1377b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio View anchor = mAnchor.get(); 1378b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio if (anchor != null && mPopupViewInitialLayoutDirectionInherited) { 13795435a30ae552391f14009c4459731ae149675b18Alan Viverette mDecorView.setLayoutDirection(anchor.getLayoutDirection()); 1380b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio } 1381b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio } 1382b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio } 1383b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio 13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Generate the layout parameters for the popup window.</p> 13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param token the window token used to bind the popup's window 13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the layout parameters to pass to the window manager 13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1391e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette private WindowManager.LayoutParams createPopupLayoutParams(IBinder token) { 1392e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final WindowManager.LayoutParams p = new WindowManager.LayoutParams(); 1393e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1394e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // These gravity settings put the view at the top left corner of the 1395e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // screen. The view is then positioned to the appropriate location by 1396e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // setting the x and y offsets to match the anchor's bottom-left 1397e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // corner. 1398aac0d4ed026d1cfbcf3fa81c6e4eb96f4347ca17Fabrice Di Meglio p.gravity = Gravity.START | Gravity.TOP; 1399e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.flags = computeFlags(p.flags); 1400e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.type = mWindowLayoutType; 1401e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.token = token; 1402e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.softInputMode = mSoftInputMode; 1403e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.windowAnimations = computeAnimationResource(); 1404e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBackground != null) { 14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.format = mBackground.getOpacity(); 14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.format = PixelFormat.TRANSLUCENT; 14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1410e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1411e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette if (mHeightMode < 0) { 1412e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.height = mLastHeight = mHeightMode; 1413e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } else { 1414e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.height = mLastHeight = mHeight; 1415e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } 1416e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1417e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette if (mWidthMode < 0) { 1418e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.width = mLastWidth = mWidthMode; 1419e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } else { 1420e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.width = mLastWidth = mWidth; 1421e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } 1422e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 14238216eb2221ad5ad6615d3966f43844268756f3c8Wale Ogunwale p.privateFlags = PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH 14248216eb2221ad5ad6615d3966f43844268756f3c8Wale Ogunwale | PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME; 1425a1eb439eee65138280c560f96e2a6896f9c9112cRobert Carr 1426e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // Used for debugging. 14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.setTitle("PopupWindow:" + Integer.toHexString(hashCode())); 14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return p; 14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int computeFlags(int curFlags) { 14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags &= ~( 14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES | 14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | 14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | 14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | 14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | 1439ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM | 1440ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell WindowManager.LayoutParams.FLAG_SPLIT_TOUCH); 14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(mIgnoreCheekPress) { 14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES; 14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mFocusable) { 14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mInputMethodMode == INPUT_METHOD_NEEDED) { 14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mInputMethodMode == INPUT_METHOD_NOT_NEEDED) { 14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mTouchable) { 14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1455c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project if (mOutsideTouchable) { 14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH; 14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mClippingEnabled) { 14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; 14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 146146e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown if (isSplitTouchEnabled()) { 146201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown curFlags |= WindowManager.LayoutParams.FLAG_SPLIT_TOUCH; 146301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown } 1464ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell if (mLayoutInScreen) { 1465ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; 1466ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell } 14670bd1d0a15294345bf88b20df28466907f982cec7Adam Powell if (mLayoutInsetDecor) { 14680bd1d0a15294345bf88b20df28466907f982cec7Adam Powell curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; 14690bd1d0a15294345bf88b20df28466907f982cec7Adam Powell } 1470e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell if (mNotTouchModal) { 1471e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; 1472e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell } 1473393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale if (mAttachedInDecor) { 1474393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR; 1475393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale } 14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return curFlags; 14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1478393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int computeAnimationResource() { 14805435a30ae552391f14009c4459731ae149675b18Alan Viverette if (mAnimationStyle == ANIMATION_STYLE_DEFAULT) { 14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsDropdown) { 14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAboveAnchor 14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ? com.android.internal.R.style.Animation_DropDownUp 14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : com.android.internal.R.style.Animation_DropDownDown; 14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAnimationStyle; 14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1490560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1492560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * Positions the popup window on screen. When the popup window is too tall 1493560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * to fit under the anchor, a parent scroll view is seeked and scrolled up 1494560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * to reclaim space. If scrolling is not possible or not enough, the popup 1495560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * window gets moved on top of the anchor. 1496560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * <p> 1497560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * The height must have been set on the layout parameters prior to calling 1498560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * this method. 14995435a30ae552391f14009c4459731ae149675b18Alan Viverette * 15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the view on which the popup window must be anchored 15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param p the layout parameters used to display the drop down 1502560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * @param xoff horizontal offset used to adjust for background padding 1503560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * @param yoff vertical offset used to adjust for background padding 1504560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * @param gravity horizontal gravity specifying popup alignment 15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is translated upwards to fit on screen 15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1507560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette private boolean findDropDownPosition(View anchor, WindowManager.LayoutParams p, int xoff, 1508560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette int yoff, int gravity) { 150962e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell final int anchorHeight = anchor.getHeight(); 1510560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int anchorWidth = anchor.getWidth(); 1511560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette if (mOverlapAnchor) { 1512560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette yoff -= anchorHeight; 1513560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette } 1514560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anchor.getLocationInWindow(mDrawingLocation); 15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.x = mDrawingLocation[0] + xoff; 151762e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell p.y = mDrawingLocation[1] + anchorHeight + yoff; 151854c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 1519560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int hgrav = Gravity.getAbsoluteGravity(gravity, anchor.getLayoutDirection()) 1520560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette & Gravity.HORIZONTAL_GRAVITY_MASK; 152154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell if (hgrav == Gravity.RIGHT) { 1522560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // Flip the location to align the right sides of the popup and 1523560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // anchor instead of left. 1524560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette p.x -= mPopupWidth - anchorWidth; 152554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell } 1526560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean onTop = false; 15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 152954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell p.gravity = Gravity.LEFT | Gravity.TOP; 153054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anchor.getLocationOnScreen(mScreenLocation); 15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect displayFrame = new Rect(); 15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anchor.getWindowVisibleDisplayFrame(displayFrame); 153462e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell 1535560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int screenY = mScreenLocation[1] + anchorHeight + yoff; 15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View root = anchor.getRootView(); 1537560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette if (screenY + mPopupHeight > displayFrame.bottom 1538560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette || p.x + mPopupWidth - root.getWidth() > 0) { 1539560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // If the drop down disappears at the bottom of the screen, we try 1540560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // to scroll a parent scrollview or move the drop down back up on 1541560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // top of the edit box. 1542b7c1b20c8a5a4d4378ae91b4a1f12a34100df452Adam Powell if (mAllowScrollingAnchorParent) { 1543560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int scrollX = anchor.getScrollX(); 1544560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int scrollY = anchor.getScrollY(); 1545560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final Rect r = new Rect(scrollX, scrollY, scrollX + mPopupWidth + xoff, 1546560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette scrollY + mPopupHeight + anchorHeight + yoff); 1547b7c1b20c8a5a4d4378ae91b4a1f12a34100df452Adam Powell anchor.requestRectangleOnScreen(r, true); 1548b7c1b20c8a5a4d4378ae91b4a1f12a34100df452Adam Powell } 15493e141685003939a9addce21ba2492ea3a8aebee6Romain Guy 1550560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // Now we re-evaluate the space available, and decide from that 15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // whether the pop-up will go above or below the anchor. 15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anchor.getLocationInWindow(mDrawingLocation); 15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.x = mDrawingLocation[0] + xoff; 1554560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette p.y = mDrawingLocation[1] + anchorHeight + yoff; 155554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 1556560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // Preserve the gravity adjustment. 155754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell if (hgrav == Gravity.RIGHT) { 1558560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette p.x -= mPopupWidth - anchorWidth; 155954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell } 1560560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 1561560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // Determine whether there is more space above or below the anchor. 15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anchor.getLocationOnScreen(mScreenLocation); 1563560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette onTop = (displayFrame.bottom - mScreenLocation[1] - anchorHeight - yoff) < 15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (mScreenLocation[1] - yoff - displayFrame.top); 1565ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg if (!mOverlapAnchor) { 1566ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg if (onTop) { 1567ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg p.gravity = Gravity.LEFT | Gravity.BOTTOM; 1568ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg p.y = root.getHeight() - mDrawingLocation[1] + yoff; 1569ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg } else { 1570ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg p.y = mDrawingLocation[1] + anchorHeight + yoff; 1571ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg } 15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 157556c2d337e02a275397fc9d0460dca90977f199acAdam Powell if (mClipToScreen) { 15767c9732db0e450785f70d634fee4037b5e887d911Chong Zhang final int winOffsetX = mScreenLocation[0] - mDrawingLocation[0]; 15777c9732db0e450785f70d634fee4037b5e887d911Chong Zhang final int winOffsetY = mScreenLocation[1] - mDrawingLocation[1]; 15787c9732db0e450785f70d634fee4037b5e887d911Chong Zhang p.x += winOffsetX; 15797c9732db0e450785f70d634fee4037b5e887d911Chong Zhang p.y += winOffsetY; 158056c2d337e02a275397fc9d0460dca90977f199acAdam Powell final int displayFrameWidth = displayFrame.right - displayFrame.left; 1581560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int right = p.x + p.width; 15827c9732db0e450785f70d634fee4037b5e887d911Chong Zhang if (right > displayFrame.right) { 15837c9732db0e450785f70d634fee4037b5e887d911Chong Zhang p.x -= right - displayFrame.right; 158456c2d337e02a275397fc9d0460dca90977f199acAdam Powell } 1585560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 158656c2d337e02a275397fc9d0460dca90977f199acAdam Powell if (p.x < displayFrame.left) { 158756c2d337e02a275397fc9d0460dca90977f199acAdam Powell p.x = displayFrame.left; 158856c2d337e02a275397fc9d0460dca90977f199acAdam Powell p.width = Math.min(p.width, displayFrameWidth); 158956c2d337e02a275397fc9d0460dca90977f199acAdam Powell } 159056c2d337e02a275397fc9d0460dca90977f199acAdam Powell 1591ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg if (mOverlapAnchor) { 1592ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg final int bottom = p.y + p.height; 1593ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg if (bottom > displayFrame.bottom) { 15947c9732db0e450785f70d634fee4037b5e887d911Chong Zhang p.y -= bottom - displayFrame.bottom; 15955f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell } 15965f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell } else { 1597ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg if (onTop) { 1598ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg final int popupTop = mScreenLocation[1] + yoff - mPopupHeight; 1599ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg if (popupTop < 0) { 1600ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg p.y += popupTop; 1601ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg } 1602ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg } else { 1603ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg p.y = Math.max(p.y, displayFrame.top); 1604ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg } 16055f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell } 16067c9732db0e450785f70d634fee4037b5e887d911Chong Zhang p.x -= winOffsetX; 16077c9732db0e450785f70d634fee4037b5e887d911Chong Zhang p.y -= winOffsetY; 160856c2d337e02a275397fc9d0460dca90977f199acAdam Powell } 160956c2d337e02a275397fc9d0460dca90977f199acAdam Powell 16109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.gravity |= Gravity.DISPLAY_CLIP_VERTICAL; 1611560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return onTop; 16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16145435a30ae552391f14009c4459731ae149675b18Alan Viverette 16159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 16169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the maximum height that is available for the popup to be 16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * completely shown. It is recommended that this height be the maximum for 16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the popup's height, otherwise it is possible that the popup will be 16199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clipped. 16205435a30ae552391f14009c4459731ae149675b18Alan Viverette * 16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor The view on which the popup window must be anchored. 16229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The maximum available height for the popup to be completely 16239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * shown. 16249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1625b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette public int getMaxAvailableHeight(@NonNull View anchor) { 16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return getMaxAvailableHeight(anchor, 0); 16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the maximum height that is available for the popup to be 16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * completely shown. It is recommended that this height be the maximum for 16329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the popup's height, otherwise it is possible that the popup will be 16339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clipped. 16349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 16359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor The view on which the popup window must be anchored. 16369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param yOffset y offset from the view's bottom edge 16379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The maximum available height for the popup to be completely 16389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * shown. 16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1640b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette public int getMaxAvailableHeight(@NonNull View anchor, int yOffset) { 164198acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau return getMaxAvailableHeight(anchor, yOffset, false); 164298acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau } 16435435a30ae552391f14009c4459731ae149675b18Alan Viverette 164498acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau /** 164598acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * Returns the maximum height that is available for the popup to be 164698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * completely shown, optionally ignoring any bottom decorations such as 164798acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * the input method. It is recommended that this height be the maximum for 164898acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * the popup's height, otherwise it is possible that the popup will be 164998acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * clipped. 16505435a30ae552391f14009c4459731ae149675b18Alan Viverette * 165198acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @param anchor The view on which the popup window must be anchored. 165298acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @param yOffset y offset from the view's bottom edge 165398acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @param ignoreBottomDecorations if true, the height returned will be 165498acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * all the way to the bottom of the display, ignoring any 165598acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * bottom decorations 165698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @return The maximum available height for the popup to be completely 165798acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * shown. 165898acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau */ 1659b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette public int getMaxAvailableHeight( 1660b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette @NonNull View anchor, int yOffset, boolean ignoreBottomDecorations) { 16619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect displayFrame = new Rect(); 16628175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi if (ignoreBottomDecorations) { 16638175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi anchor.getWindowDisplayFrame(displayFrame); 16648175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi } else { 16658175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi anchor.getWindowVisibleDisplayFrame(displayFrame); 16668175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi } 16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int[] anchorPos = mDrawingLocation; 16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anchor.getLocationOnScreen(anchorPos); 16705435a30ae552391f14009c4459731ae149675b18Alan Viverette 16718175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi final int bottomEdge = displayFrame.bottom; 1672ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg 1673ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg final int distanceToBottom; 1674ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg if (mOverlapAnchor) { 1675ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg distanceToBottom = bottomEdge - anchorPos[1] - yOffset; 1676ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg } else { 1677ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset; 1678ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg } 16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset; 16809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // anchorPos[1] is distance from anchor to top of screen 16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int returnedHeight = Math.max(distanceToBottom, distanceToTop); 16839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBackground != null) { 16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBackground.getPadding(mTempRect); 16855435a30ae552391f14009c4459731ae149675b18Alan Viverette returnedHeight -= mTempRect.top + mTempRect.bottom; 16869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16875435a30ae552391f14009c4459731ae149675b18Alan Viverette 16889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return returnedHeight; 16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16905435a30ae552391f14009c4459731ae149675b18Alan Viverette 16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 16927878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette * Disposes of the popup window. This method can be invoked only after 16937878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette * {@link #showAsDropDown(android.view.View)} has been executed. Failing 16947878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette * that, calling this method will have no effect. 16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 16965435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #showAsDropDown(android.view.View) 16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dismiss() { 16998fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (!isShowing() || mIsTransitioningToDismiss) { 1700e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette return; 1701e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } 170206f938e8aa56cd89ab0bdb04c8b946392c428dd1Svetoslav Ganov 17038fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final PopupDecorView decorView = mDecorView; 17048fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View contentView = mContentView; 17058fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 17068fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewGroup contentHolder; 17078fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewParent contentParent = contentView.getParent(); 17088fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (contentParent instanceof ViewGroup) { 17098fd949e680c15d397084430d4907c16cedfacddaAlan Viverette contentHolder = ((ViewGroup) contentParent); 17108fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } else { 17118fd949e680c15d397084430d4907c16cedfacddaAlan Viverette contentHolder = null; 17128fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 17138fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 17148fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // Ensure any ongoing or pending transitions are canceled. 17158fd949e680c15d397084430d4907c16cedfacddaAlan Viverette decorView.cancelTransitions(); 17168fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 1717e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette mIsShowing = false; 17188fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mIsTransitioningToDismiss = true; 1719b82d074038f4c8d86e1bd4f3fa4d3780bd4bcba5Craig Mautner 1720634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // This method may be called as part of window detachment, in which 1721634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // case the anchor view (and its root) will still return true from 1722634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // isAttachedToWindow() during execution of this method; however, we 1723634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // can expect the OnAttachStateChangeListener to have been called prior 1724634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // to executing this method, so we can rely on that instead. 172595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final Transition exitTransition = mExitTransition; 172621d361806c9e2dce5bae5b30f44be5ad87f32c22Alan Viverette if (mIsAnchorRootAttached && exitTransition != null && decorView.isLaidOut()) { 1727dbd299de2a07a2a0a490d4f37cf92870bf87d6c1Yohei Yukawa // The decor view is non-interactive and non-IME-focusable during exit transitions. 172895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final LayoutParams p = (LayoutParams) decorView.getLayoutParams(); 172995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette p.flags |= LayoutParams.FLAG_NOT_TOUCHABLE; 173095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette p.flags |= LayoutParams.FLAG_NOT_FOCUSABLE; 1731dbd299de2a07a2a0a490d4f37cf92870bf87d6c1Yohei Yukawa p.flags &= ~LayoutParams.FLAG_ALT_FOCUSABLE_IM; 173295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette mWindowManager.updateViewLayout(decorView, p); 173395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 1734634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // Once we start dismissing the decor view, all state (including 1735634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // the anchor root) needs to be moved to the decor view since we 1736634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // may open another popup while it's busy exiting. 1737634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette final View anchorRoot = mAnchorRoot != null ? mAnchorRoot.get() : null; 173891098574f90277128415e9593cce1e495cc51465Alan Viverette final Rect epicenter = getTransitionEpicenter(); 173995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette exitTransition.setEpicenterCallback(new EpicenterCallback() { 174095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette @Override 174195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette public Rect onGetEpicenter(Transition transition) { 174295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette return epicenter; 174395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette } 174495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette }); 1745634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette decorView.startExitTransition(exitTransition, anchorRoot, 1746634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette new TransitionListenerAdapter() { 1747634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette @Override 1748634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette public void onTransitionEnd(Transition transition) { 17497970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette dismissImmediate(decorView, contentHolder, contentView); 1750634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette } 1751634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette }); 1752e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } else { 17537970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette dismissImmediate(decorView, contentHolder, contentView); 17547878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette } 17557878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette 175695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette // Clears the anchor view. 1757634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette unregisterForViewTreeChanges(); 17587970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette 17597970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette if (mOnDismissListener != null) { 17607970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette mOnDismissListener.onDismiss(); 17617970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette } 17625435a30ae552391f14009c4459731ae149675b18Alan Viverette } 17635435a30ae552391f14009c4459731ae149675b18Alan Viverette 176491098574f90277128415e9593cce1e495cc51465Alan Viverette /** 176591098574f90277128415e9593cce1e495cc51465Alan Viverette * Returns the window-relative epicenter bounds to be used by enter and 176691098574f90277128415e9593cce1e495cc51465Alan Viverette * exit transitions. 176791098574f90277128415e9593cce1e495cc51465Alan Viverette * <p> 176891098574f90277128415e9593cce1e495cc51465Alan Viverette * <strong>Note:</strong> This is distinct from the rect passed to 176991098574f90277128415e9593cce1e495cc51465Alan Viverette * {@link #setEpicenterBounds(Rect)}, which is anchor-relative. 177091098574f90277128415e9593cce1e495cc51465Alan Viverette * 177191098574f90277128415e9593cce1e495cc51465Alan Viverette * @return the window-relative epicenter bounds to be used by enter and 177291098574f90277128415e9593cce1e495cc51465Alan Viverette * exit transitions 177391098574f90277128415e9593cce1e495cc51465Alan Viverette */ 177491098574f90277128415e9593cce1e495cc51465Alan Viverette private Rect getTransitionEpicenter() { 177595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final View anchor = mAnchor != null ? mAnchor.get() : null; 177695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final View decor = mDecorView; 177795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette if (anchor == null || decor == null) { 177895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette return null; 177995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette } 178095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 178195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final int[] anchorLocation = anchor.getLocationOnScreen(); 178295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final int[] popupLocation = mDecorView.getLocationOnScreen(); 178395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 178495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette // Compute the position of the anchor relative to the popup. 178595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final Rect bounds = new Rect(0, 0, anchor.getWidth(), anchor.getHeight()); 178695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette bounds.offset(anchorLocation[0] - popupLocation[0], anchorLocation[1] - popupLocation[1]); 178791098574f90277128415e9593cce1e495cc51465Alan Viverette 178891098574f90277128415e9593cce1e495cc51465Alan Viverette // Use anchor-relative epicenter, if specified. 178991098574f90277128415e9593cce1e495cc51465Alan Viverette if (mEpicenterBounds != null) { 179091098574f90277128415e9593cce1e495cc51465Alan Viverette final int offsetX = bounds.left; 179191098574f90277128415e9593cce1e495cc51465Alan Viverette final int offsetY = bounds.top; 179291098574f90277128415e9593cce1e495cc51465Alan Viverette bounds.set(mEpicenterBounds); 179391098574f90277128415e9593cce1e495cc51465Alan Viverette bounds.offset(offsetX, offsetY); 179491098574f90277128415e9593cce1e495cc51465Alan Viverette } 179591098574f90277128415e9593cce1e495cc51465Alan Viverette 179695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette return bounds; 179795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette } 179895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 17995435a30ae552391f14009c4459731ae149675b18Alan Viverette /** 18005435a30ae552391f14009c4459731ae149675b18Alan Viverette * Removes the popup from the window manager and tears down the supporting 18015435a30ae552391f14009c4459731ae149675b18Alan Viverette * view hierarchy, if necessary. 18025435a30ae552391f14009c4459731ae149675b18Alan Viverette */ 18037970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette private void dismissImmediate(View decorView, ViewGroup contentHolder, View contentView) { 18048fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // If this method gets called and the decor view doesn't have a parent, 18058fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // then it was either never added or was already removed. That should 18068fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // never happen, but it's worth checking to avoid potential crashes. 18078fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (decorView.getParent() != null) { 18088fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mWindowManager.removeViewImmediate(decorView); 1809df4639a0135ea643b493067b3f7cd1e092346c78Alan Viverette } 1810df4639a0135ea643b493067b3f7cd1e092346c78Alan Viverette 18118fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (contentHolder != null) { 18128fd949e680c15d397084430d4907c16cedfacddaAlan Viverette contentHolder.removeView(contentView); 18139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18148fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 18158fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // This needs to stay until after all transitions have ended since we 18168fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // need the reference to cancel transitions in preparePopup(). 18178fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mDecorView = null; 1818697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView = null; 18198fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mIsTransitioningToDismiss = false; 18209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the listener to be called when the window is dismissed. 18245435a30ae552391f14009c4459731ae149675b18Alan Viverette * 18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param onDismissListener The listener. 18269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 18279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setOnDismissListener(OnDismissListener onDismissListener) { 18289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnDismissListener = onDismissListener; 18299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18305435a30ae552391f14009c4459731ae149675b18Alan Viverette 18319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 18329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Updates the state of the popup window, if it is currently being displayed, 1833259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * from the currently set state. 1834259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1835259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * This includes: 1836259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <ul> 1837259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setClippingEnabled(boolean)}</li> 1838259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setFocusable(boolean)}</li> 1839259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setIgnoreCheekPress()}</li> 1840259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setInputMethodMode(int)}</li> 1841259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setTouchable(boolean)}</li> 1842259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setAnimationStyle(int)}</li> 1843259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * </ul> 18449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 18459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update() { 18469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isShowing() || mContentView == null) { 18479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 18489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18495435a30ae552391f14009c4459731ae149675b18Alan Viverette 18505435a30ae552391f14009c4459731ae149675b18Alan Viverette final WindowManager.LayoutParams p = 18515435a30ae552391f14009c4459731ae149675b18Alan Viverette (WindowManager.LayoutParams) mDecorView.getLayoutParams(); 18525435a30ae552391f14009c4459731ae149675b18Alan Viverette 18539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean update = false; 18545435a30ae552391f14009c4459731ae149675b18Alan Viverette 18559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newAnim = computeAnimationResource(); 18569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newAnim != p.windowAnimations) { 18579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.windowAnimations = newAnim; 18589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 18599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newFlags = computeFlags(p.flags); 18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newFlags != p.flags) { 18639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.flags = newFlags; 18649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 18659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1866b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio 18679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (update) { 1868b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio setLayoutDirectionFromAnchor(); 18695435a30ae552391f14009c4459731ae149675b18Alan Viverette mWindowManager.updateViewLayout(mDecorView, p); 18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1872d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy 1873d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy /** 1874259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the dimension of the popup window. 1875259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1876259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Calling this function also updates the window with the current popup 1877259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * state as described for {@link #update()}. 1878d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy * 1879259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param width the new width, must be >= 0 or -1 to ignore 1880259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param height the new height, must be >= 0 or -1 to ignore 1881d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy */ 1882d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy public void update(int width, int height) { 18835435a30ae552391f14009c4459731ae149675b18Alan Viverette final WindowManager.LayoutParams p = 18845435a30ae552391f14009c4459731ae149675b18Alan Viverette (WindowManager.LayoutParams) mDecorView.getLayoutParams(); 1885d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy update(p.x, p.y, width, height, false); 1886d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy } 18875435a30ae552391f14009c4459731ae149675b18Alan Viverette 18889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1889259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 1890259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1891259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Width and height can be set to -1 to update location only. Calling this 1892259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * function also updates the window with the current popup state as 1893259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * described for {@link #update()}. 18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x the new x location 18969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y the new y location 1897259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param width the new width, must be >= 0 or -1 to ignore 1898259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param height the new height, must be >= 0 or -1 to ignore 18999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 19009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(int x, int y, int width, int height) { 19019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update(x, y, width, height, false); 19029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1905259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 1906259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1907259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Width and height can be set to -1 to update location only. Calling this 1908259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * function also updates the window with the current popup state as 1909259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * described for {@link #update()}. 19109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 19119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x the new x location 19129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y the new y location 1913259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param width the new width, must be >= 0 or -1 to ignore 1914259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param height the new height, must be >= 0 or -1 to ignore 1915259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param force {@code true} to reposition the window even if the specified 1916259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * position already seems to correspond to the LayoutParams, 1917259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * {@code false} to only reposition if needed 19189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 19199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(int x, int y, int width, int height, boolean force) { 1920259c2840691a79634ffd8f63291ec21c21819542Alan Viverette if (width >= 0) { 19219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastWidth = width; 19229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setWidth(width); 19239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1925259c2840691a79634ffd8f63291ec21c21819542Alan Viverette if (height >= 0) { 19269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastHeight = height; 19279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setHeight(height); 19289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isShowing() || mContentView == null) { 19319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 19329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19345435a30ae552391f14009c4459731ae149675b18Alan Viverette final WindowManager.LayoutParams p = 19355435a30ae552391f14009c4459731ae149675b18Alan Viverette (WindowManager.LayoutParams) mDecorView.getLayoutParams(); 19369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean update = force; 19389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int finalWidth = mWidthMode < 0 ? mWidthMode : mLastWidth; 19409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (width != -1 && p.width != finalWidth) { 19419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.width = mLastWidth = finalWidth; 19429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 19439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int finalHeight = mHeightMode < 0 ? mHeightMode : mLastHeight; 19469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (height != -1 && p.height != finalHeight) { 19479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.height = mLastHeight = finalHeight; 19489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 19499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p.x != x) { 19529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.x = x; 19539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 19549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p.y != y) { 19579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.y = y; 19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 19599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newAnim = computeAnimationResource(); 19629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newAnim != p.windowAnimations) { 19639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.windowAnimations = newAnim; 19649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 19659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newFlags = computeFlags(p.flags); 19689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newFlags != p.flags) { 19699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.flags = newFlags; 19709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 19719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 197298acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau 19739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (update) { 1974b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio setLayoutDirectionFromAnchor(); 19755435a30ae552391f14009c4459731ae149675b18Alan Viverette mWindowManager.updateViewLayout(mDecorView, p); 19769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1980259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 1981259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1982259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Calling this function also updates the window with the current popup 1983259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * state as described for {@link #update()}. 19849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 19859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the popup's anchor view 1986259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param width the new width, must be >= 0 or -1 to ignore 1987259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param height the new height, must be >= 0 or -1 to ignore 19889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 19899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(View anchor, int width, int height) { 199075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette update(anchor, false, 0, 0, true, width, height); 19919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1994259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 1995259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1996259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Width and height can be set to -1 to update location only. Calling this 1997259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * function also updates the window with the current popup state as 1998259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * described for {@link #update()}. 1999259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 2000259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * If the view later scrolls to move {@code anchor} to a different 2001259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * location, the popup will be moved correspondingly. 20029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 20039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the popup's anchor view 20049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param xoff x offset from the view's left edge 20059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param yoff y offset from the view's bottom edge 2006259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param width the new width, must be >= 0 or -1 to ignore 2007259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param height the new height, must be >= 0 or -1 to ignore 20089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 20099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(View anchor, int xoff, int yoff, int width, int height) { 201075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette update(anchor, true, xoff, yoff, true, width, height); 2011105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 2012105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 2013105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private void update(View anchor, boolean updateLocation, int xoff, int yoff, 201475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette boolean updateDimension, int width, int height) { 2015105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 20169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isShowing() || mContentView == null) { 20179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 20189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 202075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette final WeakReference<View> oldAnchor = mAnchor; 202175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette final boolean needsUpdate = updateLocation && (mAnchorXoff != xoff || mAnchorYoff != yoff); 202281f08086b44a117097960195d2c9072e29644962Gilles Debunne if (oldAnchor == null || oldAnchor.get() != anchor || (needsUpdate && !mIsDropdown)) { 2023634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette registerForViewTreeChanges(anchor, xoff, yoff, mAnchoredGravity); 202481f08086b44a117097960195d2c9072e29644962Gilles Debunne } else if (needsUpdate) { 202581f08086b44a117097960195d2c9072e29644962Gilles Debunne // No need to register again if this is a DropDown, showAsDropDown already did. 202681f08086b44a117097960195d2c9072e29644962Gilles Debunne mAnchorXoff = xoff; 202781f08086b44a117097960195d2c9072e29644962Gilles Debunne mAnchorYoff = yoff; 20289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2030105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (updateDimension) { 2031105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (width == -1) { 2032105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project width = mPopupWidth; 2033105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } else { 2034105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mPopupWidth = width; 2035105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 2036105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (height == -1) { 2037105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project height = mPopupHeight; 2038105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } else { 2039105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mPopupHeight = height; 2040105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 20419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2042105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 204375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette final WindowManager.LayoutParams p = 20445435a30ae552391f14009c4459731ae149675b18Alan Viverette (WindowManager.LayoutParams) mDecorView.getLayoutParams(); 204575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette final int x = p.x; 204675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette final int y = p.y; 2047105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (updateLocation) { 204875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette updateAboveAnchor(findDropDownPosition(anchor, p, xoff, yoff, mAnchoredGravity)); 20499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 205054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell updateAboveAnchor(findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff, 205154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell mAnchoredGravity)); 20529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2053b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio 20543e141685003939a9addce21ba2492ea3a8aebee6Romain Guy update(p.x, p.y, width, height, x != p.x || y != p.y); 20559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 20589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Listener that is called when this popup window is dismissed. 20599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 20609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnDismissListener { 20619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 20629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called when this popup window is dismissed. 20639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 20649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onDismiss(); 20659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2067634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette private void unregisterForViewTreeChanges() { 2068634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette final View anchor = mAnchor != null ? mAnchor.get() : null; 20699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (anchor != null) { 2070e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final ViewTreeObserver vto = anchor.getViewTreeObserver(); 20719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project vto.removeOnScrollChangedListener(mOnScrollChangedListener); 20729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2073e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 2074634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette final View anchorRoot = mAnchorRoot != null ? mAnchorRoot.get() : null; 2075634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette if (anchorRoot != null) { 2076634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette anchorRoot.removeOnAttachStateChangeListener(mOnAnchorRootDetachedListener); 2077634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette } 2078634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 20799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnchor = null; 2080634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette mAnchorRoot = null; 2081634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette mIsAnchorRootAttached = false; 20829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2084634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette private void registerForViewTreeChanges(View anchor, int xoff, int yoff, int gravity) { 2085634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette unregisterForViewTreeChanges(); 2086e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 2087e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final ViewTreeObserver vto = anchor.getViewTreeObserver(); 20889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (vto != null) { 20899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project vto.addOnScrollChangedListener(mOnScrollChangedListener); 20909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2092634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette final View anchorRoot = anchor.getRootView(); 2093634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette anchorRoot.addOnAttachStateChangeListener(mOnAnchorRootDetachedListener); 2094634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 2095634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette mAnchor = new WeakReference<>(anchor); 2096634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette mAnchorRoot = new WeakReference<>(anchorRoot); 2097634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette mIsAnchorRootAttached = anchorRoot.isAttachedToWindow(); 2098634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 20999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnchorXoff = xoff; 21009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnchorYoff = yoff; 210154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell mAnchoredGravity = gravity; 21029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21045435a30ae552391f14009c4459731ae149675b18Alan Viverette private class PopupDecorView extends FrameLayout { 21058fd949e680c15d397084430d4907c16cedfacddaAlan Viverette private TransitionListenerAdapter mPendingExitListener; 21068fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 21075435a30ae552391f14009c4459731ae149675b18Alan Viverette public PopupDecorView(Context context) { 21085435a30ae552391f14009c4459731ae149675b18Alan Viverette super(context); 21095435a30ae552391f14009c4459731ae149675b18Alan Viverette } 21109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 21129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean dispatchKeyEvent(KeyEvent event) { 21139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { 21144ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson if (getKeyDispatcherState() == null) { 21154ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson return super.dispatchKeyEvent(event); 21164ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson } 21174ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson 21185435a30ae552391f14009c4459731ae149675b18Alan Viverette if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { 21195435a30ae552391f14009c4459731ae149675b18Alan Viverette final KeyEvent.DispatcherState state = getKeyDispatcherState(); 2120b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown if (state != null) { 2121b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown state.startTracking(event, this); 2122b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } 21238d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn return true; 2124b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } else if (event.getAction() == KeyEvent.ACTION_UP) { 21255435a30ae552391f14009c4459731ae149675b18Alan Viverette final KeyEvent.DispatcherState state = getKeyDispatcherState(); 2126b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown if (state != null && state.isTracking(event) && !event.isCanceled()) { 2127b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown dismiss(); 2128b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown return true; 2129b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } 21308d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn } 21318d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn return super.dispatchKeyEvent(event); 21329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 21339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.dispatchKeyEvent(event); 21349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 21389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean dispatchTouchEvent(MotionEvent ev) { 21399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTouchInterceptor != null && mTouchInterceptor.onTouch(this, ev)) { 21409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 21419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.dispatchTouchEvent(ev); 21439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 21469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onTouchEvent(MotionEvent event) { 21479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int x = (int) event.getX(); 21489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int y = (int) event.getY(); 21495435a30ae552391f14009c4459731ae149675b18Alan Viverette 21509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((event.getAction() == MotionEvent.ACTION_DOWN) 21519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && ((x < 0) || (x >= getWidth()) || (y < 0) || (y >= getHeight()))) { 21529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dismiss(); 21539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 21549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (event.getAction() == MotionEvent.ACTION_OUTSIDE) { 21559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dismiss(); 21569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 21579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 21589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.onTouchEvent(event); 21599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21618fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 21628fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 21638fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Requests that an enter transition run after the next layout pass. 21648fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 21658fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void requestEnterTransition(Transition transition) { 21668fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewTreeObserver observer = getViewTreeObserver(); 21678fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (observer != null && transition != null) { 21688fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final Transition enterTransition = transition.clone(); 21698fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 21708fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // Postpone the enter transition after the first layout pass. 21718fd949e680c15d397084430d4907c16cedfacddaAlan Viverette observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 21728fd949e680c15d397084430d4907c16cedfacddaAlan Viverette @Override 21738fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void onGlobalLayout() { 21748fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewTreeObserver observer = getViewTreeObserver(); 21758fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (observer != null) { 21768fd949e680c15d397084430d4907c16cedfacddaAlan Viverette observer.removeOnGlobalLayoutListener(this); 21778fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 21788fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 217991098574f90277128415e9593cce1e495cc51465Alan Viverette final Rect epicenter = getTransitionEpicenter(); 218095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette enterTransition.setEpicenterCallback(new EpicenterCallback() { 218195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette @Override 218295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette public Rect onGetEpicenter(Transition transition) { 218395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette return epicenter; 218495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette } 218595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette }); 21868fd949e680c15d397084430d4907c16cedfacddaAlan Viverette startEnterTransition(enterTransition); 21878fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 21888fd949e680c15d397084430d4907c16cedfacddaAlan Viverette }); 21898fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 21908fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 21918fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 21928fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 21938fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Starts the pending enter transition, if one is set. 21948fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 21958fd949e680c15d397084430d4907c16cedfacddaAlan Viverette private void startEnterTransition(Transition enterTransition) { 21968fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final int count = getChildCount(); 21978fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 21988fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 21998fd949e680c15d397084430d4907c16cedfacddaAlan Viverette enterTransition.addTarget(child); 22008fd949e680c15d397084430d4907c16cedfacddaAlan Viverette child.setVisibility(View.INVISIBLE); 22018fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 22028fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 22038fd949e680c15d397084430d4907c16cedfacddaAlan Viverette TransitionManager.beginDelayedTransition(this, enterTransition); 22048fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 22058fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 22068fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 22078fd949e680c15d397084430d4907c16cedfacddaAlan Viverette child.setVisibility(View.VISIBLE); 22088fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 22098fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 22108fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 22118fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 22128fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Starts an exit transition immediately. 22138fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * <p> 22148fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * <strong>Note:</strong> The transition listener is guaranteed to have 22158fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * its {@code onTransitionEnd} method called even if the transition 22168fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * never starts; however, it may be called with a {@code null} argument. 22178fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 2218634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette public void startExitTransition(Transition transition, final View anchorRoot, 2219634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette final TransitionListener listener) { 22208fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (transition == null) { 22218fd949e680c15d397084430d4907c16cedfacddaAlan Viverette return; 22228fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 22238fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 2224634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // The anchor view's window may go away while we're executing our 2225634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // transition, in which case we need to end the transition 2226634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // immediately and execute the listener to remove the popup. 2227634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette anchorRoot.addOnAttachStateChangeListener(mOnAnchorRootDetachedListener); 2228634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 22298fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // The exit listener MUST be called for cleanup, even if the 22308fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // transition never starts or ends. Stash it for later. 22318fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mPendingExitListener = new TransitionListenerAdapter() { 22328fd949e680c15d397084430d4907c16cedfacddaAlan Viverette @Override 22338fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void onTransitionEnd(Transition transition) { 2234634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette anchorRoot.removeOnAttachStateChangeListener(mOnAnchorRootDetachedListener); 22358fd949e680c15d397084430d4907c16cedfacddaAlan Viverette listener.onTransitionEnd(transition); 22368fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 22378fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // The listener was called. Our job here is done. 22388fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mPendingExitListener = null; 22398fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 22408fd949e680c15d397084430d4907c16cedfacddaAlan Viverette }; 22418fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 22428fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final Transition exitTransition = transition.clone(); 22438fd949e680c15d397084430d4907c16cedfacddaAlan Viverette exitTransition.addListener(mPendingExitListener); 22448fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 22458fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final int count = getChildCount(); 22468fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 22478fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 22488fd949e680c15d397084430d4907c16cedfacddaAlan Viverette exitTransition.addTarget(child); 22498fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 22508fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 22518fd949e680c15d397084430d4907c16cedfacddaAlan Viverette TransitionManager.beginDelayedTransition(this, exitTransition); 22528fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 22538fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 22548fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 22558fd949e680c15d397084430d4907c16cedfacddaAlan Viverette child.setVisibility(View.INVISIBLE); 22568fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 22578fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 22588fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 22598fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 22608fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Cancels all pending or current transitions. 22618fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 22628fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void cancelTransitions() { 22638fd949e680c15d397084430d4907c16cedfacddaAlan Viverette TransitionManager.endTransitions(this); 22648fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 22658fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (mPendingExitListener != null) { 22668fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mPendingExitListener.onTransitionEnd(null); 22678fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 22688fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 2269634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 2270634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette private final OnAttachStateChangeListener mOnAnchorRootDetachedListener = 2271634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette new OnAttachStateChangeListener() { 2272634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette @Override 2273634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette public void onViewAttachedToWindow(View v) {} 2274634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 2275634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette @Override 2276634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette public void onViewDetachedFromWindow(View v) { 2277634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette v.removeOnAttachStateChangeListener(this); 2278634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 2279634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette TransitionManager.endTransitions(PopupDecorView.this); 2280634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette } 2281634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette }; 22825435a30ae552391f14009c4459731ae149675b18Alan Viverette } 22835435a30ae552391f14009c4459731ae149675b18Alan Viverette 22845435a30ae552391f14009c4459731ae149675b18Alan Viverette private class PopupBackgroundView extends FrameLayout { 22855435a30ae552391f14009c4459731ae149675b18Alan Viverette public PopupBackgroundView(Context context) { 22865435a30ae552391f14009c4459731ae149675b18Alan Viverette super(context); 22875435a30ae552391f14009c4459731ae149675b18Alan Viverette } 228875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 228975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov @Override 22905435a30ae552391f14009c4459731ae149675b18Alan Viverette protected int[] onCreateDrawableState(int extraSpace) { 22915435a30ae552391f14009c4459731ae149675b18Alan Viverette if (mAboveAnchor) { 22925435a30ae552391f14009c4459731ae149675b18Alan Viverette final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 22935435a30ae552391f14009c4459731ae149675b18Alan Viverette View.mergeDrawableStates(drawableState, ABOVE_ANCHOR_STATE_SET); 22945435a30ae552391f14009c4459731ae149675b18Alan Viverette return drawableState; 229575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } else { 22965435a30ae552391f14009c4459731ae149675b18Alan Viverette return super.onCreateDrawableState(extraSpace); 229775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 229875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 22999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2301