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