19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1999441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikasimport static android.view.ViewGroup.LayoutParams.MATCH_PARENT; 2099441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikasimport static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; 2199441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikasimport static android.view.WindowManager.LayoutParams 2299441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikas .PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME; 2399441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikasimport static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viveretteimport android.annotation.NonNull; 261e940dc2d165fa6cdedb6945811988502f87ddceAlan Viveretteimport android.annotation.Nullable; 2775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.Context; 2875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.res.TypedArray; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PixelFormat; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.Drawable; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.StateListDrawable; 3346e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brownimport android.os.Build; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 355435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.Transition; 365435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.Transition.EpicenterCallback; 378fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.transition.Transition.TransitionListener; 385435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.TransitionInflater; 39e0c37bdea37f78778f6c4f23f03604e59dfb0d55Ben Weissimport android.transition.TransitionListenerAdapter; 405435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.TransitionManager; 415435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.TransitionSet; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 43c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.Gravity; 44c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.KeyEvent; 4550db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwalimport android.view.KeyboardShortcutGroup; 46c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.MotionEvent; 47c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.View; 48634a808226cc5d00bd6897bdc881cafe064e37acAlan Viveretteimport android.view.View.OnAttachStateChangeListener; 49a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport android.view.View.OnTouchListener; 50c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.ViewGroup; 518fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.view.ViewParent; 52c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.ViewTreeObserver; 538fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.view.ViewTreeObserver.OnGlobalLayoutListener; 54c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.ViewTreeObserver.OnScrollChangedListener; 55a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport android.view.WindowManager; 56259c2840691a79634ffd8f63291ec21c21819542Alan Viveretteimport android.view.WindowManager.LayoutParams; 5722dac1c8df4ec212e8195a69d2de15d313d724fbYohei Yukawaimport android.view.WindowManager.LayoutParams.SoftInputModeFlags; 58b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheevimport android.view.WindowManagerGlobal; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6099441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikasimport com.android.internal.R; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6299441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikasimport java.lang.ref.WeakReference; 6350db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwalimport java.util.List; 641e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 661e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <p> 671e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * This class represents a popup window that can be used to display an 681e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * arbitrary view. The popup window is a floating container that appears on top 691e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * of the current activity. 701e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </p> 711e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <a name="Animation"></a> 721e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <h3>Animation</h3> 731e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <p> 741e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * On all versions of Android, popup window enter and exit animations may be 751e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * specified by calling {@link #setAnimationStyle(int)} and passing the 761e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * resource ID for an animation style that defines {@code windowEnterAnimation} 771e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * and {@code windowExitAnimation}. For example, passing 781e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * {@link android.R.style#Animation_Dialog} will give a scale and alpha 791e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * animation. 801e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </br> 811e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * A window animation style may also be specified in the popup window's style 821e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * XML via the {@link android.R.styleable#PopupWindow_popupAnimationStyle popupAnimationStyle} 831e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * attribute. 841e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </p> 851e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <p> 861e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * Starting with API 23, more complex popup window enter and exit transitions 871e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * may be specified by calling either {@link #setEnterTransition(Transition)} 881e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * or {@link #setExitTransition(Transition)} and passing a {@link Transition}. 891e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </br> 901e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * Popup enter and exit transitions may also be specified in the popup window's 911e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * style XML via the {@link android.R.styleable#PopupWindow_popupEnterTransition popupEnterTransition} 921e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * and {@link android.R.styleable#PopupWindow_popupExitTransition popupExitTransition} 931e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * attributes, respectively. 941e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </p> 951e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * 961e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_overlapAnchor 971e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupAnimationStyle 981e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupBackground 991e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupElevation 1001e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupEnterTransition 1011e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupExitTransition 1025435a30ae552391f14009c4459731ae149675b18Alan Viverette * 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.widget.AutoCompleteTextView 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.widget.Spinner 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class PopupWindow { 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 108e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * Mode for {@link #setInputMethodMode(int)}: the requirements for the 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * input method should be based on the focusability of the popup. That is 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if it is focusable than it needs to work with the input method, else 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * it doesn't. 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int INPUT_METHOD_FROM_FOCUSABLE = 0; 1145435a30ae552391f14009c4459731ae149675b18Alan Viverette 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 116e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * Mode for {@link #setInputMethodMode(int)}: this popup always needs to 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * work with an input method, regardless of whether it is focusable. This 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * means that it will always be displayed so that the user can also operate 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the input method while it is shown. 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int INPUT_METHOD_NEEDED = 1; 1225435a30ae552391f14009c4459731ae149675b18Alan Viverette 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 124e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * Mode for {@link #setInputMethodMode(int)}: this popup never needs to 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * work with an input method, regardless of whether it is focusable. This 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * means that it will always be displayed to use as much space on the 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * screen as needed, regardless of whether this covers the input method. 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int INPUT_METHOD_NOT_NEEDED = 2; 13054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 13154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell private static final int DEFAULT_ANCHORED_GRAVITY = Gravity.TOP | Gravity.START; 13254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 1335435a30ae552391f14009c4459731ae149675b18Alan Viverette /** 1345435a30ae552391f14009c4459731ae149675b18Alan Viverette * Default animation style indicating that separate animations should be 1355435a30ae552391f14009c4459731ae149675b18Alan Viverette * used for top/bottom anchoring states. 1365435a30ae552391f14009c4459731ae149675b18Alan Viverette */ 1375435a30ae552391f14009c4459731ae149675b18Alan Viverette private static final int ANIMATION_STYLE_DEFAULT = -1; 1385435a30ae552391f14009c4459731ae149675b18Alan Viverette 139f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette private final int[] mTmpDrawingLocation = new int[2]; 140f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette private final int[] mTmpScreenLocation = new int[2]; 141b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev private final int[] mTmpAppLocation = new int[2]; 1425435a30ae552391f14009c4459731ae149675b18Alan Viverette private final Rect mTempRect = new Rect(); 1435435a30ae552391f14009c4459731ae149675b18Alan Viverette 144448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy private Context mContext; 145448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy private WindowManager mWindowManager; 1465435a30ae552391f14009c4459731ae149675b18Alan Viverette 14750db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal /** 14850db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal * Keeps track of popup's parent's decor view. This is needed to dispatch 14950db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal * requestKeyboardShortcuts to the owning Activity. 15050db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal */ 15150db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal private WeakReference<View> mParentRootView; 15250db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mIsShowing; 1548fd949e680c15d397084430d4907c16cedfacddaAlan Viverette private boolean mIsTransitioningToDismiss; 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mIsDropdown; 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1575435a30ae552391f14009c4459731ae149675b18Alan Viverette /** View that handles event dispatch and content transitions. */ 1585435a30ae552391f14009c4459731ae149675b18Alan Viverette private PopupDecorView mDecorView; 1595435a30ae552391f14009c4459731ae149675b18Alan Viverette 160697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette /** View that holds the background and may animate during a transition. */ 161697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette private View mBackgroundView; 162697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette 163697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette /** The contents of the popup. May be identical to the background view. */ 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View mContentView; 1655435a30ae552391f14009c4459731ae149675b18Alan Viverette 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mFocusable; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mInputMethodMode = INPUT_METHOD_FROM_FOCUSABLE; 16822dac1c8df4ec212e8195a69d2de15d313d724fbYohei Yukawa @SoftInputModeFlags 1697eab094722af54717859b7dcce3cc050f059e00bDianne Hackborn private int mSoftInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED; 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mTouchable = true; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mOutsideTouchable = false; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mClippingEnabled = true; 17346e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown private int mSplitTouchEnabled = -1; 174ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell private boolean mLayoutInScreen; 17556c2d337e02a275397fc9d0460dca90977f199acAdam Powell private boolean mClipToScreen; 176348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell private boolean mAllowScrollingAnchorParent = true; 1770bd1d0a15294345bf88b20df28466907f982cec7Adam Powell private boolean mLayoutInsetDecor = false; 178e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell private boolean mNotTouchModal; 179393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale private boolean mAttachedInDecor = true; 180393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale private boolean mAttachedInDecorSet = false; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnTouchListener mTouchInterceptor; 183393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mWidthMode; 185259c2840691a79634ffd8f63291ec21c21819542Alan Viverette private int mWidth = LayoutParams.WRAP_CONTENT; 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLastWidth; 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mHeightMode; 188259c2840691a79634ffd8f63291ec21c21819542Alan Viverette private int mHeight = LayoutParams.WRAP_CONTENT; 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLastHeight; 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 191ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette private float mElevation; 192ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Drawable mBackground; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Drawable mAboveAnchorBackgroundDrawable; 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Drawable mBelowAnchorBackgroundDrawable; 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1975435a30ae552391f14009c4459731ae149675b18Alan Viverette private Transition mEnterTransition; 1985435a30ae552391f14009c4459731ae149675b18Alan Viverette private Transition mExitTransition; 19991098574f90277128415e9593cce1e495cc51465Alan Viverette private Rect mEpicenterBounds; 200560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mAboveAnchor; 202574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell private int mWindowLayoutType = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; 2035435a30ae552391f14009c4459731ae149675b18Alan Viverette 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnDismissListener mOnDismissListener; 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mIgnoreCheekPress = false; 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2075435a30ae552391f14009c4459731ae149675b18Alan Viverette private int mAnimationStyle = ANIMATION_STYLE_DEFAULT; 2085435a30ae552391f14009c4459731ae149675b18Alan Viverette 209085160612d9066e23c96a6cac15eb3a51481fdafRobert Carr private int mGravity = Gravity.NO_GRAVITY; 210085160612d9066e23c96a6cac15eb3a51481fdafRobert Carr 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int[] ABOVE_ANCHOR_STATE_SET = new int[] { 2124753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme com.android.internal.R.attr.state_above_anchor 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 215afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev private final OnAttachStateChangeListener mOnAnchorDetachedListener = 216afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev new OnAttachStateChangeListener() { 217afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev @Override 218afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev public void onViewAttachedToWindow(View v) { 219afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev // Anchor might have been reattached in a different position. 220afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev alignToAnchor(); 221afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev } 222afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev 223afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev @Override 224afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev public void onViewDetachedFromWindow(View v) { 225afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev // Leave the popup in its current position. 226afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev // The anchor might become attached again. 227afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev } 228afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev }; 229afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev 230634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette private final OnAttachStateChangeListener mOnAnchorRootDetachedListener = 231634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette new OnAttachStateChangeListener() { 232634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette @Override 233634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette public void onViewAttachedToWindow(View v) {} 234634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 235634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette @Override 236634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette public void onViewDetachedFromWindow(View v) { 237634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette mIsAnchorRootAttached = false; 238634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette } 239634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette }; 240634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private WeakReference<View> mAnchor; 242634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette private WeakReference<View> mAnchorRoot; 243634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette private boolean mIsAnchorRootAttached; 244560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 245afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev private final OnScrollChangedListener mOnScrollChangedListener = this::alignToAnchor; 246560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 247b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev private final View.OnLayoutChangeListener mOnLayoutChangeListener = 248b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> alignToAnchor(); 249b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev 2505435a30ae552391f14009c4459731ae149675b18Alan Viverette private int mAnchorXoff; 2515435a30ae552391f14009c4459731ae149675b18Alan Viverette private int mAnchorYoff; 2525435a30ae552391f14009c4459731ae149675b18Alan Viverette private int mAnchoredGravity; 253560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette private boolean mOverlapAnchor; 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 255b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio private boolean mPopupViewInitialLayoutDirectionInherited; 256b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window of dimension (0,0).</p> 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does provide a background.</p> 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(Context context) { 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, null); 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window of dimension (0,0).</p> 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does provide a background.</p> 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(Context context, AttributeSet attrs) { 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, attrs, com.android.internal.R.attr.popupWindowStyle); 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window of dimension (0,0).</p> 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does provide a background.</p> 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 280617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr) { 281617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette this(context, attrs, defStyleAttr, 0); 282c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 2835435a30ae552391f14009c4459731ae149675b18Alan Viverette 284c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 285c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>Create a new, empty, non focusable popup window of dimension (0,0).</p> 2865435a30ae552391f14009c4459731ae149675b18Alan Viverette * 287c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>The popup does not provide a background.</p> 288c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 289c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 29175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 293617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette final TypedArray a = context.obtainStyledAttributes( 294ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette attrs, R.styleable.PopupWindow, defStyleAttr, defStyleRes); 295ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette final Drawable bg = a.getDrawable(R.styleable.PopupWindow_popupBackground); 296ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette mElevation = a.getDimension(R.styleable.PopupWindow_popupElevation, 0); 297560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette mOverlapAnchor = a.getBoolean(R.styleable.PopupWindow_overlapAnchor, false); 298c3808b5dc7d5873d04e8a0a247b179b2757764baAdam Powell 2995435a30ae552391f14009c4459731ae149675b18Alan Viverette // Preserve default behavior from Gingerbread. If the animation is 3005435a30ae552391f14009c4459731ae149675b18Alan Viverette // undefined or explicitly specifies the Gingerbread animation style, 3015435a30ae552391f14009c4459731ae149675b18Alan Viverette // use a sentinel value. 3025435a30ae552391f14009c4459731ae149675b18Alan Viverette if (a.hasValueOrEmpty(R.styleable.PopupWindow_popupAnimationStyle)) { 3035435a30ae552391f14009c4459731ae149675b18Alan Viverette final int animStyle = a.getResourceId(R.styleable.PopupWindow_popupAnimationStyle, 0); 3045435a30ae552391f14009c4459731ae149675b18Alan Viverette if (animStyle == R.style.Animation_PopupWindow) { 3055435a30ae552391f14009c4459731ae149675b18Alan Viverette mAnimationStyle = ANIMATION_STYLE_DEFAULT; 3065435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 3075435a30ae552391f14009c4459731ae149675b18Alan Viverette mAnimationStyle = animStyle; 3085435a30ae552391f14009c4459731ae149675b18Alan Viverette } 3095435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 3105435a30ae552391f14009c4459731ae149675b18Alan Viverette mAnimationStyle = ANIMATION_STYLE_DEFAULT; 3115435a30ae552391f14009c4459731ae149675b18Alan Viverette } 3125435a30ae552391f14009c4459731ae149675b18Alan Viverette 3135435a30ae552391f14009c4459731ae149675b18Alan Viverette final Transition enterTransition = getTransition(a.getResourceId( 3145435a30ae552391f14009c4459731ae149675b18Alan Viverette R.styleable.PopupWindow_popupEnterTransition, 0)); 3155435a30ae552391f14009c4459731ae149675b18Alan Viverette final Transition exitTransition; 3165435a30ae552391f14009c4459731ae149675b18Alan Viverette if (a.hasValueOrEmpty(R.styleable.PopupWindow_popupExitTransition)) { 3175435a30ae552391f14009c4459731ae149675b18Alan Viverette exitTransition = getTransition(a.getResourceId( 3185435a30ae552391f14009c4459731ae149675b18Alan Viverette R.styleable.PopupWindow_popupExitTransition, 0)); 3195435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 3205435a30ae552391f14009c4459731ae149675b18Alan Viverette exitTransition = enterTransition == null ? null : enterTransition.clone(); 3215435a30ae552391f14009c4459731ae149675b18Alan Viverette } 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 324ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 3255435a30ae552391f14009c4459731ae149675b18Alan Viverette setEnterTransition(enterTransition); 3265435a30ae552391f14009c4459731ae149675b18Alan Viverette setExitTransition(exitTransition); 327ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette setBackgroundDrawable(bg); 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window of dimension (0,0).</p> 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow() { 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(null, 0, 0); 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new non focusable popup window which can display the 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tt>contentView</tt>. The dimension of the window are (0,0).</p> 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param contentView the popup's content 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(View contentView) { 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(contentView, 0, 0); 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window. The dimension of the 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window must be passed to this constructor.</p> 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param width the popup's width 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param height the popup's height 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(int width, int height) { 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(null, width, height); 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new non focusable popup window which can display the 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tt>contentView</tt>. The dimension of the window must be passed to 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this constructor.</p> 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param contentView the popup's content 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param width the popup's width 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param height the popup's height 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(View contentView, int width, int height) { 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(contentView, width, height, false); 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new popup window which can display the <tt>contentView</tt>. 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The dimension of the window must be passed to this constructor.</p> 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param contentView the popup's content 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param width the popup's width 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param height the popup's height 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param focusable true if the popup can be focused, false otherwise 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 395448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy public PopupWindow(View contentView, int width, int height, boolean focusable) { 396448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy if (contentView != null) { 397448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy mContext = contentView.getContext(); 398448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); 399448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy } 400393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setContentView(contentView); 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setWidth(width); 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setHeight(height); 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setFocusable(focusable); 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4071e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette /** 4081e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * Sets the enter transition to be used when the popup window is shown. 4091e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * 4101e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @param enterTransition the enter transition, or {@code null} to clear 4111e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @see #getEnterTransition() 4121e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupEnterTransition 4131e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette */ 4141e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette public void setEnterTransition(@Nullable Transition enterTransition) { 4155435a30ae552391f14009c4459731ae149675b18Alan Viverette mEnterTransition = enterTransition; 4165435a30ae552391f14009c4459731ae149675b18Alan Viverette } 4175435a30ae552391f14009c4459731ae149675b18Alan Viverette 4181e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette /** 4191e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * Returns the enter transition to be used when the popup window is shown. 4201e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * 4211e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @return the enter transition, or {@code null} if not set 4221e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @see #setEnterTransition(Transition) 4231e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupEnterTransition 4241e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette */ 4251e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette @Nullable 4261e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette public Transition getEnterTransition() { 4271e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette return mEnterTransition; 4281e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette } 4291e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette 4301e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette /** 4311e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * Sets the exit transition to be used when the popup window is dismissed. 4321e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * 4331e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @param exitTransition the exit transition, or {@code null} to clear 4341e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @see #getExitTransition() 4351e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupExitTransition 4361e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette */ 4371e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette public void setExitTransition(@Nullable Transition exitTransition) { 4385435a30ae552391f14009c4459731ae149675b18Alan Viverette mExitTransition = exitTransition; 4395435a30ae552391f14009c4459731ae149675b18Alan Viverette } 4405435a30ae552391f14009c4459731ae149675b18Alan Viverette 44191098574f90277128415e9593cce1e495cc51465Alan Viverette /** 4421e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * Returns the exit transition to be used when the popup window is 4431e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * dismissed. 4441e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * 4451e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @return the exit transition, or {@code null} if not set 4461e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @see #setExitTransition(Transition) 4471e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupExitTransition 4481e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette */ 4491e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette @Nullable 4501e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette public Transition getExitTransition() { 4511e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette return mExitTransition; 4521e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette } 4531e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette 4541e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette /** 45591098574f90277128415e9593cce1e495cc51465Alan Viverette * Sets the bounds used as the epicenter of the enter and exit transitions. 45691098574f90277128415e9593cce1e495cc51465Alan Viverette * <p> 45791098574f90277128415e9593cce1e495cc51465Alan Viverette * Transitions use a point or Rect, referred to as the epicenter, to orient 45891098574f90277128415e9593cce1e495cc51465Alan Viverette * the direction of travel. For popup windows, the anchor view bounds are 45991098574f90277128415e9593cce1e495cc51465Alan Viverette * used as the default epicenter. 46091098574f90277128415e9593cce1e495cc51465Alan Viverette * <p> 46191098574f90277128415e9593cce1e495cc51465Alan Viverette * See {@link Transition#setEpicenterCallback(EpicenterCallback)} for more 46291098574f90277128415e9593cce1e495cc51465Alan Viverette * information about how transition epicenters. 46391098574f90277128415e9593cce1e495cc51465Alan Viverette * 46491098574f90277128415e9593cce1e495cc51465Alan Viverette * @param bounds the epicenter bounds relative to the anchor view, or 46591098574f90277128415e9593cce1e495cc51465Alan Viverette * {@code null} to use the default epicenter 46691098574f90277128415e9593cce1e495cc51465Alan Viverette * @see #getTransitionEpicenter() 46791098574f90277128415e9593cce1e495cc51465Alan Viverette * @hide 46891098574f90277128415e9593cce1e495cc51465Alan Viverette */ 46991098574f90277128415e9593cce1e495cc51465Alan Viverette public void setEpicenterBounds(Rect bounds) { 47091098574f90277128415e9593cce1e495cc51465Alan Viverette mEpicenterBounds = bounds; 47191098574f90277128415e9593cce1e495cc51465Alan Viverette } 47291098574f90277128415e9593cce1e495cc51465Alan Viverette 4735435a30ae552391f14009c4459731ae149675b18Alan Viverette private Transition getTransition(int resId) { 4745435a30ae552391f14009c4459731ae149675b18Alan Viverette if (resId != 0 && resId != R.transition.no_transition) { 4755435a30ae552391f14009c4459731ae149675b18Alan Viverette final TransitionInflater inflater = TransitionInflater.from(mContext); 4765435a30ae552391f14009c4459731ae149675b18Alan Viverette final Transition transition = inflater.inflateTransition(resId); 4775435a30ae552391f14009c4459731ae149675b18Alan Viverette if (transition != null) { 4785435a30ae552391f14009c4459731ae149675b18Alan Viverette final boolean isEmpty = transition instanceof TransitionSet 4795435a30ae552391f14009c4459731ae149675b18Alan Viverette && ((TransitionSet) transition).getTransitionCount() == 0; 4805435a30ae552391f14009c4459731ae149675b18Alan Viverette if (!isEmpty) { 4815435a30ae552391f14009c4459731ae149675b18Alan Viverette return transition; 4825435a30ae552391f14009c4459731ae149675b18Alan Viverette } 4835435a30ae552391f14009c4459731ae149675b18Alan Viverette } 4845435a30ae552391f14009c4459731ae149675b18Alan Viverette } 4855435a30ae552391f14009c4459731ae149675b18Alan Viverette return null; 4865435a30ae552391f14009c4459731ae149675b18Alan Viverette } 4875435a30ae552391f14009c4459731ae149675b18Alan Viverette 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 489ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * Return the drawable used as the popup window's background. 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 491ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @return the background drawable or {@code null} if not set 492ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @see #setBackgroundDrawable(Drawable) 493ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @attr ref android.R.styleable#PopupWindow_popupBackground 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable getBackground() { 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBackground; 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 500ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * Specifies the background drawable for this popup window. The background 501ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * can be set to {@code null}. 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param background the popup's background 504ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @see #getBackground() 505ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @attr ref android.R.styleable#PopupWindow_popupBackground 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setBackgroundDrawable(Drawable background) { 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBackground = background; 509ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 510ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // If this is a StateListDrawable, try to find and store the drawable to be 511ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // used when the drop-down is placed above its anchor view, and the one to be 512ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // used when the drop-down is placed below its anchor view. We extract 513ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // the drawables ourselves to work around a problem with using refreshDrawableState 514ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // that it will take into account the padding of all drawables specified in a 515ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // StateListDrawable, thus adding superfluous padding to drop-down views. 516ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // 517ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // We assume a StateListDrawable will have a drawable for ABOVE_ANCHOR_STATE_SET and 518ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // at least one other drawable, intended for the 'below-anchor state'. 519ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette if (mBackground instanceof StateListDrawable) { 520ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette StateListDrawable stateList = (StateListDrawable) mBackground; 521ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 522ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // Find the above-anchor view - this one's easy, it should be labeled as such. 523ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette int aboveAnchorStateIndex = stateList.getStateDrawableIndex(ABOVE_ANCHOR_STATE_SET); 524ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 525ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // Now, for the below-anchor view, look for any other drawable specified in the 526ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // StateListDrawable which is not for the above-anchor state and use that. 527ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette int count = stateList.getStateCount(); 528ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette int belowAnchorStateIndex = -1; 529ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette for (int i = 0; i < count; i++) { 530ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette if (i != aboveAnchorStateIndex) { 531ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette belowAnchorStateIndex = i; 532ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette break; 533ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } 534ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } 535ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 536ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // Store the drawables we found, if we found them. Otherwise, set them both 537ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // to null so that we'll just use refreshDrawableState. 538ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette if (aboveAnchorStateIndex != -1 && belowAnchorStateIndex != -1) { 539ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette mAboveAnchorBackgroundDrawable = stateList.getStateDrawable(aboveAnchorStateIndex); 540ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette mBelowAnchorBackgroundDrawable = stateList.getStateDrawable(belowAnchorStateIndex); 541ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } else { 542ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette mBelowAnchorBackgroundDrawable = null; 543ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette mAboveAnchorBackgroundDrawable = null; 544ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } 545ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 549ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @return the elevation for this popup window in pixels 550ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @see #setElevation(float) 551ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @attr ref android.R.styleable#PopupWindow_popupElevation 552ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette */ 553ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette public float getElevation() { 554ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette return mElevation; 555ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette } 556ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette 557ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette /** 558ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * Specifies the elevation for this popup window. 559ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * 560ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @param elevation the popup's elevation in pixels 561ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @see #getElevation() 562ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @attr ref android.R.styleable#PopupWindow_popupElevation 563ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette */ 564ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette public void setElevation(float elevation) { 565ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette mElevation = elevation; 566ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette } 567ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette 568ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette /** 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Return the animation style to use the popup appears and disappears</p> 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the animation style to use the popup appears and disappears 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getAnimationStyle() { 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAnimationStyle; 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 576393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 57854ec76d81ac38284caa6d00ad5f2d2207206b9ceShuhrat Dehkanov * Set the flag on popup to ignore cheek press events; by default this flag 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is set to false 58054ec76d81ac38284caa6d00ad5f2d2207206b9ceShuhrat Dehkanov * which means the popup will not ignore cheek press dispatch events. 5815435a30ae552391f14009c4459731ae149675b18Alan Viverette * 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 585393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setIgnoreCheekPress() { 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIgnoreCheekPress = true; 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5915435a30ae552391f14009c4459731ae149675b18Alan Viverette 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Change the animation style resource for this popup.</p> 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param animationStyle animation style to use when the popup appears 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and disappears. Set to -1 for the default animation, 0 for no 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * animation, or a resource identifier for an explicit animation. 6025435a30ae552391f14009c4459731ae149675b18Alan Viverette * 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAnimationStyle(int animationStyle) { 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimationStyle = animationStyle; 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6085435a30ae552391f14009c4459731ae149675b18Alan Viverette 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Return the view used as the content of the popup window.</p> 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return a {@link android.view.View} representing the popup's content 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setContentView(android.view.View) 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public View getContentView() { 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mContentView; 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Change the popup's content. The content is represented by an instance 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of {@link android.view.View}.</p> 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 62481f08086b44a117097960195d2c9072e29644962Gilles Debunne * <p>This method has no effect if called when the popup is showing.</p> 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param contentView the new content for the popup 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getContentView() 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isShowing() 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setContentView(View contentView) { 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isShowing()) { 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentView = contentView; 637448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy 6380c0b768e1514280812321854db6dfba723c3d169Romain Guy if (mContext == null && mContentView != null) { 639448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy mContext = mContentView.getContext(); 640448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy } 641448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy 6420c0b768e1514280812321854db6dfba723c3d169Romain Guy if (mWindowManager == null && mContentView != null) { 643448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); 644448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy } 645393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 646393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // Setting the default for attachedInDecor based on SDK version here 647393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // instead of in the constructor since we might not have the context 648393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // object in the constructor. We only want to set default here if the 649393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // app hasn't already set the attachedInDecor. 650393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale if (mContext != null && !mAttachedInDecorSet) { 651393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // Attach popup window in decor frame of parent window by default for 652393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // {@link Build.VERSION_CODES.LOLLIPOP_MR1} or greater. Keep current 653393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // behavior of not attaching to decor frame for older SDKs. 654393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale setAttachedInDecor(mContext.getApplicationInfo().targetSdkVersion 655393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale >= Build.VERSION_CODES.LOLLIPOP_MR1); 656393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale } 657393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set a callback for all touch events being dispatched to the popup 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window. 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTouchInterceptor(OnTouchListener l) { 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTouchInterceptor = l; 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 667393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicate whether the popup window can grab the focus.</p> 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is focusable, false otherwise 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setFocusable(boolean) 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isFocusable() { 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFocusable; 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Changes the focusability of the popup window. When focusable, the 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window will grab the focus from the current focused widget if the popup 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * contains a focusable {@link android.view.View}. By default a popup 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window is not focusable.</p> 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param focusable true if the popup should grab focus, false otherwise. 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isFocusable() 6925435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setFocusable(boolean focusable) { 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFocusable = focusable; 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the current value in {@link #setInputMethodMode(int)}. 7015435a30ae552391f14009c4459731ae149675b18Alan Viverette * 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setInputMethodMode(int) 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getInputMethodMode() { 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mInputMethodMode; 7065435a30ae552391f14009c4459731ae149675b18Alan Viverette 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7085435a30ae552391f14009c4459731ae149675b18Alan Viverette 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Control how the popup operates with an input method: one of 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #INPUT_METHOD_FROM_FOCUSABLE}, {@link #INPUT_METHOD_NEEDED}, 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or {@link #INPUT_METHOD_NOT_NEEDED}. 7135435a30ae552391f14009c4459731ae149675b18Alan Viverette * 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 7175435a30ae552391f14009c4459731ae149675b18Alan Viverette * 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getInputMethodMode() 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setInputMethodMode(int mode) { 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mInputMethodMode = mode; 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 724374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy 725374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy /** 726374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * Sets the operating mode for the soft input area. 727374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * 728374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @param mode The desired mode, see 729374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * {@link android.view.WindowManager.LayoutParams#softInputMode} 730374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * for the full list 731374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * 732374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @see android.view.WindowManager.LayoutParams#softInputMode 733374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @see #getSoftInputMode() 734374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy */ 73522dac1c8df4ec212e8195a69d2de15d313d724fbYohei Yukawa public void setSoftInputMode(@SoftInputModeFlags int mode) { 736374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy mSoftInputMode = mode; 737374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy } 738374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy 739374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy /** 740374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * Returns the current value in {@link #setSoftInputMode(int)}. 741374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * 742374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @see #setSoftInputMode(int) 743374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @see android.view.WindowManager.LayoutParams#softInputMode 744374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy */ 74522dac1c8df4ec212e8195a69d2de15d313d724fbYohei Yukawa @SoftInputModeFlags 746374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy public int getSoftInputMode() { 747374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy return mSoftInputMode; 748374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy } 7495435a30ae552391f14009c4459731ae149675b18Alan Viverette 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicates whether the popup window receives touch events.</p> 7525435a30ae552391f14009c4459731ae149675b18Alan Viverette * 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is touchable, false otherwise 7545435a30ae552391f14009c4459731ae149675b18Alan Viverette * 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setTouchable(boolean) 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isTouchable() { 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mTouchable; 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Changes the touchability of the popup window. When touchable, the 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window will receive touch events, otherwise touch events will go to the 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window below it. By default the window is touchable.</p> 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param touchable true if the popup should receive touch events, false otherwise 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isTouchable() 7735435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTouchable(boolean touchable) { 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTouchable = touchable; 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicates whether the popup window will be informed of touch events 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * outside of its window.</p> 7835435a30ae552391f14009c4459731ae149675b18Alan Viverette * 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is outside touchable, false otherwise 7855435a30ae552391f14009c4459731ae149675b18Alan Viverette * 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setOutsideTouchable(boolean) 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isOutsideTouchable() { 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mOutsideTouchable; 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Controls whether the pop-up will be informed of touch events outside 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of its window. This only makes sense for pop-ups that are touchable 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * but not focusable, which means touches outside of the window will 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be delivered to the window behind. The default is false.</p> 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param touchable true if the popup should receive outside 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * touch events, false otherwise 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isOutsideTouchable() 8065435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setOutsideTouchable(boolean touchable) { 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOutsideTouchable = touchable; 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicates whether clipping of the popup window is enabled.</p> 8155435a30ae552391f14009c4459731ae149675b18Alan Viverette * 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the clipping is enabled, false otherwise 8175435a30ae552391f14009c4459731ae149675b18Alan Viverette * 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setClippingEnabled(boolean) 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isClippingEnabled() { 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mClippingEnabled; 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Allows the popup window to extend beyond the bounds of the screen. By default the 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window is clipped to the screen boundaries. Setting this to false will allow windows to be 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * accurately positioned.</p> 8285435a30ae552391f14009c4459731ae149675b18Alan Viverette * 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param enabled false if the window should be allowed to extend outside of the screen 8345435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isClippingEnabled() 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setClippingEnabled(boolean enabled) { 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mClippingEnabled = enabled; 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 84356c2d337e02a275397fc9d0460dca90977f199acAdam Powell * Clip this popup window to the screen, but not to the containing window. 84456c2d337e02a275397fc9d0460dca90977f199acAdam Powell * 84556c2d337e02a275397fc9d0460dca90977f199acAdam Powell * @param enabled True to clip to the screen. 84656c2d337e02a275397fc9d0460dca90977f199acAdam Powell * @hide 84756c2d337e02a275397fc9d0460dca90977f199acAdam Powell */ 84856c2d337e02a275397fc9d0460dca90977f199acAdam Powell public void setClipToScreenEnabled(boolean enabled) { 84956c2d337e02a275397fc9d0460dca90977f199acAdam Powell mClipToScreen = enabled; 85056c2d337e02a275397fc9d0460dca90977f199acAdam Powell } 851348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell 852348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell /** 853348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * Allow PopupWindow to scroll the anchor's parent to provide more room 854348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * for the popup. Enabled by default. 855348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * 856348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * @param enabled True to scroll the anchor's parent when more room is desired by the popup. 857348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell */ 858348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell void setAllowScrollingAnchorParent(boolean enabled) { 859348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell mAllowScrollingAnchorParent = enabled; 860348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell } 8615435a30ae552391f14009c4459731ae149675b18Alan Viverette 8624753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme /** @hide */ 8634753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme protected final boolean getAllowScrollingAnchorParent() { 8644753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme return mAllowScrollingAnchorParent; 8654753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme } 8664753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme 86756c2d337e02a275397fc9d0460dca90977f199acAdam Powell /** 86801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * <p>Indicates whether the popup window supports splitting touches.</p> 8695435a30ae552391f14009c4459731ae149675b18Alan Viverette * 87001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * @return true if the touch splitting is enabled, false otherwise 8715435a30ae552391f14009c4459731ae149675b18Alan Viverette * 87201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * @see #setSplitTouchEnabled(boolean) 87301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown */ 87401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown public boolean isSplitTouchEnabled() { 87546e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown if (mSplitTouchEnabled < 0 && mContext != null) { 87646e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown return mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB; 87746e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown } 87846e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown return mSplitTouchEnabled == 1; 87901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown } 88001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown 88101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown /** 88201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * <p>Allows the popup window to split touches across other windows that also 88346e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown * support split touch. When this flag is false, the first pointer 88401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * that goes down determines the window to which all subsequent touches 88546e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown * go until all pointers go up. When this flag is true, each pointer 88601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * (not necessarily the first) that goes down determines the window 88701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * to which all subsequent touches of that pointer will go until that 88801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * pointer goes up thereby enabling touches with multiple pointers 88901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * to be split across multiple windows.</p> 89001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * 89101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * @param enabled true if the split touches should be enabled, false otherwise 89201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * @see #isSplitTouchEnabled() 89301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown */ 89401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown public void setSplitTouchEnabled(boolean enabled) { 89546e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown mSplitTouchEnabled = enabled ? 1 : 0; 89601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown } 89701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown 89801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown /** 899ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * <p>Indicates whether the popup window will be forced into using absolute screen coordinates 900ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * for positioning.</p> 901ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * 902ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * @return true if the window will always be positioned in screen coordinates. 903ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * @hide 904ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell */ 905ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell public boolean isLayoutInScreenEnabled() { 906ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell return mLayoutInScreen; 907ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell } 908ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell 909ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell /** 910ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * <p>Allows the popup window to force the flag 911ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * {@link WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN}, overriding default behavior. 912ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * This will cause the popup to be positioned in absolute screen coordinates.</p> 913ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * 914ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * @param enabled true if the popup should always be positioned in screen coordinates 915ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * @hide 916ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell */ 917ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell public void setLayoutInScreenEnabled(boolean enabled) { 918ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell mLayoutInScreen = enabled; 919ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell } 920ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell 921ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell /** 922393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * <p>Indicates whether the popup window will be attached in the decor frame of its parent 923393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * window. 924393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 925393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @return true if the window will be attached to the decor frame of its parent window. 926393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 927393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @see #setAttachedInDecor(boolean) 928393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR 929393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale */ 930393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale public boolean isAttachedInDecor() { 931393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale return mAttachedInDecor; 932393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale } 933393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 934393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale /** 935393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * <p>This will attach the popup window to the decor frame of the parent window to avoid 936393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * overlaping with screen decorations like the navigation bar. Overrides the default behavior of 937393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * the flag {@link WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR}. 938393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 939393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * <p>By default the flag is set on SDK version {@link Build.VERSION_CODES#LOLLIPOP_MR1} or 940393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * greater and cleared on lesser SDK versions. 941393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 942393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @param enabled true if the popup should be attached to the decor frame of its parent window. 943393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 944393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR 945393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale */ 946393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale public void setAttachedInDecor(boolean enabled) { 947393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale mAttachedInDecor = enabled; 948393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale mAttachedInDecorSet = true; 949393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale } 950393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 951393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale /** 9520bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * Allows the popup window to force the flag 9530bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * {@link WindowManager.LayoutParams#FLAG_LAYOUT_INSET_DECOR}, overriding default behavior. 9540bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * This will cause the popup to inset its content to account for system windows overlaying 9550bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * the screen, such as the status bar. 9560bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * 9570bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * <p>This will often be combined with {@link #setLayoutInScreenEnabled(boolean)}. 9580bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * 9590bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * @param enabled true if the popup's views should inset content to account for system windows, 9600bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * the way that decor views behave for full-screen windows. 9610bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * @hide 9620bd1d0a15294345bf88b20df28466907f982cec7Adam Powell */ 9630bd1d0a15294345bf88b20df28466907f982cec7Adam Powell public void setLayoutInsetDecor(boolean enabled) { 9640bd1d0a15294345bf88b20df28466907f982cec7Adam Powell mLayoutInsetDecor = enabled; 9650bd1d0a15294345bf88b20df28466907f982cec7Adam Powell } 9660bd1d0a15294345bf88b20df28466907f982cec7Adam Powell 9674753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme /** @hide */ 9684753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme protected final boolean isLayoutInsetDecor() { 9694753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme return mLayoutInsetDecor; 9704753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme } 9714753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme 9720bd1d0a15294345bf88b20df28466907f982cec7Adam Powell /** 97380ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette * Set the layout type for this window. 97480ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette * <p> 97580ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette * See {@link WindowManager.LayoutParams#type} for possible values. 976574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell * 977574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell * @param layoutType Layout type for this window. 97836344a90c226c90243e4e02bfb13589e120431ddChris Banes * 97936344a90c226c90243e4e02bfb13589e120431ddChris Banes * @see WindowManager.LayoutParams#type 980574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell */ 981574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell public void setWindowLayoutType(int layoutType) { 982574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell mWindowLayoutType = layoutType; 983574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell } 984574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell 985574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell /** 98636344a90c226c90243e4e02bfb13589e120431ddChris Banes * Returns the layout type for this window. 98736344a90c226c90243e4e02bfb13589e120431ddChris Banes * 98836344a90c226c90243e4e02bfb13589e120431ddChris Banes * @see #setWindowLayoutType(int) 989574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell */ 990574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell public int getWindowLayoutType() { 991574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell return mWindowLayoutType; 992574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell } 993574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell 994574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell /** 995e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell * Set whether this window is touch modal or if outside touches will be sent to 996e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell * other windows behind it. 997e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell * @hide 998e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell */ 999e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell public void setTouchModal(boolean touchModal) { 1000e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell mNotTouchModal = !touchModal; 1001e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell } 1002e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell 1003e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell /** 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Change the width and height measure specs that are given to the 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window manager by the popup. By default these are 0, meaning that 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the current width or height is requested as an explicit size from 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the window manager. You can supply 10085435a30ae552391f14009c4459731ae149675b18Alan Viverette * {@link ViewGroup.LayoutParams#WRAP_CONTENT} or 1009980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * {@link ViewGroup.LayoutParams#MATCH_PARENT} to have that measure 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * spec supplied instead, replacing the absolute width and height that 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * has been set in the popup.</p> 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown.</p> 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param widthSpec an explicit width measure spec mode, either 10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link ViewGroup.LayoutParams#WRAP_CONTENT}, 1018980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * {@link ViewGroup.LayoutParams#MATCH_PARENT}, or 0 to use the absolute 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * width. 10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param heightSpec an explicit height measure spec mode, either 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link ViewGroup.LayoutParams#WRAP_CONTENT}, 1022980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * {@link ViewGroup.LayoutParams#MATCH_PARENT}, or 0 to use the absolute 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * height. 1024259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * 1025259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @deprecated Use {@link #setWidth(int)} and {@link #setHeight(int)}. 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1027259c2840691a79634ffd8f63291ec21c21819542Alan Viverette @Deprecated 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setWindowLayoutMode(int widthSpec, int heightSpec) { 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWidthMode = widthSpec; 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeightMode = heightSpec; 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10325435a30ae552391f14009c4459731ae149675b18Alan Viverette 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1034c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * Returns the popup's requested height. May be a layout constant such as 1035c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * {@link LayoutParams#WRAP_CONTENT} or {@link LayoutParams#MATCH_PARENT}. 1036c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * <p> 1037c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * The actual size of the popup may depend on other factors such as 1038c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * clipping and window layout. 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1040c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @return the popup height in pixels or a layout constant 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setHeight(int) 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getHeight() { 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mHeight; 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1048c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * Sets the popup's requested height. May be a layout constant such as 1049c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * {@link LayoutParams#WRAP_CONTENT} or {@link LayoutParams#MATCH_PARENT}. 1050c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * <p> 1051c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * The actual size of the popup may depend on other factors such as 1052c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * clipping and window layout. 1053259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1054259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * If the popup is showing, calling this method will take effect the next 1055259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * time the popup is shown. 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1057c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param height the popup height in pixels or a layout constant 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getHeight() 10595435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setHeight(int height) { 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeight = height; 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1066c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * Returns the popup's requested width. May be a layout constant such as 1067c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * {@link LayoutParams#WRAP_CONTENT} or {@link LayoutParams#MATCH_PARENT}. 1068c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * <p> 1069c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * The actual size of the popup may depend on other factors such as 1070c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * clipping and window layout. 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1072c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @return the popup width in pixels or a layout constant 10735435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #setWidth(int) 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getWidth() { 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mWidth; 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1080c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * Sets the popup's requested width. May be a layout constant such as 1081c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * {@link LayoutParams#WRAP_CONTENT} or {@link LayoutParams#MATCH_PARENT}. 1082c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * <p> 1083c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * The actual size of the popup may depend on other factors such as 1084c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * clipping and window layout. 1085259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1086259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * If the popup is showing, calling this method will take effect the next 1087259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * time the popup is shown. 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1089c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param width the popup width in pixels or a layout constant 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getWidth() 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isShowing() 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setWidth(int width) { 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWidth = width; 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 109875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Sets whether the popup window should overlap its anchor view when 109975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * displayed as a drop-down. 110075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * <p> 110175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If the popup is showing, calling this method will take effect only 110275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * the next time the popup is shown. 110375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * 110475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @param overlapAnchor Whether the popup should overlap its anchor. 110575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * 110675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @see #getOverlapAnchor() 110775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @see #isShowing() 110875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette */ 110975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette public void setOverlapAnchor(boolean overlapAnchor) { 111075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette mOverlapAnchor = overlapAnchor; 111175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette } 111275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette 111375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette /** 111475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Returns whether the popup window should overlap its anchor view when 111575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * displayed as a drop-down. 111675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * 111775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @return Whether the popup should overlap its anchor. 111875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * 111975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @see #setOverlapAnchor(boolean) 112075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette */ 112175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette public boolean getOverlapAnchor() { 112275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette return mOverlapAnchor; 112375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette } 112475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette 112575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette /** 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicate whether this popup window is showing on screen.</p> 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is showing, false otherwise 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isShowing() { 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mIsShowing; 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11344753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme /** @hide */ 11354753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme protected final void setShowing(boolean isShowing) { 11364753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme mIsShowing = isShowing; 11374753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme } 11384753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme 11394753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme /** @hide */ 11404753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme protected final void setDropDown(boolean isDropDown) { 11414753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme mIsDropdown = isDropDown; 11424753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme } 11434753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme 11444753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme /** @hide */ 11454753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme protected final void setTransitioningToDismiss(boolean transitioningToDismiss) { 11464753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme mIsTransitioningToDismiss = transitioningToDismiss; 11474753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme } 11484753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme 11494753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme /** @hide */ 11504753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme protected final boolean isTransitioningToDismiss() { 11514753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme return mIsTransitioningToDismiss; 11524753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme } 11534753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme 11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Display the content view in a popup window at the specified location. If the popup window 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cannot fit on screen, it will be clipped. See {@link android.view.WindowManager.LayoutParams} 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for more information on how gravity and the x and y parameters are related. Specifying 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a gravity of {@link android.view.Gravity#NO_GRAVITY} is similar to specifying 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>Gravity.LEFT | Gravity.TOP</code>. 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p> 11625435a30ae552391f14009c4459731ae149675b18Alan Viverette * 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param parent a parent view to get the {@link android.view.View#getWindowToken()} token from 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param gravity the gravity which controls the placement of the popup window 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x the popup's x location offset 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y the popup's y location offset 11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void showAtLocation(View parent, int gravity, int x, int y) { 116950db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal mParentRootView = new WeakReference<>(parent.getRootView()); 11708ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell showAtLocation(parent.getWindowToken(), gravity, x, y); 11718ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell } 11728ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell 11738ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell /** 11748ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * Display the content view in a popup window at the specified location. 11758ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * 11768ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @param token Window token to use for creating the new window 11778ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @param gravity the gravity which controls the placement of the popup window 11788ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @param x the popup's x location offset 11798ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @param y the popup's y location offset 11808ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * 11818ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @hide Internal use only. Applications should use 11828ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * {@link #showAtLocation(View, int, int, int)} instead. 11838ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell */ 11848ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell public void showAtLocation(IBinder token, int gravity, int x, int y) { 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isShowing() || mContentView == null) { 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1189e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette TransitionManager.endTransitions(mDecorView); 1190e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1191f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette detachFromAnchor(); 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsShowing = true; 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsDropdown = false; 1195085160612d9066e23c96a6cac15eb3a51481fdafRobert Carr mGravity = gravity; 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1197e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final WindowManager.LayoutParams p = createPopupLayoutParams(token); 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project preparePopup(p); 1199e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.x = x; 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.y = y; 1202e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokePopup(p); 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 120775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Display the content view in a popup window anchored to the bottom-left 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * corner of the anchor view. If there is not enough room on screen to show 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the popup in its entirety, this method tries to find a parent scroll 121075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * view to scroll. If no parent scroll view can be scrolled, the 121175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * bottom-left corner of the popup is pinned at the top left corner of the 121275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * anchor view. 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the view on which to pin the popup window 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #dismiss() 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void showAsDropDown(View anchor) { 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project showAsDropDown(anchor, 0, 0); 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 122375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Display the content view in a popup window anchored to the bottom-left 12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * corner of the anchor view offset by the specified x and y coordinates. 122575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If there is not enough room on screen to show the popup in its entirety, 122675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * this method tries to find a parent scroll view to scroll. If no parent 122775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * scroll view can be scrolled, the bottom-left corner of the popup is 122875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * pinned at the top left corner of the anchor view. 122975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * <p> 123075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If the view later scrolls to move <code>anchor</code> to a different 123175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * location, the popup will be moved correspondingly. 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the view on which to pin the popup window 123454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param xoff A horizontal offset from the anchor in pixels 123554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param yoff A vertical offset from the anchor in pixels 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #dismiss() 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void showAsDropDown(View anchor, int xoff, int yoff) { 124054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell showAsDropDown(anchor, xoff, yoff, DEFAULT_ANCHORED_GRAVITY); 124154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell } 124254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 124354c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell /** 124475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Displays the content view in a popup window anchored to the corner of 124575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * another view. The window is positioned according to the specified 124675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * gravity and offset by the specified x and y coordinates. 124775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * <p> 124875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If there is not enough room on screen to show the popup in its entirety, 124975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * this method tries to find a parent scroll view to scroll. If no parent 125075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * view can be scrolled, the specified vertical gravity will be ignored and 125175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * the popup will anchor itself such that it is visible. 125275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * <p> 125375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If the view later scrolls to move <code>anchor</code> to a different 125475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * location, the popup will be moved correspondingly. 125554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * 125654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param anchor the view on which to pin the popup window 125754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param xoff A horizontal offset from the anchor in pixels 125854c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param yoff A vertical offset from the anchor in pixels 125954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param gravity Alignment of the popup relative to the anchor 126054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * 126154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @see #dismiss() 126254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell */ 126354c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell public void showAsDropDown(View anchor, int xoff, int yoff, int gravity) { 12644753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme if (isShowing() || !hasContentView()) { 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1268e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette TransitionManager.endTransitions(mDecorView); 1269e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1270f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette attachToAnchor(anchor, xoff, yoff, gravity); 12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsShowing = true; 12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsDropdown = true; 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1275b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev final WindowManager.LayoutParams p = 1276b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev createPopupLayoutParams(anchor.getApplicationWindowToken()); 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project preparePopup(p); 12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1279f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final boolean aboveAnchor = findDropDownPosition(anchor, p, xoff, yoff, 128050df07a1add902da01018756c213169e4e126a28Alan Viverette p.width, p.height, gravity, mAllowScrollingAnchorParent); 1281e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette updateAboveAnchor(aboveAnchor); 1282396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver p.accessibilityIdOfAnchor = (anchor != null) ? anchor.getAccessibilityViewId() : -1; 12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokePopup(p); 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12874753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme /** @hide */ 12884753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme protected final void updateAboveAnchor(boolean aboveAnchor) { 12893e141685003939a9addce21ba2492ea3a8aebee6Romain Guy if (aboveAnchor != mAboveAnchor) { 12903e141685003939a9addce21ba2492ea3a8aebee6Romain Guy mAboveAnchor = aboveAnchor; 12913e141685003939a9addce21ba2492ea3a8aebee6Romain Guy 1292697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette if (mBackground != null && mBackgroundView != null) { 1293697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette // If the background drawable provided was a StateListDrawable 1294697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette // with above-anchor and below-anchor states, use those. 1295697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette // Otherwise, rely on refreshDrawableState to do the job. 12963e141685003939a9addce21ba2492ea3a8aebee6Romain Guy if (mAboveAnchorBackgroundDrawable != null) { 12973e141685003939a9addce21ba2492ea3a8aebee6Romain Guy if (mAboveAnchor) { 1298697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView.setBackground(mAboveAnchorBackgroundDrawable); 12993e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } else { 1300697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView.setBackground(mBelowAnchorBackgroundDrawable); 13013e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 13023e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } else { 1303697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView.refreshDrawableState(); 13043e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 13053e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 13063e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 13073e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 13083e141685003939a9addce21ba2492ea3a8aebee6Romain Guy 13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Indicates whether the popup is showing above (the y coordinate of the popup's bottom 13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is less than the y coordinate of the anchor) or below the anchor view (the y coordinate 13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the popup is greater than y coordinate of the anchor's bottom). 13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The value returned 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by this method is meaningful only after {@link #showAsDropDown(android.view.View)} 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or {@link #showAsDropDown(android.view.View, int, int)} was invoked. 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return True if this popup is showing above the anchor view, false otherwise. 13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isAboveAnchor() { 13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAboveAnchor; 13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1325e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette * Prepare the popup by embedding it into a new ViewGroup if the background 1326e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette * drawable is not null. If embedding is required, the layout parameters' 1327e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette * height is modified to take into account the background's padding. 13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param p the layout parameters of the popup's content view 13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void preparePopup(WindowManager.LayoutParams p) { 1332448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy if (mContentView == null || mContext == null || mWindowManager == null) { 1333448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy throw new IllegalStateException("You must specify a valid content view by " 1334448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy + "calling setContentView() before attempting to show the popup."); 1335448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy } 1336448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy 13378fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // The old decor view may be transitioning out. Make sure it finishes 13388fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // and cleans up before we try to create another one. 13398fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (mDecorView != null) { 13408fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mDecorView.cancelTransitions(); 13418fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 13428fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 13435435a30ae552391f14009c4459731ae149675b18Alan Viverette // When a background is available, we embed the content view within 13445435a30ae552391f14009c4459731ae149675b18Alan Viverette // another view that owns the background drawable. 13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBackground != null) { 1346697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView = createBackgroundView(mContentView); 1347697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView.setBackground(mBackground); 13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1349697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView = mContentView; 13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1351ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette 1352697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mDecorView = createDecorView(mBackgroundView); 13535435a30ae552391f14009c4459731ae149675b18Alan Viverette 13545435a30ae552391f14009c4459731ae149675b18Alan Viverette // The background owner should be elevated so that it casts a shadow. 1355697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView.setElevation(mElevation); 13565435a30ae552391f14009c4459731ae149675b18Alan Viverette 13575435a30ae552391f14009c4459731ae149675b18Alan Viverette // We may wrap that in another view, so we'll need to manually specify 13585435a30ae552391f14009c4459731ae149675b18Alan Viverette // the surface insets. 1359246c209e4fe704c0745224be0ab05225e8431d11Wale Ogunwale p.setSurfaceInsets(mBackgroundView, true /*manual*/, true /*preservePrevious*/); 13605435a30ae552391f14009c4459731ae149675b18Alan Viverette 1361b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio mPopupViewInitialLayoutDirectionInherited = 13625435a30ae552391f14009c4459731ae149675b18Alan Viverette (mContentView.getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT); 13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13665435a30ae552391f14009c4459731ae149675b18Alan Viverette * Wraps a content view in a PopupViewContainer. 13675435a30ae552391f14009c4459731ae149675b18Alan Viverette * 13685435a30ae552391f14009c4459731ae149675b18Alan Viverette * @param contentView the content view to wrap 13695435a30ae552391f14009c4459731ae149675b18Alan Viverette * @return a PopupViewContainer that wraps the content view 13705435a30ae552391f14009c4459731ae149675b18Alan Viverette */ 13715435a30ae552391f14009c4459731ae149675b18Alan Viverette private PopupBackgroundView createBackgroundView(View contentView) { 13725435a30ae552391f14009c4459731ae149675b18Alan Viverette final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams(); 13735435a30ae552391f14009c4459731ae149675b18Alan Viverette final int height; 13742665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr if (layoutParams != null && layoutParams.height == WRAP_CONTENT) { 13752665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr height = WRAP_CONTENT; 13765435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 13772665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr height = MATCH_PARENT; 13785435a30ae552391f14009c4459731ae149675b18Alan Viverette } 13795435a30ae552391f14009c4459731ae149675b18Alan Viverette 13805435a30ae552391f14009c4459731ae149675b18Alan Viverette final PopupBackgroundView backgroundView = new PopupBackgroundView(mContext); 13815435a30ae552391f14009c4459731ae149675b18Alan Viverette final PopupBackgroundView.LayoutParams listParams = new PopupBackgroundView.LayoutParams( 13822665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr MATCH_PARENT, height); 13835435a30ae552391f14009c4459731ae149675b18Alan Viverette backgroundView.addView(contentView, listParams); 13845435a30ae552391f14009c4459731ae149675b18Alan Viverette 13855435a30ae552391f14009c4459731ae149675b18Alan Viverette return backgroundView; 13865435a30ae552391f14009c4459731ae149675b18Alan Viverette } 13875435a30ae552391f14009c4459731ae149675b18Alan Viverette 13885435a30ae552391f14009c4459731ae149675b18Alan Viverette /** 13895435a30ae552391f14009c4459731ae149675b18Alan Viverette * Wraps a content view in a FrameLayout. 13905435a30ae552391f14009c4459731ae149675b18Alan Viverette * 13915435a30ae552391f14009c4459731ae149675b18Alan Viverette * @param contentView the content view to wrap 13925435a30ae552391f14009c4459731ae149675b18Alan Viverette * @return a FrameLayout that wraps the content view 13935435a30ae552391f14009c4459731ae149675b18Alan Viverette */ 13945435a30ae552391f14009c4459731ae149675b18Alan Viverette private PopupDecorView createDecorView(View contentView) { 13955435a30ae552391f14009c4459731ae149675b18Alan Viverette final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams(); 13965435a30ae552391f14009c4459731ae149675b18Alan Viverette final int height; 13972665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr if (layoutParams != null && layoutParams.height == WRAP_CONTENT) { 13982665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr height = WRAP_CONTENT; 13995435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 14002665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr height = MATCH_PARENT; 14015435a30ae552391f14009c4459731ae149675b18Alan Viverette } 14025435a30ae552391f14009c4459731ae149675b18Alan Viverette 14035435a30ae552391f14009c4459731ae149675b18Alan Viverette final PopupDecorView decorView = new PopupDecorView(mContext); 14042665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr decorView.addView(contentView, MATCH_PARENT, height); 14055435a30ae552391f14009c4459731ae149675b18Alan Viverette decorView.setClipChildren(false); 14065435a30ae552391f14009c4459731ae149675b18Alan Viverette decorView.setClipToPadding(false); 14075435a30ae552391f14009c4459731ae149675b18Alan Viverette 14085435a30ae552391f14009c4459731ae149675b18Alan Viverette return decorView; 14095435a30ae552391f14009c4459731ae149675b18Alan Viverette } 14105435a30ae552391f14009c4459731ae149675b18Alan Viverette 14115435a30ae552391f14009c4459731ae149675b18Alan Viverette /** 14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Invoke the popup window by adding the content view to the window 14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * manager.</p> 14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The content view must be non-null when this method is invoked.</p> 14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param p the layout parameters of the popup's content view 14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void invokePopup(WindowManager.LayoutParams p) { 14200c0b768e1514280812321854db6dfba723c3d169Romain Guy if (mContext != null) { 14210c0b768e1514280812321854db6dfba723c3d169Romain Guy p.packageName = mContext.getPackageName(); 14220c0b768e1514280812321854db6dfba723c3d169Romain Guy } 14235435a30ae552391f14009c4459731ae149675b18Alan Viverette 14248fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final PopupDecorView decorView = mDecorView; 14258fd949e680c15d397084430d4907c16cedfacddaAlan Viverette decorView.setFitsSystemWindows(mLayoutInsetDecor); 14265435a30ae552391f14009c4459731ae149675b18Alan Viverette 14278fd949e680c15d397084430d4907c16cedfacddaAlan Viverette setLayoutDirectionFromAnchor(); 14285435a30ae552391f14009c4459731ae149675b18Alan Viverette 14298fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mWindowManager.addView(decorView, p); 143095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 143195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette if (mEnterTransition != null) { 143295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette decorView.requestEnterTransition(mEnterTransition); 143395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette } 14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1436b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio private void setLayoutDirectionFromAnchor() { 1437b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio if (mAnchor != null) { 1438b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio View anchor = mAnchor.get(); 1439b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio if (anchor != null && mPopupViewInitialLayoutDirectionInherited) { 14405435a30ae552391f14009c4459731ae149675b18Alan Viverette mDecorView.setLayoutDirection(anchor.getLayoutDirection()); 1441b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio } 1442b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio } 1443b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio } 1444b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio 1445489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr private int computeGravity() { 1446085160612d9066e23c96a6cac15eb3a51481fdafRobert Carr int gravity = mGravity == Gravity.NO_GRAVITY ? Gravity.START | Gravity.TOP : mGravity; 1447085160612d9066e23c96a6cac15eb3a51481fdafRobert Carr if (mIsDropdown && (mClipToScreen || mClippingEnabled)) { 14489705fa0602290b56edc81f64bfcba38f159069b1Alan Viverette gravity |= Gravity.DISPLAY_CLIP_VERTICAL; 1449489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr } 1450489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr return gravity; 1451489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr } 1452489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr 14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Generate the layout parameters for the popup window.</p> 14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param token the window token used to bind the popup's window 14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the layout parameters to pass to the window manager 14594753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme * 14604753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme * @hide 14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14624753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme protected final WindowManager.LayoutParams createPopupLayoutParams(IBinder token) { 1463e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final WindowManager.LayoutParams p = new WindowManager.LayoutParams(); 1464e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1465e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // These gravity settings put the view at the top left corner of the 1466e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // screen. The view is then positioned to the appropriate location by 1467e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // setting the x and y offsets to match the anchor's bottom-left 1468e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // corner. 1469489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr p.gravity = computeGravity(); 1470e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.flags = computeFlags(p.flags); 1471e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.type = mWindowLayoutType; 1472e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.token = token; 1473e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.softInputMode = mSoftInputMode; 1474e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.windowAnimations = computeAnimationResource(); 1475e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBackground != null) { 14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.format = mBackground.getOpacity(); 14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.format = PixelFormat.TRANSLUCENT; 14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1481e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1482e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette if (mHeightMode < 0) { 1483e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.height = mLastHeight = mHeightMode; 1484e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } else { 1485e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.height = mLastHeight = mHeight; 1486e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } 1487e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1488e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette if (mWidthMode < 0) { 1489e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.width = mLastWidth = mWidthMode; 1490e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } else { 1491e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.width = mLastWidth = mWidth; 1492e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } 1493e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 14948216eb2221ad5ad6615d3966f43844268756f3c8Wale Ogunwale p.privateFlags = PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH 14958216eb2221ad5ad6615d3966f43844268756f3c8Wale Ogunwale | PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME; 1496a1eb439eee65138280c560f96e2a6896f9c9112cRobert Carr 1497e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // Used for debugging. 14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.setTitle("PopupWindow:" + Integer.toHexString(hashCode())); 14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return p; 15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int computeFlags(int curFlags) { 15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags &= ~( 15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES | 15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | 15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | 15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | 15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | 1510ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM | 1511ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell WindowManager.LayoutParams.FLAG_SPLIT_TOUCH); 15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(mIgnoreCheekPress) { 15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES; 15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mFocusable) { 15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mInputMethodMode == INPUT_METHOD_NEEDED) { 15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mInputMethodMode == INPUT_METHOD_NOT_NEEDED) { 15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mTouchable) { 15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1526c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project if (mOutsideTouchable) { 15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH; 15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1529cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr if (!mClippingEnabled || mClipToScreen) { 15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; 15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 153246e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown if (isSplitTouchEnabled()) { 153301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown curFlags |= WindowManager.LayoutParams.FLAG_SPLIT_TOUCH; 153401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown } 1535ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell if (mLayoutInScreen) { 1536ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; 1537ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell } 15380bd1d0a15294345bf88b20df28466907f982cec7Adam Powell if (mLayoutInsetDecor) { 15390bd1d0a15294345bf88b20df28466907f982cec7Adam Powell curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; 15400bd1d0a15294345bf88b20df28466907f982cec7Adam Powell } 1541e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell if (mNotTouchModal) { 1542e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; 1543e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell } 1544393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale if (mAttachedInDecor) { 15454753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR; 1546393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale } 15479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return curFlags; 15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1549393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 15509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int computeAnimationResource() { 15515435a30ae552391f14009c4459731ae149675b18Alan Viverette if (mAnimationStyle == ANIMATION_STYLE_DEFAULT) { 15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsDropdown) { 15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAboveAnchor 15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ? com.android.internal.R.style.Animation_DropDownUp 15559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : com.android.internal.R.style.Animation_DropDownDown; 15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAnimationStyle; 15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1561560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1563560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * Positions the popup window on screen. When the popup window is too tall 1564560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * to fit under the anchor, a parent scroll view is seeked and scrolled up 1565560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * to reclaim space. If scrolling is not possible or not enough, the popup 1566560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * window gets moved on top of the anchor. 1567560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * <p> 1568f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette * The results of positioning are placed in {@code outParams}. 15695435a30ae552391f14009c4459731ae149675b18Alan Viverette * 15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the view on which the popup window must be anchored 1571f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette * @param outParams the layout parameters used to display the drop down 15729125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette * @param xOffset absolute horizontal offset from the left of the anchor 15736acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette * @param yOffset absolute vertical offset from the top of the anchor 1574560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * @param gravity horizontal gravity specifying popup alignment 157550df07a1add902da01018756c213169e4e126a28Alan Viverette * @param allowScroll whether the anchor view's parent may be scrolled 157650df07a1add902da01018756c213169e4e126a28Alan Viverette * when the popup window doesn't fit on screen 15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is translated upwards to fit on screen 15784753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme * 15794753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme * @hide 15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15814753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme protected final boolean findDropDownPosition(View anchor, WindowManager.LayoutParams outParams, 158250df07a1add902da01018756c213169e4e126a28Alan Viverette int xOffset, int yOffset, int width, int height, int gravity, boolean allowScroll) { 158362e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell final int anchorHeight = anchor.getHeight(); 1584560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int anchorWidth = anchor.getWidth(); 1585560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette if (mOverlapAnchor) { 1586f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette yOffset -= anchorHeight; 1587560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette } 1588560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 15896acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette // Initially, align to the bottom-left corner of the anchor plus offsets. 1590b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev final int[] appScreenLocation = mTmpAppLocation; 1591b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev final View appRootView = getAppRootView(anchor); 1592b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev appRootView.getLocationOnScreen(appScreenLocation); 1593b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev 1594b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev final int[] screenLocation = mTmpScreenLocation; 1595b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev anchor.getLocationOnScreen(screenLocation); 1596b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev 1597f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int[] drawingLocation = mTmpDrawingLocation; 1598b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev drawingLocation[0] = screenLocation[0] - appScreenLocation[0]; 1599b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev drawingLocation[1] = screenLocation[1] - appScreenLocation[1]; 1600f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette outParams.x = drawingLocation[0] + xOffset; 1601f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette outParams.y = drawingLocation[1] + anchorHeight + yOffset; 160254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 1603f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr final Rect displayFrame = new Rect(); 1604b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev appRootView.getWindowVisibleDisplayFrame(displayFrame); 16052665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr if (width == MATCH_PARENT) { 1606f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr width = displayFrame.right - displayFrame.left; 1607f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr } 16082665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr if (height == MATCH_PARENT) { 1609f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr height = displayFrame.bottom - displayFrame.top; 1610f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr } 1611f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr 1612cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr // Let the window manager know to align the top to y. 16138367c50972ee4fce55ac483441125b8b09af5eaeRobert Carr outParams.gravity = computeGravity(); 1614cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr outParams.width = width; 1615cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr outParams.height = height; 1616cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr 16176acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette // If we need to adjust for gravity RIGHT, align to the bottom-right 16186acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette // corner of the anchor (still accounting for offsets). 1619560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int hgrav = Gravity.getAbsoluteGravity(gravity, anchor.getLayoutDirection()) 1620560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette & Gravity.HORIZONTAL_GRAVITY_MASK; 162154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell if (hgrav == Gravity.RIGHT) { 1622f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette outParams.x -= width - anchorWidth; 162354c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell } 1624560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 16259125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // First, attempt to fit the popup vertically without resizing. 16269125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final boolean fitsVertical = tryFitVertical(outParams, yOffset, height, 16279125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette anchorHeight, drawingLocation[1], screenLocation[1], displayFrame.top, 16289125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette displayFrame.bottom, false); 16299125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16309125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // Next, attempt to fit the popup horizontally without resizing. 16319125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final boolean fitsHorizontal = tryFitHorizontal(outParams, xOffset, width, 16329125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette anchorWidth, drawingLocation[0], screenLocation[0], displayFrame.left, 16339125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette displayFrame.right, false); 16349125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16359125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // If the popup still doesn't fit, attempt to scroll the parent. 16369125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (!fitsVertical || !fitsHorizontal) { 16379125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int scrollX = anchor.getScrollX(); 16389125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int scrollY = anchor.getScrollY(); 16399125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final Rect r = new Rect(scrollX, scrollY, scrollX + width + xOffset, 16409125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette scrollY + height + anchorHeight + yOffset); 164150df07a1add902da01018756c213169e4e126a28Alan Viverette if (allowScroll && anchor.requestRectangleOnScreen(r, true)) { 16429125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // Reset for the new anchor position. 1643b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev anchor.getLocationOnScreen(screenLocation); 1644b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev drawingLocation[0] = screenLocation[0] - appScreenLocation[0]; 1645b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev drawingLocation[1] = screenLocation[1] - appScreenLocation[1]; 16469125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.x = drawingLocation[0] + xOffset; 16479125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.y = drawingLocation[1] + anchorHeight + yOffset; 16489125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16499125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // Preserve the gravity adjustment. 16509125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (hgrav == Gravity.RIGHT) { 16519125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.x -= width - anchorWidth; 16529125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 1653b7c1b20c8a5a4d4378ae91b4a1f12a34100df452Adam Powell } 16543e141685003939a9addce21ba2492ea3a8aebee6Romain Guy 16559125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // Try to fit the popup again and allowing resizing. 16569125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette tryFitVertical(outParams, yOffset, height, anchorHeight, drawingLocation[1], 16579125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette screenLocation[1], displayFrame.top, displayFrame.bottom, mClipToScreen); 16589125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette tryFitHorizontal(outParams, xOffset, width, anchorWidth, drawingLocation[0], 16599125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette screenLocation[0], displayFrame.left, displayFrame.right, mClipToScreen); 16609125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 166154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 16629125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // Return whether the popup's top edge is above the anchor's top edge. 16639125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return outParams.y < drawingLocation[1]; 16649125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 1665560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 16669125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette private boolean tryFitVertical(@NonNull LayoutParams outParams, int yOffset, int height, 16679125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette int anchorHeight, int drawingLocationY, int screenLocationY, int displayFrameTop, 16689125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette int displayFrameBottom, boolean allowResize) { 166955f0a99076477b77e017454e4356d908c43c2d22Alan Viverette final int winOffsetY = screenLocationY - drawingLocationY; 16703b105d92a5913777a8a89bdce8647da5e27267b7Vladislav Kaznacheev final int anchorTopInScreen = outParams.y + winOffsetY; 16713b105d92a5913777a8a89bdce8647da5e27267b7Vladislav Kaznacheev final int spaceBelow = displayFrameBottom - anchorTopInScreen; 16723b105d92a5913777a8a89bdce8647da5e27267b7Vladislav Kaznacheev if (anchorTopInScreen >= 0 && height <= spaceBelow) { 16739125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return true; 16749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16763b105d92a5913777a8a89bdce8647da5e27267b7Vladislav Kaznacheev final int spaceAbove = anchorTopInScreen - anchorHeight - displayFrameTop; 16779125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (height <= spaceAbove) { 16789125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // Move everything up. 16799125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (mOverlapAnchor) { 16803b105d92a5913777a8a89bdce8647da5e27267b7Vladislav Kaznacheev yOffset += anchorHeight; 168156c2d337e02a275397fc9d0460dca90977f199acAdam Powell } 16829125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.y = drawingLocationY - height + yOffset; 16839125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16849125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return true; 16859125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 1686560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 16879125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (positionInDisplayVertical(outParams, height, drawingLocationY, screenLocationY, 16889125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette displayFrameTop, displayFrameBottom, allowResize)) { 16899125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return true; 16909125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 1691f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette 16929125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return false; 16939125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 169456c2d337e02a275397fc9d0460dca90977f199acAdam Powell 16959125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette private boolean positionInDisplayVertical(@NonNull LayoutParams outParams, int height, 16969125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette int drawingLocationY, int screenLocationY, int displayFrameTop, int displayFrameBottom, 16979125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette boolean canResize) { 16989125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette boolean fitsInDisplay = true; 16996acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette 17009125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int winOffsetY = screenLocationY - drawingLocationY; 17019125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.y += winOffsetY; 17029125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.height = height; 17039125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 17049125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int bottom = outParams.y + height; 17059125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (bottom > displayFrameBottom) { 17069125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // The popup is too far down, move it back in. 17079125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.y -= bottom - displayFrameBottom; 17089125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 17096acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette 17109125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (outParams.y < displayFrameTop) { 17119125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // The popup is too far up, move it back in and clip if 17129125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // it's still too large. 17139125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.y = displayFrameTop; 17149125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 17159125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int displayFrameHeight = displayFrameBottom - displayFrameTop; 17169125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (canResize && height > displayFrameHeight) { 17179125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.height = displayFrameHeight; 17189125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } else { 17199125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette fitsInDisplay = false; 17205f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell } 17219125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 17229125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 17239125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.y -= winOffsetY; 1724f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette 17259125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return fitsInDisplay; 17269125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 17279125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 17289125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette private boolean tryFitHorizontal(@NonNull LayoutParams outParams, int xOffset, int width, 17299125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette int anchorWidth, int drawingLocationX, int screenLocationX, int displayFrameLeft, 17309125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette int displayFrameRight, boolean allowResize) { 173155f0a99076477b77e017454e4356d908c43c2d22Alan Viverette final int winOffsetX = screenLocationX - drawingLocationX; 173255f0a99076477b77e017454e4356d908c43c2d22Alan Viverette final int anchorLeftInScreen = outParams.x + winOffsetX; 17339125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int spaceRight = displayFrameRight - anchorLeftInScreen; 173455f0a99076477b77e017454e4356d908c43c2d22Alan Viverette if (anchorLeftInScreen >= 0 && width <= spaceRight) { 17359125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return true; 173656c2d337e02a275397fc9d0460dca90977f199acAdam Powell } 173756c2d337e02a275397fc9d0460dca90977f199acAdam Powell 17389125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (positionInDisplayHorizontal(outParams, width, drawingLocationX, screenLocationX, 17399125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette displayFrameLeft, displayFrameRight, allowResize)) { 17409125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return true; 17419125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 17429125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 17439125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return false; 17449125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 17459125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 17469125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette private boolean positionInDisplayHorizontal(@NonNull LayoutParams outParams, int width, 17479125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette int drawingLocationX, int screenLocationX, int displayFrameLeft, int displayFrameRight, 17489125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette boolean canResize) { 17499125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette boolean fitsInDisplay = true; 17509125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 17519125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // Use screen coordinates for comparison against display frame. 17529125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int winOffsetX = screenLocationX - drawingLocationX; 17539125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.x += winOffsetX; 17549125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 17559125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int right = outParams.x + width; 17569125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (right > displayFrameRight) { 17579125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // The popup is too far right, move it back in. 17589125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.x -= right - displayFrameRight; 17599125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 17609125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 17619125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (outParams.x < displayFrameLeft) { 17629125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // The popup is too far left, move it back in and clip if it's 17639125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // still too large. 17649125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.x = displayFrameLeft; 17659125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 17669125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int displayFrameWidth = displayFrameRight - displayFrameLeft; 17679125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (canResize && width > displayFrameWidth) { 17689125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.width = displayFrameWidth; 17699125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } else { 17709125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette fitsInDisplay = false; 17719125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 17729125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 17739125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 17749125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.x -= winOffsetX; 1775560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 17769125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return fitsInDisplay; 17779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17785435a30ae552391f14009c4459731ae149675b18Alan Viverette 17799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 17809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the maximum height that is available for the popup to be 17819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * completely shown. It is recommended that this height be the maximum for 17829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the popup's height, otherwise it is possible that the popup will be 17839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clipped. 17845435a30ae552391f14009c4459731ae149675b18Alan Viverette * 17859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor The view on which the popup window must be anchored. 17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The maximum available height for the popup to be completely 17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * shown. 17889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1789b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette public int getMaxAvailableHeight(@NonNull View anchor) { 17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return getMaxAvailableHeight(anchor, 0); 17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 17949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the maximum height that is available for the popup to be 17959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * completely shown. It is recommended that this height be the maximum for 17969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the popup's height, otherwise it is possible that the popup will be 17979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clipped. 17989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 17999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor The view on which the popup window must be anchored. 18009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param yOffset y offset from the view's bottom edge 18019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The maximum available height for the popup to be completely 18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * shown. 18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1804b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette public int getMaxAvailableHeight(@NonNull View anchor, int yOffset) { 180598acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau return getMaxAvailableHeight(anchor, yOffset, false); 180698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau } 18075435a30ae552391f14009c4459731ae149675b18Alan Viverette 180898acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau /** 180998acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * Returns the maximum height that is available for the popup to be 181098acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * completely shown, optionally ignoring any bottom decorations such as 181198acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * the input method. It is recommended that this height be the maximum for 181298acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * the popup's height, otherwise it is possible that the popup will be 181398acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * clipped. 18145435a30ae552391f14009c4459731ae149675b18Alan Viverette * 181598acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @param anchor The view on which the popup window must be anchored. 181698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @param yOffset y offset from the view's bottom edge 181798acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @param ignoreBottomDecorations if true, the height returned will be 181898acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * all the way to the bottom of the display, ignoring any 181998acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * bottom decorations 182098acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @return The maximum available height for the popup to be completely 182198acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * shown. 182298acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau */ 1823b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette public int getMaxAvailableHeight( 1824b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette @NonNull View anchor, int yOffset, boolean ignoreBottomDecorations) { 1825701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr Rect displayFrame = null; 1826701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr final Rect visibleDisplayFrame = new Rect(); 1827701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr 1828b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev final View appView = getAppRootView(anchor); 1829b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev appView.getWindowVisibleDisplayFrame(visibleDisplayFrame); 18308175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi if (ignoreBottomDecorations) { 1831701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr // In the ignore bottom decorations case we want to 1832701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr // still respect all other decorations so we use the inset visible 1833701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr // frame on the top right and left and take the bottom 1834701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr // value from the full frame. 1835701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr displayFrame = new Rect(); 18368175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi anchor.getWindowDisplayFrame(displayFrame); 1837701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr displayFrame.top = visibleDisplayFrame.top; 1838701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr displayFrame.right = visibleDisplayFrame.right; 1839701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr displayFrame.left = visibleDisplayFrame.left; 18408175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi } else { 1841701d73084d13e3fac62a3ede9c6298abed58f66aRobert Carr displayFrame = visibleDisplayFrame; 18428175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi } 18439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1844f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int[] anchorPos = mTmpDrawingLocation; 18459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anchor.getLocationOnScreen(anchorPos); 18465435a30ae552391f14009c4459731ae149675b18Alan Viverette 18478175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi final int bottomEdge = displayFrame.bottom; 1848ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg 1849ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg final int distanceToBottom; 1850ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg if (mOverlapAnchor) { 1851ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg distanceToBottom = bottomEdge - anchorPos[1] - yOffset; 1852ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg } else { 1853ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset; 1854ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg } 18559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset; 18569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // anchorPos[1] is distance from anchor to top of screen 18589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int returnedHeight = Math.max(distanceToBottom, distanceToTop); 18599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBackground != null) { 18609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBackground.getPadding(mTempRect); 18615435a30ae552391f14009c4459731ae149675b18Alan Viverette returnedHeight -= mTempRect.top + mTempRect.bottom; 18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18635435a30ae552391f14009c4459731ae149675b18Alan Viverette 18649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return returnedHeight; 18659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18665435a30ae552391f14009c4459731ae149675b18Alan Viverette 18679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 18687878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette * Disposes of the popup window. This method can be invoked only after 18697878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette * {@link #showAsDropDown(android.view.View)} has been executed. Failing 18707878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette * that, calling this method will have no effect. 18719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 18725435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #showAsDropDown(android.view.View) 18739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 18749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dismiss() { 18754753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme if (!isShowing() || isTransitioningToDismiss()) { 1876e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette return; 1877e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } 187806f938e8aa56cd89ab0bdb04c8b946392c428dd1Svetoslav Ganov 18798fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final PopupDecorView decorView = mDecorView; 18808fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View contentView = mContentView; 18818fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 18828fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewGroup contentHolder; 18838fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewParent contentParent = contentView.getParent(); 18848fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (contentParent instanceof ViewGroup) { 18858fd949e680c15d397084430d4907c16cedfacddaAlan Viverette contentHolder = ((ViewGroup) contentParent); 18868fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } else { 18878fd949e680c15d397084430d4907c16cedfacddaAlan Viverette contentHolder = null; 18888fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 18898fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 18908fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // Ensure any ongoing or pending transitions are canceled. 18918fd949e680c15d397084430d4907c16cedfacddaAlan Viverette decorView.cancelTransitions(); 18928fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 1893e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette mIsShowing = false; 18948fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mIsTransitioningToDismiss = true; 1895b82d074038f4c8d86e1bd4f3fa4d3780bd4bcba5Craig Mautner 1896634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // This method may be called as part of window detachment, in which 1897634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // case the anchor view (and its root) will still return true from 1898634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // isAttachedToWindow() during execution of this method; however, we 1899634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // can expect the OnAttachStateChangeListener to have been called prior 1900634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // to executing this method, so we can rely on that instead. 190195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final Transition exitTransition = mExitTransition; 1902054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette if (exitTransition != null && decorView.isLaidOut() 1903054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette && (mIsAnchorRootAttached || mAnchorRoot == null)) { 1904dbd299de2a07a2a0a490d4f37cf92870bf87d6c1Yohei Yukawa // The decor view is non-interactive and non-IME-focusable during exit transitions. 190595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final LayoutParams p = (LayoutParams) decorView.getLayoutParams(); 190695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette p.flags |= LayoutParams.FLAG_NOT_TOUCHABLE; 190795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette p.flags |= LayoutParams.FLAG_NOT_FOCUSABLE; 1908dbd299de2a07a2a0a490d4f37cf92870bf87d6c1Yohei Yukawa p.flags &= ~LayoutParams.FLAG_ALT_FOCUSABLE_IM; 190995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette mWindowManager.updateViewLayout(decorView, p); 191095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 1911054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette final View anchorRoot = mAnchorRoot != null ? mAnchorRoot.get() : null; 1912054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette final Rect epicenter = getTransitionEpicenter(); 1913054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette 1914634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // Once we start dismissing the decor view, all state (including 1915634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // the anchor root) needs to be moved to the decor view since we 1916634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // may open another popup while it's busy exiting. 1917054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette decorView.startExitTransition(exitTransition, anchorRoot, epicenter, 1918634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette new TransitionListenerAdapter() { 1919634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette @Override 1920634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette public void onTransitionEnd(Transition transition) { 19217970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette dismissImmediate(decorView, contentHolder, contentView); 1922634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette } 1923634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette }); 1924e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } else { 19257970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette dismissImmediate(decorView, contentHolder, contentView); 19267878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette } 19277878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette 192895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette // Clears the anchor view. 1929f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette detachFromAnchor(); 19307970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette 19317970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette if (mOnDismissListener != null) { 19327970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette mOnDismissListener.onDismiss(); 19337970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette } 19345435a30ae552391f14009c4459731ae149675b18Alan Viverette } 19355435a30ae552391f14009c4459731ae149675b18Alan Viverette 193691098574f90277128415e9593cce1e495cc51465Alan Viverette /** 193791098574f90277128415e9593cce1e495cc51465Alan Viverette * Returns the window-relative epicenter bounds to be used by enter and 193891098574f90277128415e9593cce1e495cc51465Alan Viverette * exit transitions. 193991098574f90277128415e9593cce1e495cc51465Alan Viverette * <p> 194091098574f90277128415e9593cce1e495cc51465Alan Viverette * <strong>Note:</strong> This is distinct from the rect passed to 194191098574f90277128415e9593cce1e495cc51465Alan Viverette * {@link #setEpicenterBounds(Rect)}, which is anchor-relative. 194291098574f90277128415e9593cce1e495cc51465Alan Viverette * 194391098574f90277128415e9593cce1e495cc51465Alan Viverette * @return the window-relative epicenter bounds to be used by enter and 194491098574f90277128415e9593cce1e495cc51465Alan Viverette * exit transitions 19454753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme * 19464753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme * @hide 194791098574f90277128415e9593cce1e495cc51465Alan Viverette */ 19484753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme protected final Rect getTransitionEpicenter() { 194995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final View anchor = mAnchor != null ? mAnchor.get() : null; 195095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final View decor = mDecorView; 195195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette if (anchor == null || decor == null) { 195295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette return null; 195395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette } 195495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 195595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final int[] anchorLocation = anchor.getLocationOnScreen(); 195695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final int[] popupLocation = mDecorView.getLocationOnScreen(); 195795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 195895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette // Compute the position of the anchor relative to the popup. 195995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final Rect bounds = new Rect(0, 0, anchor.getWidth(), anchor.getHeight()); 196095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette bounds.offset(anchorLocation[0] - popupLocation[0], anchorLocation[1] - popupLocation[1]); 196191098574f90277128415e9593cce1e495cc51465Alan Viverette 196291098574f90277128415e9593cce1e495cc51465Alan Viverette // Use anchor-relative epicenter, if specified. 196391098574f90277128415e9593cce1e495cc51465Alan Viverette if (mEpicenterBounds != null) { 196491098574f90277128415e9593cce1e495cc51465Alan Viverette final int offsetX = bounds.left; 196591098574f90277128415e9593cce1e495cc51465Alan Viverette final int offsetY = bounds.top; 196691098574f90277128415e9593cce1e495cc51465Alan Viverette bounds.set(mEpicenterBounds); 196791098574f90277128415e9593cce1e495cc51465Alan Viverette bounds.offset(offsetX, offsetY); 196891098574f90277128415e9593cce1e495cc51465Alan Viverette } 196991098574f90277128415e9593cce1e495cc51465Alan Viverette 197095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette return bounds; 197195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette } 197295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 19735435a30ae552391f14009c4459731ae149675b18Alan Viverette /** 19745435a30ae552391f14009c4459731ae149675b18Alan Viverette * Removes the popup from the window manager and tears down the supporting 19755435a30ae552391f14009c4459731ae149675b18Alan Viverette * view hierarchy, if necessary. 19765435a30ae552391f14009c4459731ae149675b18Alan Viverette */ 19777970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette private void dismissImmediate(View decorView, ViewGroup contentHolder, View contentView) { 19788fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // If this method gets called and the decor view doesn't have a parent, 19798fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // then it was either never added or was already removed. That should 19808fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // never happen, but it's worth checking to avoid potential crashes. 19818fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (decorView.getParent() != null) { 19828fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mWindowManager.removeViewImmediate(decorView); 1983df4639a0135ea643b493067b3f7cd1e092346c78Alan Viverette } 1984df4639a0135ea643b493067b3f7cd1e092346c78Alan Viverette 19858fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (contentHolder != null) { 19868fd949e680c15d397084430d4907c16cedfacddaAlan Viverette contentHolder.removeView(contentView); 19879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19888fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 19898fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // This needs to stay until after all transitions have ended since we 19908fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // need the reference to cancel transitions in preparePopup(). 19918fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mDecorView = null; 1992697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView = null; 19938fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mIsTransitioningToDismiss = false; 19949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 19979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the listener to be called when the window is dismissed. 19985435a30ae552391f14009c4459731ae149675b18Alan Viverette * 19999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param onDismissListener The listener. 20009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 20019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setOnDismissListener(OnDismissListener onDismissListener) { 20029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnDismissListener = onDismissListener; 20039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20045435a30ae552391f14009c4459731ae149675b18Alan Viverette 20054753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme /** @hide */ 20064753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme protected final OnDismissListener getOnDismissListener() { 20074753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme return mOnDismissListener; 20084753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme } 20094753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme 20109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 20119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Updates the state of the popup window, if it is currently being displayed, 2012259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * from the currently set state. 2013259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 2014259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * This includes: 2015259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <ul> 2016259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setClippingEnabled(boolean)}</li> 2017259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setFocusable(boolean)}</li> 2018259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setIgnoreCheekPress()}</li> 2019259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setInputMethodMode(int)}</li> 2020259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setTouchable(boolean)}</li> 2021259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setAnimationStyle(int)}</li> 2022259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * </ul> 20239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 20249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update() { 20254753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme if (!isShowing() || !hasContentView()) { 20269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 20279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20285435a30ae552391f14009c4459731ae149675b18Alan Viverette 20294753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme final WindowManager.LayoutParams p = getDecorViewLayoutParams(); 20305435a30ae552391f14009c4459731ae149675b18Alan Viverette 20319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean update = false; 20325435a30ae552391f14009c4459731ae149675b18Alan Viverette 20339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newAnim = computeAnimationResource(); 20349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newAnim != p.windowAnimations) { 20359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.windowAnimations = newAnim; 20369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 20379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newFlags = computeFlags(p.flags); 20409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newFlags != p.flags) { 20419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.flags = newFlags; 20429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 20439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2044b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio 2045489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr final int newGravity = computeGravity(); 2046489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr if (newGravity != p.gravity) { 2047489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr p.gravity = newGravity; 2048489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr update = true; 2049489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr } 2050489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr 20519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (update) { 20526f7971701499cc7558e7476ee6bb4e62a39d10fdFelipe Leme update(mAnchor != null ? mAnchor.get() : null, p); 20539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2055d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy 20564753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme /** @hide */ 20574753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme protected void update(View anchor, WindowManager.LayoutParams params) { 20584753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme setLayoutDirectionFromAnchor(); 20594753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme mWindowManager.updateViewLayout(mDecorView, params); 20604753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme } 20614753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme 2062d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy /** 2063259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the dimension of the popup window. 2064259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 2065259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Calling this function also updates the window with the current popup 2066259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * state as described for {@link #update()}. 2067d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy * 2068c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param width the new width in pixels, must be >= 0 or -1 to ignore 2069c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param height the new height in pixels, must be >= 0 or -1 to ignore 2070d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy */ 2071d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy public void update(int width, int height) { 20724753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme final WindowManager.LayoutParams p = getDecorViewLayoutParams(); 2073d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy update(p.x, p.y, width, height, false); 2074d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy } 20755435a30ae552391f14009c4459731ae149675b18Alan Viverette 20769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2077259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 2078259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 2079259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Width and height can be set to -1 to update location only. Calling this 2080259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * function also updates the window with the current popup state as 2081259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * described for {@link #update()}. 20829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 20839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x the new x location 20849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y the new y location 2085c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param width the new width in pixels, must be >= 0 or -1 to ignore 2086c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param height the new height in pixels, must be >= 0 or -1 to ignore 20879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 20889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(int x, int y, int width, int height) { 20899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update(x, y, width, height, false); 20909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2093259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 2094259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 2095259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Width and height can be set to -1 to update location only. Calling this 2096259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * function also updates the window with the current popup state as 2097259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * described for {@link #update()}. 20989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 20999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x the new x location 21009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y the new y location 2101c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param width the new width in pixels, must be >= 0 or -1 to ignore 2102c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param height the new height in pixels, must be >= 0 or -1 to ignore 2103259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param force {@code true} to reposition the window even if the specified 2104259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * position already seems to correspond to the LayoutParams, 2105259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * {@code false} to only reposition if needed 21069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 21079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(int x, int y, int width, int height, boolean force) { 2108259c2840691a79634ffd8f63291ec21c21819542Alan Viverette if (width >= 0) { 21099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastWidth = width; 21109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setWidth(width); 21119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2113259c2840691a79634ffd8f63291ec21c21819542Alan Viverette if (height >= 0) { 21149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastHeight = height; 21159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setHeight(height); 21169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21184753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme if (!isShowing() || !hasContentView()) { 21199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 21209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21224753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme final WindowManager.LayoutParams p = getDecorViewLayoutParams(); 21239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean update = force; 21259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int finalWidth = mWidthMode < 0 ? mWidthMode : mLastWidth; 21279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (width != -1 && p.width != finalWidth) { 21289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.width = mLastWidth = finalWidth; 21299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 21309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int finalHeight = mHeightMode < 0 ? mHeightMode : mLastHeight; 21339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (height != -1 && p.height != finalHeight) { 21349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.height = mLastHeight = finalHeight; 21359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 21369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p.x != x) { 21399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.x = x; 21409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 21419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p.y != y) { 21449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.y = y; 21459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 21469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newAnim = computeAnimationResource(); 21499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newAnim != p.windowAnimations) { 21509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.windowAnimations = newAnim; 21519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 21529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newFlags = computeFlags(p.flags); 21559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newFlags != p.flags) { 21569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.flags = newFlags; 21579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 21589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 215998acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau 2160489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr final int newGravity = computeGravity(); 2161489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr if (newGravity != p.gravity) { 2162489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr p.gravity = newGravity; 2163489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr update = true; 2164489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr } 2165489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr 2166dd23777dfbbe6299f5e07584c69c73ea0835fe46Felipe Leme View anchor = null; 2167dd23777dfbbe6299f5e07584c69c73ea0835fe46Felipe Leme int newAccessibilityIdOfAnchor = -1; 2168dd23777dfbbe6299f5e07584c69c73ea0835fe46Felipe Leme 2169dd23777dfbbe6299f5e07584c69c73ea0835fe46Felipe Leme if (mAnchor != null && mAnchor.get() != null) { 2170dd23777dfbbe6299f5e07584c69c73ea0835fe46Felipe Leme anchor = mAnchor.get(); 2171dd23777dfbbe6299f5e07584c69c73ea0835fe46Felipe Leme newAccessibilityIdOfAnchor = anchor.getAccessibilityViewId(); 2172dd23777dfbbe6299f5e07584c69c73ea0835fe46Felipe Leme } 2173dd23777dfbbe6299f5e07584c69c73ea0835fe46Felipe Leme 2174396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver if (newAccessibilityIdOfAnchor != p.accessibilityIdOfAnchor) { 2175396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver p.accessibilityIdOfAnchor = newAccessibilityIdOfAnchor; 2176396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver update = true; 2177396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver } 2178396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver 21799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (update) { 21804753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme update(anchor, p); 21819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21844753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme /** @hide */ 21854753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme protected boolean hasContentView() { 21864753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme return mContentView != null; 21874753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme } 21884753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme 21894753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme /** @hide */ 21904753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme protected boolean hasDecorView() { 21914753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme return mDecorView != null; 21924753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme } 21934753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme 21944753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme /** @hide */ 21954753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme protected WindowManager.LayoutParams getDecorViewLayoutParams() { 21964753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme return (WindowManager.LayoutParams) mDecorView.getLayoutParams(); 21974753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme } 21984753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme 21999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2200259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 2201259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 2202259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Calling this function also updates the window with the current popup 2203259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * state as described for {@link #update()}. 22049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 22059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the popup's anchor view 2206c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param width the new width in pixels, must be >= 0 or -1 to ignore 2207c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param height the new height in pixels, must be >= 0 or -1 to ignore 22089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 22099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(View anchor, int width, int height) { 2210b91d6d06b824aab4076fb985304a602806429042Alan Viverette update(anchor, false, 0, 0, width, height); 22119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2214259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 2215259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 2216259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Width and height can be set to -1 to update location only. Calling this 2217259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * function also updates the window with the current popup state as 2218259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * described for {@link #update()}. 2219259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 2220259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * If the view later scrolls to move {@code anchor} to a different 2221259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * location, the popup will be moved correspondingly. 22229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 22239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the popup's anchor view 22249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param xoff x offset from the view's left edge 22259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param yoff y offset from the view's bottom edge 2226c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param width the new width in pixels, must be >= 0 or -1 to ignore 2227c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param height the new height in pixels, must be >= 0 or -1 to ignore 22289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 22299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(View anchor, int xoff, int yoff, int width, int height) { 2230b91d6d06b824aab4076fb985304a602806429042Alan Viverette update(anchor, true, xoff, yoff, width, height); 2231105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 2232105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 2233105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private void update(View anchor, boolean updateLocation, int xoff, int yoff, 2234b91d6d06b824aab4076fb985304a602806429042Alan Viverette int width, int height) { 2235105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 22364753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme if (!isShowing() || !hasContentView()) { 22379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 22389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 224075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette final WeakReference<View> oldAnchor = mAnchor; 2241f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int gravity = mAnchoredGravity; 2242f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette 224375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette final boolean needsUpdate = updateLocation && (mAnchorXoff != xoff || mAnchorYoff != yoff); 224481f08086b44a117097960195d2c9072e29644962Gilles Debunne if (oldAnchor == null || oldAnchor.get() != anchor || (needsUpdate && !mIsDropdown)) { 2245f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette attachToAnchor(anchor, xoff, yoff, gravity); 224681f08086b44a117097960195d2c9072e29644962Gilles Debunne } else if (needsUpdate) { 224781f08086b44a117097960195d2c9072e29644962Gilles Debunne // No need to register again if this is a DropDown, showAsDropDown already did. 224881f08086b44a117097960195d2c9072e29644962Gilles Debunne mAnchorXoff = xoff; 224981f08086b44a117097960195d2c9072e29644962Gilles Debunne mAnchorYoff = yoff; 22509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22524753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme final WindowManager.LayoutParams p = getDecorViewLayoutParams(); 2253f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int oldGravity = p.gravity; 2254f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int oldWidth = p.width; 2255f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int oldHeight = p.height; 2256f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int oldX = p.x; 2257f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int oldY = p.y; 2258f95b2d9aabc2e989bd1d665e728922b1c529589aAlan Viverette 2259b91d6d06b824aab4076fb985304a602806429042Alan Viverette // If an explicit width/height has not specified, use the most recent 2260b91d6d06b824aab4076fb985304a602806429042Alan Viverette // explicitly specified value (either from setWidth/Height or update). 2261f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr if (width < 0) { 2262b91d6d06b824aab4076fb985304a602806429042Alan Viverette width = mWidth; 2263b91d6d06b824aab4076fb985304a602806429042Alan Viverette } 2264f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr if (height < 0) { 2265b91d6d06b824aab4076fb985304a602806429042Alan Viverette height = mHeight; 22669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2267105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 2268f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final boolean aboveAnchor = findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff, 226950df07a1add902da01018756c213169e4e126a28Alan Viverette width, height, gravity, mAllowScrollingAnchorParent); 2270f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette updateAboveAnchor(aboveAnchor); 2271b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio 2272f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final boolean paramsChanged = oldGravity != p.gravity || oldX != p.x || oldY != p.y 2273f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette || oldWidth != p.width || oldHeight != p.height; 227450df07a1add902da01018756c213169e4e126a28Alan Viverette 227550df07a1add902da01018756c213169e4e126a28Alan Viverette // If width and mWidth were both < 0 then we have a MATCH_PARENT or 227650df07a1add902da01018756c213169e4e126a28Alan Viverette // WRAP_CONTENT case. findDropDownPosition will have resolved this to 227750df07a1add902da01018756c213169e4e126a28Alan Viverette // absolute values, but we don't want to update mWidth/mHeight to these 227850df07a1add902da01018756c213169e4e126a28Alan Viverette // absolute values. 227950df07a1add902da01018756c213169e4e126a28Alan Viverette final int newWidth = width < 0 ? width : p.width; 228050df07a1add902da01018756c213169e4e126a28Alan Viverette final int newHeight = height < 0 ? height : p.height; 228150df07a1add902da01018756c213169e4e126a28Alan Viverette update(p.x, p.y, newWidth, newHeight, paramsChanged); 22829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 22859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Listener that is called when this popup window is dismissed. 22869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 22879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnDismissListener { 22889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 22899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called when this popup window is dismissed. 22909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 22919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onDismiss(); 22929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22944753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme /** @hide */ 22954753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme protected final void detachFromAnchor() { 2296634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette final View anchor = mAnchor != null ? mAnchor.get() : null; 22979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (anchor != null) { 2298e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final ViewTreeObserver vto = anchor.getViewTreeObserver(); 22999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project vto.removeOnScrollChangedListener(mOnScrollChangedListener); 2300afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev anchor.removeOnAttachStateChangeListener(mOnAnchorDetachedListener); 23019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2302e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 2303634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette final View anchorRoot = mAnchorRoot != null ? mAnchorRoot.get() : null; 2304634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette if (anchorRoot != null) { 2305634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette anchorRoot.removeOnAttachStateChangeListener(mOnAnchorRootDetachedListener); 2306b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev anchorRoot.removeOnLayoutChangeListener(mOnLayoutChangeListener); 2307634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette } 2308634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 23099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnchor = null; 2310634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette mAnchorRoot = null; 2311634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette mIsAnchorRootAttached = false; 23129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23144753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme /** @hide */ 23154753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme protected final void attachToAnchor(View anchor, int xoff, int yoff, int gravity) { 2316f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette detachFromAnchor(); 2317e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 2318e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final ViewTreeObserver vto = anchor.getViewTreeObserver(); 23199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (vto != null) { 23209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project vto.addOnScrollChangedListener(mOnScrollChangedListener); 23219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2322afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev anchor.addOnAttachStateChangeListener(mOnAnchorDetachedListener); 23239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2324634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette final View anchorRoot = anchor.getRootView(); 2325634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette anchorRoot.addOnAttachStateChangeListener(mOnAnchorRootDetachedListener); 2326b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev anchorRoot.addOnLayoutChangeListener(mOnLayoutChangeListener); 2327634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 2328634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette mAnchor = new WeakReference<>(anchor); 2329634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette mAnchorRoot = new WeakReference<>(anchorRoot); 2330634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette mIsAnchorRootAttached = anchorRoot.isAttachedToWindow(); 233150db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal mParentRootView = mAnchorRoot; 2332634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 23339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnchorXoff = xoff; 23349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnchorYoff = yoff; 233554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell mAnchoredGravity = gravity; 23369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2338afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev private void alignToAnchor() { 2339afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev final View anchor = mAnchor != null ? mAnchor.get() : null; 23404753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme if (anchor != null && anchor.isAttachedToWindow() && hasDecorView()) { 23414753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme final WindowManager.LayoutParams p = getDecorViewLayoutParams(); 2342afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev 2343afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev updateAboveAnchor(findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff, 2344afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev p.width, p.height, mAnchoredGravity, false)); 2345afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev update(p.x, p.y, -1, -1, true); 2346afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev } 2347afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev } 2348afaa932ecee84c4d2d0104b22508d3047dd69a14Vladislav Kaznacheev 2349b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev private View getAppRootView(View anchor) { 2350b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev final View appWindowView = WindowManagerGlobal.getInstance().getWindowView( 2351b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev anchor.getApplicationWindowToken()); 2352b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev if (appWindowView != null) { 2353b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev return appWindowView; 2354b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev } 2355b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev return anchor.getRootView(); 2356b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev } 2357b40e61b77c7109c0b4e50167184e9a64cb20018eVladislav Kaznacheev 23585435a30ae552391f14009c4459731ae149675b18Alan Viverette private class PopupDecorView extends FrameLayout { 23597e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette /** Runnable used to clean up listeners after exit transition. */ 23607e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette private Runnable mCleanupAfterExit; 23618fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 23625435a30ae552391f14009c4459731ae149675b18Alan Viverette public PopupDecorView(Context context) { 23635435a30ae552391f14009c4459731ae149675b18Alan Viverette super(context); 23645435a30ae552391f14009c4459731ae149675b18Alan Viverette } 23659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 23679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean dispatchKeyEvent(KeyEvent event) { 23689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { 23694ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson if (getKeyDispatcherState() == null) { 23704ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson return super.dispatchKeyEvent(event); 23714ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson } 23724ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson 23735435a30ae552391f14009c4459731ae149675b18Alan Viverette if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { 23745435a30ae552391f14009c4459731ae149675b18Alan Viverette final KeyEvent.DispatcherState state = getKeyDispatcherState(); 2375b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown if (state != null) { 2376b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown state.startTracking(event, this); 2377b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } 23788d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn return true; 2379b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } else if (event.getAction() == KeyEvent.ACTION_UP) { 23805435a30ae552391f14009c4459731ae149675b18Alan Viverette final KeyEvent.DispatcherState state = getKeyDispatcherState(); 2381b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown if (state != null && state.isTracking(event) && !event.isCanceled()) { 2382b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown dismiss(); 2383b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown return true; 2384b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } 23858d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn } 23868d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn return super.dispatchKeyEvent(event); 23879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 23889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.dispatchKeyEvent(event); 23899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 23939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean dispatchTouchEvent(MotionEvent ev) { 23949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTouchInterceptor != null && mTouchInterceptor.onTouch(this, ev)) { 23959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 23969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.dispatchTouchEvent(ev); 23989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 24019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onTouchEvent(MotionEvent event) { 24029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int x = (int) event.getX(); 24039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int y = (int) event.getY(); 24045435a30ae552391f14009c4459731ae149675b18Alan Viverette 24059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((event.getAction() == MotionEvent.ACTION_DOWN) 24069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && ((x < 0) || (x >= getWidth()) || (y < 0) || (y >= getHeight()))) { 24079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dismiss(); 24089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 24099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (event.getAction() == MotionEvent.ACTION_OUTSIDE) { 24109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dismiss(); 24119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 24129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 24139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.onTouchEvent(event); 24149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24168fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 24178fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 24188fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Requests that an enter transition run after the next layout pass. 24198fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 24208fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void requestEnterTransition(Transition transition) { 24218fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewTreeObserver observer = getViewTreeObserver(); 24228fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (observer != null && transition != null) { 24238fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final Transition enterTransition = transition.clone(); 24248fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 24258fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // Postpone the enter transition after the first layout pass. 24268fd949e680c15d397084430d4907c16cedfacddaAlan Viverette observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 24278fd949e680c15d397084430d4907c16cedfacddaAlan Viverette @Override 24288fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void onGlobalLayout() { 24298fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewTreeObserver observer = getViewTreeObserver(); 24308fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (observer != null) { 24318fd949e680c15d397084430d4907c16cedfacddaAlan Viverette observer.removeOnGlobalLayoutListener(this); 24328fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 24338fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 243491098574f90277128415e9593cce1e495cc51465Alan Viverette final Rect epicenter = getTransitionEpicenter(); 243595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette enterTransition.setEpicenterCallback(new EpicenterCallback() { 243695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette @Override 243795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette public Rect onGetEpicenter(Transition transition) { 243895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette return epicenter; 243995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette } 244095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette }); 24418fd949e680c15d397084430d4907c16cedfacddaAlan Viverette startEnterTransition(enterTransition); 24428fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 24438fd949e680c15d397084430d4907c16cedfacddaAlan Viverette }); 24448fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 24458fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 24468fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 24478fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 24488fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Starts the pending enter transition, if one is set. 24498fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 24508fd949e680c15d397084430d4907c16cedfacddaAlan Viverette private void startEnterTransition(Transition enterTransition) { 24518fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final int count = getChildCount(); 24528fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 24538fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 24548fd949e680c15d397084430d4907c16cedfacddaAlan Viverette enterTransition.addTarget(child); 24558fd949e680c15d397084430d4907c16cedfacddaAlan Viverette child.setVisibility(View.INVISIBLE); 24568fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 24578fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 24588fd949e680c15d397084430d4907c16cedfacddaAlan Viverette TransitionManager.beginDelayedTransition(this, enterTransition); 24598fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 24608fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 24618fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 24628fd949e680c15d397084430d4907c16cedfacddaAlan Viverette child.setVisibility(View.VISIBLE); 24638fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 24648fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 24658fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 24668fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 24678fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Starts an exit transition immediately. 24688fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * <p> 24698fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * <strong>Note:</strong> The transition listener is guaranteed to have 24708fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * its {@code onTransitionEnd} method called even if the transition 24717e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette * never starts. 24728fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 2473054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette public void startExitTransition(@NonNull Transition transition, 2474054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette @Nullable final View anchorRoot, @Nullable final Rect epicenter, 2475054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette @NonNull final TransitionListener listener) { 24768fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (transition == null) { 24778fd949e680c15d397084430d4907c16cedfacddaAlan Viverette return; 24788fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 24798fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 2480634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // The anchor view's window may go away while we're executing our 2481634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // transition, in which case we need to end the transition 2482634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // immediately and execute the listener to remove the popup. 2483054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette if (anchorRoot != null) { 2484054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette anchorRoot.addOnAttachStateChangeListener(mOnAnchorRootDetachedListener); 2485054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette } 2486634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 24877e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette // The cleanup runnable MUST be called even if the transition is 24887e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette // canceled before it starts (and thus can't call onTransitionEnd). 24897e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette mCleanupAfterExit = () -> { 24907e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette listener.onTransitionEnd(transition); 24918fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 24927e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette if (anchorRoot != null) { 24937e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette anchorRoot.removeOnAttachStateChangeListener(mOnAnchorRootDetachedListener); 24948fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 24957e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette 24967e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette // The listener was called. Our job here is done. 24977e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette mCleanupAfterExit = null; 24988fd949e680c15d397084430d4907c16cedfacddaAlan Viverette }; 24998fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 25008fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final Transition exitTransition = transition.clone(); 25017e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette exitTransition.addListener(new TransitionListenerAdapter() { 25027e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette @Override 25037e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette public void onTransitionEnd(Transition t) { 25047e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette t.removeListener(this); 25057e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette 25067e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette // This null check shouldn't be necessary, but it's easier 25077e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette // to check here than it is to test every possible case. 25087e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette if (mCleanupAfterExit != null) { 25097e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette mCleanupAfterExit.run(); 25107e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette } 25117e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette } 25127e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette }); 2513054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette exitTransition.setEpicenterCallback(new EpicenterCallback() { 2514054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette @Override 2515054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette public Rect onGetEpicenter(Transition transition) { 2516054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette return epicenter; 2517054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette } 2518054c172ec699cdcd1fbeb35a6892c53d724e3fe9Alan Viverette }); 25198fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 25208fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final int count = getChildCount(); 25218fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 25228fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 25238fd949e680c15d397084430d4907c16cedfacddaAlan Viverette exitTransition.addTarget(child); 25248fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 25258fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 25268fd949e680c15d397084430d4907c16cedfacddaAlan Viverette TransitionManager.beginDelayedTransition(this, exitTransition); 25278fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 25288fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 25298fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 25308fd949e680c15d397084430d4907c16cedfacddaAlan Viverette child.setVisibility(View.INVISIBLE); 25318fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 25328fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 25338fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 25348fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 25358fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Cancels all pending or current transitions. 25368fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 25378fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void cancelTransitions() { 25388fd949e680c15d397084430d4907c16cedfacddaAlan Viverette TransitionManager.endTransitions(this); 25398fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 25407e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette // If the cleanup runnable is still around, that means the 25417e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette // transition never started. We should run it now to clean up. 25427e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette if (mCleanupAfterExit != null) { 25437e1aeb791e45177440de811363a587f9f95a63bcAlan Viverette mCleanupAfterExit.run(); 25448fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 25458fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 2546634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 2547634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette private final OnAttachStateChangeListener mOnAnchorRootDetachedListener = 2548634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette new OnAttachStateChangeListener() { 2549634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette @Override 2550634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette public void onViewAttachedToWindow(View v) {} 2551634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 2552634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette @Override 2553634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette public void onViewDetachedFromWindow(View v) { 2554634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette v.removeOnAttachStateChangeListener(this); 2555634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 2556634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette TransitionManager.endTransitions(PopupDecorView.this); 2557634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette } 2558634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette }; 255950db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal 256050db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal @Override 256150db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal public void requestKeyboardShortcuts(List<KeyboardShortcutGroup> list, int deviceId) { 256250db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal if (mParentRootView != null) { 256350db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal View parentRoot = mParentRootView.get(); 256450db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal if (parentRoot != null) { 256550db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal parentRoot.requestKeyboardShortcuts(list, deviceId); 256650db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal } 256750db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal } 256850db731b546f98d2ba80ced32e4c1218c338f1a3Peeyush Agarwal } 25695435a30ae552391f14009c4459731ae149675b18Alan Viverette } 25705435a30ae552391f14009c4459731ae149675b18Alan Viverette 25715435a30ae552391f14009c4459731ae149675b18Alan Viverette private class PopupBackgroundView extends FrameLayout { 25725435a30ae552391f14009c4459731ae149675b18Alan Viverette public PopupBackgroundView(Context context) { 25735435a30ae552391f14009c4459731ae149675b18Alan Viverette super(context); 25745435a30ae552391f14009c4459731ae149675b18Alan Viverette } 257575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 257675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov @Override 25775435a30ae552391f14009c4459731ae149675b18Alan Viverette protected int[] onCreateDrawableState(int extraSpace) { 25785435a30ae552391f14009c4459731ae149675b18Alan Viverette if (mAboveAnchor) { 25795435a30ae552391f14009c4459731ae149675b18Alan Viverette final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 25805435a30ae552391f14009c4459731ae149675b18Alan Viverette View.mergeDrawableStates(drawableState, ABOVE_ANCHOR_STATE_SET); 25815435a30ae552391f14009c4459731ae149675b18Alan Viverette return drawableState; 258275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } else { 25835435a30ae552391f14009c4459731ae149675b18Alan Viverette return super.onCreateDrawableState(extraSpace); 258475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 258575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 25869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 25879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2588