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