PopupWindow.java revision 489c39d2db3be43e34c5ac55e09d8c17a5a04688
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport com.android.internal.R; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viveretteimport android.annotation.NonNull; 221e940dc2d165fa6cdedb6945811988502f87ddceAlan Viveretteimport android.annotation.Nullable; 2375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.Context; 2475986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.res.TypedArray; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PixelFormat; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.Drawable; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.StateListDrawable; 2946e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brownimport android.os.Build; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 315435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.Transition; 325435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.Transition.EpicenterCallback; 338fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.transition.Transition.TransitionListener; 348fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.transition.Transition.TransitionListenerAdapter; 355435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.TransitionInflater; 365435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.TransitionManager; 375435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.TransitionSet; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 39c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.Gravity; 40c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.KeyEvent; 41c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.MotionEvent; 42c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.View; 43634a808226cc5d00bd6897bdc881cafe064e37acAlan Viveretteimport android.view.View.OnAttachStateChangeListener; 44a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport android.view.View.OnTouchListener; 45c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.ViewGroup; 468fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.view.ViewParent; 47c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.ViewTreeObserver; 488fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.view.ViewTreeObserver.OnGlobalLayoutListener; 49c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.ViewTreeObserver.OnScrollChangedListener; 50a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport android.view.WindowManager; 51259c2840691a79634ffd8f63291ec21c21819542Alan Viveretteimport android.view.WindowManager.LayoutParams; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 53a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport java.lang.ref.WeakReference; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 551e940dc2d165fa6cdedb6945811988502f87ddceAlan Viveretteimport static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME; 561e940dc2d165fa6cdedb6945811988502f87ddceAlan Viveretteimport static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH; 572665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carrimport static android.view.ViewGroup.LayoutParams.MATCH_PARENT; 582665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carrimport static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; 591e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 611e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <p> 621e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * This class represents a popup window that can be used to display an 631e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * arbitrary view. The popup window is a floating container that appears on top 641e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * of the current activity. 651e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </p> 661e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <a name="Animation"></a> 671e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <h3>Animation</h3> 681e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <p> 691e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * On all versions of Android, popup window enter and exit animations may be 701e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * specified by calling {@link #setAnimationStyle(int)} and passing the 711e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * resource ID for an animation style that defines {@code windowEnterAnimation} 721e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * and {@code windowExitAnimation}. For example, passing 731e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * {@link android.R.style#Animation_Dialog} will give a scale and alpha 741e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * animation. 751e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </br> 761e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * A window animation style may also be specified in the popup window's style 771e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * XML via the {@link android.R.styleable#PopupWindow_popupAnimationStyle popupAnimationStyle} 781e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * attribute. 791e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </p> 801e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * <p> 811e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * Starting with API 23, more complex popup window enter and exit transitions 821e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * may be specified by calling either {@link #setEnterTransition(Transition)} 831e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * or {@link #setExitTransition(Transition)} and passing a {@link Transition}. 841e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </br> 851e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * Popup enter and exit transitions may also be specified in the popup window's 861e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * style XML via the {@link android.R.styleable#PopupWindow_popupEnterTransition popupEnterTransition} 871e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * and {@link android.R.styleable#PopupWindow_popupExitTransition popupExitTransition} 881e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * attributes, respectively. 891e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * </p> 901e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * 911e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_overlapAnchor 921e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupAnimationStyle 931e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupBackground 941e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupElevation 951e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupEnterTransition 961e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupExitTransition 975435a30ae552391f14009c4459731ae149675b18Alan Viverette * 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.widget.AutoCompleteTextView 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.widget.Spinner 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class PopupWindow { 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 103e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * Mode for {@link #setInputMethodMode(int)}: the requirements for the 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * input method should be based on the focusability of the popup. That is 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if it is focusable than it needs to work with the input method, else 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * it doesn't. 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int INPUT_METHOD_FROM_FOCUSABLE = 0; 1095435a30ae552391f14009c4459731ae149675b18Alan Viverette 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 111e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * Mode for {@link #setInputMethodMode(int)}: this popup always needs to 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * work with an input method, regardless of whether it is focusable. This 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * means that it will always be displayed so that the user can also operate 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the input method while it is shown. 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int INPUT_METHOD_NEEDED = 1; 1175435a30ae552391f14009c4459731ae149675b18Alan Viverette 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 119e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * Mode for {@link #setInputMethodMode(int)}: this popup never needs to 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * work with an input method, regardless of whether it is focusable. This 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * means that it will always be displayed to use as much space on the 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * screen as needed, regardless of whether this covers the input method. 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int INPUT_METHOD_NOT_NEEDED = 2; 12554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 12654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell private static final int DEFAULT_ANCHORED_GRAVITY = Gravity.TOP | Gravity.START; 12754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 1285435a30ae552391f14009c4459731ae149675b18Alan Viverette /** 1295435a30ae552391f14009c4459731ae149675b18Alan Viverette * Default animation style indicating that separate animations should be 1305435a30ae552391f14009c4459731ae149675b18Alan Viverette * used for top/bottom anchoring states. 1315435a30ae552391f14009c4459731ae149675b18Alan Viverette */ 1325435a30ae552391f14009c4459731ae149675b18Alan Viverette private static final int ANIMATION_STYLE_DEFAULT = -1; 1335435a30ae552391f14009c4459731ae149675b18Alan Viverette 134f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette private final int[] mTmpDrawingLocation = new int[2]; 135f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette private final int[] mTmpScreenLocation = new int[2]; 1365435a30ae552391f14009c4459731ae149675b18Alan Viverette private final Rect mTempRect = new Rect(); 1375435a30ae552391f14009c4459731ae149675b18Alan Viverette 138448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy private Context mContext; 139448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy private WindowManager mWindowManager; 1405435a30ae552391f14009c4459731ae149675b18Alan Viverette 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mIsShowing; 1428fd949e680c15d397084430d4907c16cedfacddaAlan Viverette private boolean mIsTransitioningToDismiss; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mIsDropdown; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1455435a30ae552391f14009c4459731ae149675b18Alan Viverette /** View that handles event dispatch and content transitions. */ 1465435a30ae552391f14009c4459731ae149675b18Alan Viverette private PopupDecorView mDecorView; 1475435a30ae552391f14009c4459731ae149675b18Alan Viverette 148697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette /** View that holds the background and may animate during a transition. */ 149697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette private View mBackgroundView; 150697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette 151697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette /** The contents of the popup. May be identical to the background view. */ 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View mContentView; 1535435a30ae552391f14009c4459731ae149675b18Alan Viverette 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mFocusable; 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mInputMethodMode = INPUT_METHOD_FROM_FOCUSABLE; 1567eab094722af54717859b7dcce3cc050f059e00bDianne Hackborn private int mSoftInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED; 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mTouchable = true; 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mOutsideTouchable = false; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mClippingEnabled = true; 16046e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown private int mSplitTouchEnabled = -1; 161ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell private boolean mLayoutInScreen; 16256c2d337e02a275397fc9d0460dca90977f199acAdam Powell private boolean mClipToScreen; 163348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell private boolean mAllowScrollingAnchorParent = true; 1640bd1d0a15294345bf88b20df28466907f982cec7Adam Powell private boolean mLayoutInsetDecor = false; 165e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell private boolean mNotTouchModal; 166393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale private boolean mAttachedInDecor = true; 167393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale private boolean mAttachedInDecorSet = false; 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnTouchListener mTouchInterceptor; 170393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mWidthMode; 172259c2840691a79634ffd8f63291ec21c21819542Alan Viverette private int mWidth = LayoutParams.WRAP_CONTENT; 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLastWidth; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mHeightMode; 175259c2840691a79634ffd8f63291ec21c21819542Alan Viverette private int mHeight = LayoutParams.WRAP_CONTENT; 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLastHeight; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 178ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette private float mElevation; 179ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Drawable mBackground; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Drawable mAboveAnchorBackgroundDrawable; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Drawable mBelowAnchorBackgroundDrawable; 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1845435a30ae552391f14009c4459731ae149675b18Alan Viverette private Transition mEnterTransition; 1855435a30ae552391f14009c4459731ae149675b18Alan Viverette private Transition mExitTransition; 18691098574f90277128415e9593cce1e495cc51465Alan Viverette private Rect mEpicenterBounds; 187560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mAboveAnchor; 189574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell private int mWindowLayoutType = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; 1905435a30ae552391f14009c4459731ae149675b18Alan Viverette 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnDismissListener mOnDismissListener; 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mIgnoreCheekPress = false; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1945435a30ae552391f14009c4459731ae149675b18Alan Viverette private int mAnimationStyle = ANIMATION_STYLE_DEFAULT; 1955435a30ae552391f14009c4459731ae149675b18Alan Viverette 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int[] ABOVE_ANCHOR_STATE_SET = new int[] { 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.attr.state_above_anchor 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 200634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette private final OnAttachStateChangeListener mOnAnchorRootDetachedListener = 201634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette new OnAttachStateChangeListener() { 202634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette @Override 203634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette public void onViewAttachedToWindow(View v) {} 204634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 205634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette @Override 206634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette public void onViewDetachedFromWindow(View v) { 207634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette mIsAnchorRootAttached = false; 208634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette } 209634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette }; 210634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private WeakReference<View> mAnchor; 212634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette private WeakReference<View> mAnchorRoot; 213634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette private boolean mIsAnchorRootAttached; 214560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 2155435a30ae552391f14009c4459731ae149675b18Alan Viverette private final OnScrollChangedListener mOnScrollChangedListener = new OnScrollChangedListener() { 2165435a30ae552391f14009c4459731ae149675b18Alan Viverette @Override 2175435a30ae552391f14009c4459731ae149675b18Alan Viverette public void onScrollChanged() { 2185435a30ae552391f14009c4459731ae149675b18Alan Viverette final View anchor = mAnchor != null ? mAnchor.get() : null; 2195435a30ae552391f14009c4459731ae149675b18Alan Viverette if (anchor != null && mDecorView != null) { 2205435a30ae552391f14009c4459731ae149675b18Alan Viverette final WindowManager.LayoutParams p = (WindowManager.LayoutParams) 2215435a30ae552391f14009c4459731ae149675b18Alan Viverette mDecorView.getLayoutParams(); 2225435a30ae552391f14009c4459731ae149675b18Alan Viverette 2235435a30ae552391f14009c4459731ae149675b18Alan Viverette updateAboveAnchor(findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff, 224f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette p.width, p.height, mAnchoredGravity)); 2255435a30ae552391f14009c4459731ae149675b18Alan Viverette update(p.x, p.y, -1, -1, true); 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2275435a30ae552391f14009c4459731ae149675b18Alan Viverette } 2285435a30ae552391f14009c4459731ae149675b18Alan Viverette }; 229560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 2305435a30ae552391f14009c4459731ae149675b18Alan Viverette private int mAnchorXoff; 2315435a30ae552391f14009c4459731ae149675b18Alan Viverette private int mAnchorYoff; 2325435a30ae552391f14009c4459731ae149675b18Alan Viverette private int mAnchoredGravity; 233560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette private boolean mOverlapAnchor; 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 235b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio private boolean mPopupViewInitialLayoutDirectionInherited; 236b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window of dimension (0,0).</p> 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does provide a background.</p> 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(Context context) { 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, null); 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window of dimension (0,0).</p> 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does provide a background.</p> 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(Context context, AttributeSet attrs) { 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, attrs, com.android.internal.R.attr.popupWindowStyle); 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window of dimension (0,0).</p> 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does provide a background.</p> 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 260617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr) { 261617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette this(context, attrs, defStyleAttr, 0); 262c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 2635435a30ae552391f14009c4459731ae149675b18Alan Viverette 264c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 265c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>Create a new, empty, non focusable popup window of dimension (0,0).</p> 2665435a30ae552391f14009c4459731ae149675b18Alan Viverette * 267c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>The popup does not provide a background.</p> 268c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 269c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 27175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 273617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette final TypedArray a = context.obtainStyledAttributes( 274ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette attrs, R.styleable.PopupWindow, defStyleAttr, defStyleRes); 275ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette final Drawable bg = a.getDrawable(R.styleable.PopupWindow_popupBackground); 276ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette mElevation = a.getDimension(R.styleable.PopupWindow_popupElevation, 0); 277560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette mOverlapAnchor = a.getBoolean(R.styleable.PopupWindow_overlapAnchor, false); 278c3808b5dc7d5873d04e8a0a247b179b2757764baAdam Powell 2795435a30ae552391f14009c4459731ae149675b18Alan Viverette // Preserve default behavior from Gingerbread. If the animation is 2805435a30ae552391f14009c4459731ae149675b18Alan Viverette // undefined or explicitly specifies the Gingerbread animation style, 2815435a30ae552391f14009c4459731ae149675b18Alan Viverette // use a sentinel value. 2825435a30ae552391f14009c4459731ae149675b18Alan Viverette if (a.hasValueOrEmpty(R.styleable.PopupWindow_popupAnimationStyle)) { 2835435a30ae552391f14009c4459731ae149675b18Alan Viverette final int animStyle = a.getResourceId(R.styleable.PopupWindow_popupAnimationStyle, 0); 2845435a30ae552391f14009c4459731ae149675b18Alan Viverette if (animStyle == R.style.Animation_PopupWindow) { 2855435a30ae552391f14009c4459731ae149675b18Alan Viverette mAnimationStyle = ANIMATION_STYLE_DEFAULT; 2865435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 2875435a30ae552391f14009c4459731ae149675b18Alan Viverette mAnimationStyle = animStyle; 2885435a30ae552391f14009c4459731ae149675b18Alan Viverette } 2895435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 2905435a30ae552391f14009c4459731ae149675b18Alan Viverette mAnimationStyle = ANIMATION_STYLE_DEFAULT; 2915435a30ae552391f14009c4459731ae149675b18Alan Viverette } 2925435a30ae552391f14009c4459731ae149675b18Alan Viverette 2935435a30ae552391f14009c4459731ae149675b18Alan Viverette final Transition enterTransition = getTransition(a.getResourceId( 2945435a30ae552391f14009c4459731ae149675b18Alan Viverette R.styleable.PopupWindow_popupEnterTransition, 0)); 2955435a30ae552391f14009c4459731ae149675b18Alan Viverette final Transition exitTransition; 2965435a30ae552391f14009c4459731ae149675b18Alan Viverette if (a.hasValueOrEmpty(R.styleable.PopupWindow_popupExitTransition)) { 2975435a30ae552391f14009c4459731ae149675b18Alan Viverette exitTransition = getTransition(a.getResourceId( 2985435a30ae552391f14009c4459731ae149675b18Alan Viverette R.styleable.PopupWindow_popupExitTransition, 0)); 2995435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 3005435a30ae552391f14009c4459731ae149675b18Alan Viverette exitTransition = enterTransition == null ? null : enterTransition.clone(); 3015435a30ae552391f14009c4459731ae149675b18Alan Viverette } 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 304ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 3055435a30ae552391f14009c4459731ae149675b18Alan Viverette setEnterTransition(enterTransition); 3065435a30ae552391f14009c4459731ae149675b18Alan Viverette setExitTransition(exitTransition); 307ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette setBackgroundDrawable(bg); 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window of dimension (0,0).</p> 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow() { 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(null, 0, 0); 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new non focusable popup window which can display the 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tt>contentView</tt>. The dimension of the window are (0,0).</p> 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param contentView the popup's content 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(View contentView) { 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(contentView, 0, 0); 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window. The dimension of the 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window must be passed to this constructor.</p> 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param width the popup's width 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param height the popup's height 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(int width, int height) { 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(null, width, height); 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new non focusable popup window which can display the 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tt>contentView</tt>. The dimension of the window must be passed to 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this constructor.</p> 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param contentView the popup's content 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param width the popup's width 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param height the popup's height 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(View contentView, int width, int height) { 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(contentView, width, height, false); 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new popup window which can display the <tt>contentView</tt>. 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The dimension of the window must be passed to this constructor.</p> 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param contentView the popup's content 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param width the popup's width 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param height the popup's height 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param focusable true if the popup can be focused, false otherwise 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 375448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy public PopupWindow(View contentView, int width, int height, boolean focusable) { 376448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy if (contentView != null) { 377448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy mContext = contentView.getContext(); 378448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); 379448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy } 380393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setContentView(contentView); 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setWidth(width); 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setHeight(height); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setFocusable(focusable); 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3871e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette /** 3881e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * Sets the enter transition to be used when the popup window is shown. 3891e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * 3901e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @param enterTransition the enter transition, or {@code null} to clear 3911e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @see #getEnterTransition() 3921e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupEnterTransition 3931e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette */ 3941e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette public void setEnterTransition(@Nullable Transition enterTransition) { 3955435a30ae552391f14009c4459731ae149675b18Alan Viverette mEnterTransition = enterTransition; 3965435a30ae552391f14009c4459731ae149675b18Alan Viverette } 3975435a30ae552391f14009c4459731ae149675b18Alan Viverette 3981e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette /** 3991e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * Returns the enter transition to be used when the popup window is shown. 4001e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * 4011e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @return the enter transition, or {@code null} if not set 4021e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @see #setEnterTransition(Transition) 4031e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupEnterTransition 4041e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette */ 4051e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette @Nullable 4061e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette public Transition getEnterTransition() { 4071e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette return mEnterTransition; 4081e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette } 4091e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette 4101e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette /** 4111e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * Sets the exit transition to be used when the popup window is dismissed. 4121e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * 4131e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @param exitTransition the exit transition, or {@code null} to clear 4141e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @see #getExitTransition() 4151e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupExitTransition 4161e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette */ 4171e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette public void setExitTransition(@Nullable Transition exitTransition) { 4185435a30ae552391f14009c4459731ae149675b18Alan Viverette mExitTransition = exitTransition; 4195435a30ae552391f14009c4459731ae149675b18Alan Viverette } 4205435a30ae552391f14009c4459731ae149675b18Alan Viverette 42191098574f90277128415e9593cce1e495cc51465Alan Viverette /** 4221e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * Returns the exit transition to be used when the popup window is 4231e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * dismissed. 4241e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * 4251e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @return the exit transition, or {@code null} if not set 4261e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @see #setExitTransition(Transition) 4271e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette * @attr ref android.R.styleable#PopupWindow_popupExitTransition 4281e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette */ 4291e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette @Nullable 4301e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette public Transition getExitTransition() { 4311e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette return mExitTransition; 4321e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette } 4331e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette 4341e940dc2d165fa6cdedb6945811988502f87ddceAlan Viverette /** 43591098574f90277128415e9593cce1e495cc51465Alan Viverette * Sets the bounds used as the epicenter of the enter and exit transitions. 43691098574f90277128415e9593cce1e495cc51465Alan Viverette * <p> 43791098574f90277128415e9593cce1e495cc51465Alan Viverette * Transitions use a point or Rect, referred to as the epicenter, to orient 43891098574f90277128415e9593cce1e495cc51465Alan Viverette * the direction of travel. For popup windows, the anchor view bounds are 43991098574f90277128415e9593cce1e495cc51465Alan Viverette * used as the default epicenter. 44091098574f90277128415e9593cce1e495cc51465Alan Viverette * <p> 44191098574f90277128415e9593cce1e495cc51465Alan Viverette * See {@link Transition#setEpicenterCallback(EpicenterCallback)} for more 44291098574f90277128415e9593cce1e495cc51465Alan Viverette * information about how transition epicenters. 44391098574f90277128415e9593cce1e495cc51465Alan Viverette * 44491098574f90277128415e9593cce1e495cc51465Alan Viverette * @param bounds the epicenter bounds relative to the anchor view, or 44591098574f90277128415e9593cce1e495cc51465Alan Viverette * {@code null} to use the default epicenter 44691098574f90277128415e9593cce1e495cc51465Alan Viverette * @see #getTransitionEpicenter() 44791098574f90277128415e9593cce1e495cc51465Alan Viverette * @hide 44891098574f90277128415e9593cce1e495cc51465Alan Viverette */ 44991098574f90277128415e9593cce1e495cc51465Alan Viverette public void setEpicenterBounds(Rect bounds) { 45091098574f90277128415e9593cce1e495cc51465Alan Viverette mEpicenterBounds = bounds; 45191098574f90277128415e9593cce1e495cc51465Alan Viverette } 45291098574f90277128415e9593cce1e495cc51465Alan Viverette 4535435a30ae552391f14009c4459731ae149675b18Alan Viverette private Transition getTransition(int resId) { 4545435a30ae552391f14009c4459731ae149675b18Alan Viverette if (resId != 0 && resId != R.transition.no_transition) { 4555435a30ae552391f14009c4459731ae149675b18Alan Viverette final TransitionInflater inflater = TransitionInflater.from(mContext); 4565435a30ae552391f14009c4459731ae149675b18Alan Viverette final Transition transition = inflater.inflateTransition(resId); 4575435a30ae552391f14009c4459731ae149675b18Alan Viverette if (transition != null) { 4585435a30ae552391f14009c4459731ae149675b18Alan Viverette final boolean isEmpty = transition instanceof TransitionSet 4595435a30ae552391f14009c4459731ae149675b18Alan Viverette && ((TransitionSet) transition).getTransitionCount() == 0; 4605435a30ae552391f14009c4459731ae149675b18Alan Viverette if (!isEmpty) { 4615435a30ae552391f14009c4459731ae149675b18Alan Viverette return transition; 4625435a30ae552391f14009c4459731ae149675b18Alan Viverette } 4635435a30ae552391f14009c4459731ae149675b18Alan Viverette } 4645435a30ae552391f14009c4459731ae149675b18Alan Viverette } 4655435a30ae552391f14009c4459731ae149675b18Alan Viverette return null; 4665435a30ae552391f14009c4459731ae149675b18Alan Viverette } 4675435a30ae552391f14009c4459731ae149675b18Alan Viverette 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 469ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * Return the drawable used as the popup window's background. 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 471ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @return the background drawable or {@code null} if not set 472ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @see #setBackgroundDrawable(Drawable) 473ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @attr ref android.R.styleable#PopupWindow_popupBackground 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable getBackground() { 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBackground; 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 480ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * Specifies the background drawable for this popup window. The background 481ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * can be set to {@code null}. 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param background the popup's background 484ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @see #getBackground() 485ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @attr ref android.R.styleable#PopupWindow_popupBackground 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setBackgroundDrawable(Drawable background) { 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBackground = background; 489ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 490ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // If this is a StateListDrawable, try to find and store the drawable to be 491ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // used when the drop-down is placed above its anchor view, and the one to be 492ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // used when the drop-down is placed below its anchor view. We extract 493ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // the drawables ourselves to work around a problem with using refreshDrawableState 494ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // that it will take into account the padding of all drawables specified in a 495ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // StateListDrawable, thus adding superfluous padding to drop-down views. 496ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // 497ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // We assume a StateListDrawable will have a drawable for ABOVE_ANCHOR_STATE_SET and 498ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // at least one other drawable, intended for the 'below-anchor state'. 499ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette if (mBackground instanceof StateListDrawable) { 500ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette StateListDrawable stateList = (StateListDrawable) mBackground; 501ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 502ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // Find the above-anchor view - this one's easy, it should be labeled as such. 503ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette int aboveAnchorStateIndex = stateList.getStateDrawableIndex(ABOVE_ANCHOR_STATE_SET); 504ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 505ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // Now, for the below-anchor view, look for any other drawable specified in the 506ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // StateListDrawable which is not for the above-anchor state and use that. 507ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette int count = stateList.getStateCount(); 508ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette int belowAnchorStateIndex = -1; 509ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette for (int i = 0; i < count; i++) { 510ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette if (i != aboveAnchorStateIndex) { 511ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette belowAnchorStateIndex = i; 512ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette break; 513ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } 514ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } 515ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 516ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // Store the drawables we found, if we found them. Otherwise, set them both 517ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // to null so that we'll just use refreshDrawableState. 518ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette if (aboveAnchorStateIndex != -1 && belowAnchorStateIndex != -1) { 519ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette mAboveAnchorBackgroundDrawable = stateList.getStateDrawable(aboveAnchorStateIndex); 520ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette mBelowAnchorBackgroundDrawable = stateList.getStateDrawable(belowAnchorStateIndex); 521ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } else { 522ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette mBelowAnchorBackgroundDrawable = null; 523ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette mAboveAnchorBackgroundDrawable = null; 524ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } 525ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 529ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @return the elevation for this popup window in pixels 530ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @see #setElevation(float) 531ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @attr ref android.R.styleable#PopupWindow_popupElevation 532ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette */ 533ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette public float getElevation() { 534ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette return mElevation; 535ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette } 536ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette 537ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette /** 538ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * Specifies the elevation for this popup window. 539ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * 540ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @param elevation the popup's elevation in pixels 541ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @see #getElevation() 542ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @attr ref android.R.styleable#PopupWindow_popupElevation 543ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette */ 544ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette public void setElevation(float elevation) { 545ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette mElevation = elevation; 546ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette } 547ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette 548ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette /** 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Return the animation style to use the popup appears and disappears</p> 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the animation style to use the popup appears and disappears 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getAnimationStyle() { 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAnimationStyle; 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 556393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 55854ec76d81ac38284caa6d00ad5f2d2207206b9ceShuhrat Dehkanov * Set the flag on popup to ignore cheek press events; by default this flag 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is set to false 56054ec76d81ac38284caa6d00ad5f2d2207206b9ceShuhrat Dehkanov * which means the popup will not ignore cheek press dispatch events. 5615435a30ae552391f14009c4459731ae149675b18Alan Viverette * 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 565393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setIgnoreCheekPress() { 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIgnoreCheekPress = true; 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5715435a30ae552391f14009c4459731ae149675b18Alan Viverette 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Change the animation style resource for this popup.</p> 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param animationStyle animation style to use when the popup appears 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and disappears. Set to -1 for the default animation, 0 for no 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * animation, or a resource identifier for an explicit animation. 5835435a30ae552391f14009c4459731ae149675b18Alan Viverette * 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAnimationStyle(int animationStyle) { 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimationStyle = animationStyle; 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5895435a30ae552391f14009c4459731ae149675b18Alan Viverette 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Return the view used as the content of the popup window.</p> 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return a {@link android.view.View} representing the popup's content 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setContentView(android.view.View) 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public View getContentView() { 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mContentView; 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Change the popup's content. The content is represented by an instance 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of {@link android.view.View}.</p> 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 60581f08086b44a117097960195d2c9072e29644962Gilles Debunne * <p>This method has no effect if called when the popup is showing.</p> 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param contentView the new content for the popup 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getContentView() 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isShowing() 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setContentView(View contentView) { 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isShowing()) { 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentView = contentView; 618448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy 6190c0b768e1514280812321854db6dfba723c3d169Romain Guy if (mContext == null && mContentView != null) { 620448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy mContext = mContentView.getContext(); 621448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy } 622448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy 6230c0b768e1514280812321854db6dfba723c3d169Romain Guy if (mWindowManager == null && mContentView != null) { 624448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); 625448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy } 626393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 627393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // Setting the default for attachedInDecor based on SDK version here 628393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // instead of in the constructor since we might not have the context 629393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // object in the constructor. We only want to set default here if the 630393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // app hasn't already set the attachedInDecor. 631393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale if (mContext != null && !mAttachedInDecorSet) { 632393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // Attach popup window in decor frame of parent window by default for 633393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // {@link Build.VERSION_CODES.LOLLIPOP_MR1} or greater. Keep current 634393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // behavior of not attaching to decor frame for older SDKs. 635393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale setAttachedInDecor(mContext.getApplicationInfo().targetSdkVersion 636393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale >= Build.VERSION_CODES.LOLLIPOP_MR1); 637393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale } 638393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set a callback for all touch events being dispatched to the popup 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window. 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTouchInterceptor(OnTouchListener l) { 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTouchInterceptor = l; 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 648393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicate whether the popup window can grab the focus.</p> 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is focusable, false otherwise 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setFocusable(boolean) 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isFocusable() { 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFocusable; 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Changes the focusability of the popup window. When focusable, the 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window will grab the focus from the current focused widget if the popup 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * contains a focusable {@link android.view.View}. By default a popup 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window is not focusable.</p> 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param focusable true if the popup should grab focus, false otherwise. 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isFocusable() 6735435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setFocusable(boolean focusable) { 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFocusable = focusable; 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the current value in {@link #setInputMethodMode(int)}. 6825435a30ae552391f14009c4459731ae149675b18Alan Viverette * 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setInputMethodMode(int) 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getInputMethodMode() { 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mInputMethodMode; 6875435a30ae552391f14009c4459731ae149675b18Alan Viverette 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6895435a30ae552391f14009c4459731ae149675b18Alan Viverette 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Control how the popup operates with an input method: one of 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #INPUT_METHOD_FROM_FOCUSABLE}, {@link #INPUT_METHOD_NEEDED}, 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or {@link #INPUT_METHOD_NOT_NEEDED}. 6945435a30ae552391f14009c4459731ae149675b18Alan Viverette * 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 6985435a30ae552391f14009c4459731ae149675b18Alan Viverette * 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getInputMethodMode() 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setInputMethodMode(int mode) { 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mInputMethodMode = mode; 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 705374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy 706374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy /** 707374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * Sets the operating mode for the soft input area. 708374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * 709374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @param mode The desired mode, see 710374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * {@link android.view.WindowManager.LayoutParams#softInputMode} 711374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * for the full list 712374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * 713374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @see android.view.WindowManager.LayoutParams#softInputMode 714374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @see #getSoftInputMode() 715374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy */ 716374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy public void setSoftInputMode(int mode) { 717374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy mSoftInputMode = mode; 718374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy } 719374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy 720374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy /** 721374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * Returns the current value in {@link #setSoftInputMode(int)}. 722374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * 723374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @see #setSoftInputMode(int) 724374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @see android.view.WindowManager.LayoutParams#softInputMode 725374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy */ 726374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy public int getSoftInputMode() { 727374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy return mSoftInputMode; 728374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy } 7295435a30ae552391f14009c4459731ae149675b18Alan Viverette 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicates whether the popup window receives touch events.</p> 7325435a30ae552391f14009c4459731ae149675b18Alan Viverette * 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is touchable, false otherwise 7345435a30ae552391f14009c4459731ae149675b18Alan Viverette * 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setTouchable(boolean) 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isTouchable() { 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mTouchable; 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Changes the touchability of the popup window. When touchable, the 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window will receive touch events, otherwise touch events will go to the 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window below it. By default the window is touchable.</p> 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param touchable true if the popup should receive touch events, false otherwise 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isTouchable() 7535435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTouchable(boolean touchable) { 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTouchable = touchable; 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicates whether the popup window will be informed of touch events 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * outside of its window.</p> 7635435a30ae552391f14009c4459731ae149675b18Alan Viverette * 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is outside touchable, false otherwise 7655435a30ae552391f14009c4459731ae149675b18Alan Viverette * 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setOutsideTouchable(boolean) 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isOutsideTouchable() { 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mOutsideTouchable; 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Controls whether the pop-up will be informed of touch events outside 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of its window. This only makes sense for pop-ups that are touchable 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * but not focusable, which means touches outside of the window will 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be delivered to the window behind. The default is false.</p> 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param touchable true if the popup should receive outside 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * touch events, false otherwise 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isOutsideTouchable() 7865435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setOutsideTouchable(boolean touchable) { 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOutsideTouchable = touchable; 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicates whether clipping of the popup window is enabled.</p> 7955435a30ae552391f14009c4459731ae149675b18Alan Viverette * 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the clipping is enabled, false otherwise 7975435a30ae552391f14009c4459731ae149675b18Alan Viverette * 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setClippingEnabled(boolean) 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isClippingEnabled() { 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mClippingEnabled; 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Allows the popup window to extend beyond the bounds of the screen. By default the 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window is clipped to the screen boundaries. Setting this to false will allow windows to be 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * accurately positioned.</p> 8085435a30ae552391f14009c4459731ae149675b18Alan Viverette * 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param enabled false if the window should be allowed to extend outside of the screen 8145435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isClippingEnabled() 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setClippingEnabled(boolean enabled) { 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mClippingEnabled = enabled; 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 82356c2d337e02a275397fc9d0460dca90977f199acAdam Powell * Clip this popup window to the screen, but not to the containing window. 82456c2d337e02a275397fc9d0460dca90977f199acAdam Powell * 82556c2d337e02a275397fc9d0460dca90977f199acAdam Powell * @param enabled True to clip to the screen. 82656c2d337e02a275397fc9d0460dca90977f199acAdam Powell * @hide 82756c2d337e02a275397fc9d0460dca90977f199acAdam Powell */ 82856c2d337e02a275397fc9d0460dca90977f199acAdam Powell public void setClipToScreenEnabled(boolean enabled) { 82956c2d337e02a275397fc9d0460dca90977f199acAdam Powell mClipToScreen = enabled; 83056c2d337e02a275397fc9d0460dca90977f199acAdam Powell } 831348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell 832348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell /** 833348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * Allow PopupWindow to scroll the anchor's parent to provide more room 834348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * for the popup. Enabled by default. 835348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * 836348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * @param enabled True to scroll the anchor's parent when more room is desired by the popup. 837348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell */ 838348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell void setAllowScrollingAnchorParent(boolean enabled) { 839348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell mAllowScrollingAnchorParent = enabled; 840348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell } 8415435a30ae552391f14009c4459731ae149675b18Alan Viverette 84256c2d337e02a275397fc9d0460dca90977f199acAdam Powell /** 84301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * <p>Indicates whether the popup window supports splitting touches.</p> 8445435a30ae552391f14009c4459731ae149675b18Alan Viverette * 84501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * @return true if the touch splitting is enabled, false otherwise 8465435a30ae552391f14009c4459731ae149675b18Alan Viverette * 84701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * @see #setSplitTouchEnabled(boolean) 84801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown */ 84901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown public boolean isSplitTouchEnabled() { 85046e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown if (mSplitTouchEnabled < 0 && mContext != null) { 85146e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown return mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB; 85246e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown } 85346e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown return mSplitTouchEnabled == 1; 85401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown } 85501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown 85601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown /** 85701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * <p>Allows the popup window to split touches across other windows that also 85846e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown * support split touch. When this flag is false, the first pointer 85901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * that goes down determines the window to which all subsequent touches 86046e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown * go until all pointers go up. When this flag is true, each pointer 86101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * (not necessarily the first) that goes down determines the window 86201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * to which all subsequent touches of that pointer will go until that 86301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * pointer goes up thereby enabling touches with multiple pointers 86401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * to be split across multiple windows.</p> 86501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * 86601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * @param enabled true if the split touches should be enabled, false otherwise 86701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * @see #isSplitTouchEnabled() 86801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown */ 86901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown public void setSplitTouchEnabled(boolean enabled) { 87046e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown mSplitTouchEnabled = enabled ? 1 : 0; 87101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown } 87201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown 87301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown /** 874ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * <p>Indicates whether the popup window will be forced into using absolute screen coordinates 875ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * for positioning.</p> 876ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * 877ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * @return true if the window will always be positioned in screen coordinates. 878ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * @hide 879ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell */ 880ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell public boolean isLayoutInScreenEnabled() { 881ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell return mLayoutInScreen; 882ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell } 883ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell 884ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell /** 885ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * <p>Allows the popup window to force the flag 886ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * {@link WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN}, overriding default behavior. 887ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * This will cause the popup to be positioned in absolute screen coordinates.</p> 888ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * 889ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * @param enabled true if the popup should always be positioned in screen coordinates 890ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * @hide 891ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell */ 892ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell public void setLayoutInScreenEnabled(boolean enabled) { 893ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell mLayoutInScreen = enabled; 894ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell } 895ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell 896ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell /** 897393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * <p>Indicates whether the popup window will be attached in the decor frame of its parent 898393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * window. 899393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 900393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @return true if the window will be attached to the decor frame of its parent window. 901393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 902393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @see #setAttachedInDecor(boolean) 903393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR 904393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale */ 905393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale public boolean isAttachedInDecor() { 906393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale return mAttachedInDecor; 907393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale } 908393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 909393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale /** 910393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * <p>This will attach the popup window to the decor frame of the parent window to avoid 911393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * overlaping with screen decorations like the navigation bar. Overrides the default behavior of 912393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * the flag {@link WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR}. 913393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 914393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * <p>By default the flag is set on SDK version {@link Build.VERSION_CODES#LOLLIPOP_MR1} or 915393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * greater and cleared on lesser SDK versions. 916393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 917393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @param enabled true if the popup should be attached to the decor frame of its parent window. 918393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 919393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR 920393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale */ 921393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale public void setAttachedInDecor(boolean enabled) { 922393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale mAttachedInDecor = enabled; 923393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale mAttachedInDecorSet = true; 924393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale } 925393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 926393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale /** 9270bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * Allows the popup window to force the flag 9280bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * {@link WindowManager.LayoutParams#FLAG_LAYOUT_INSET_DECOR}, overriding default behavior. 9290bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * This will cause the popup to inset its content to account for system windows overlaying 9300bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * the screen, such as the status bar. 9310bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * 9320bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * <p>This will often be combined with {@link #setLayoutInScreenEnabled(boolean)}. 9330bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * 9340bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * @param enabled true if the popup's views should inset content to account for system windows, 9350bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * the way that decor views behave for full-screen windows. 9360bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * @hide 9370bd1d0a15294345bf88b20df28466907f982cec7Adam Powell */ 9380bd1d0a15294345bf88b20df28466907f982cec7Adam Powell public void setLayoutInsetDecor(boolean enabled) { 9390bd1d0a15294345bf88b20df28466907f982cec7Adam Powell mLayoutInsetDecor = enabled; 9400bd1d0a15294345bf88b20df28466907f982cec7Adam Powell } 9410bd1d0a15294345bf88b20df28466907f982cec7Adam Powell 9420bd1d0a15294345bf88b20df28466907f982cec7Adam Powell /** 94380ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette * Set the layout type for this window. 94480ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette * <p> 94580ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette * See {@link WindowManager.LayoutParams#type} for possible values. 946574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell * 947574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell * @param layoutType Layout type for this window. 94836344a90c226c90243e4e02bfb13589e120431ddChris Banes * 94936344a90c226c90243e4e02bfb13589e120431ddChris Banes * @see WindowManager.LayoutParams#type 950574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell */ 951574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell public void setWindowLayoutType(int layoutType) { 952574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell mWindowLayoutType = layoutType; 953574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell } 954574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell 955574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell /** 95636344a90c226c90243e4e02bfb13589e120431ddChris Banes * Returns the layout type for this window. 95736344a90c226c90243e4e02bfb13589e120431ddChris Banes * 95836344a90c226c90243e4e02bfb13589e120431ddChris Banes * @see #setWindowLayoutType(int) 959574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell */ 960574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell public int getWindowLayoutType() { 961574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell return mWindowLayoutType; 962574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell } 963574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell 964574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell /** 965e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell * Set whether this window is touch modal or if outside touches will be sent to 966e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell * other windows behind it. 967e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell * @hide 968e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell */ 969e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell public void setTouchModal(boolean touchModal) { 970e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell mNotTouchModal = !touchModal; 971e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell } 972e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell 973e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell /** 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Change the width and height measure specs that are given to the 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window manager by the popup. By default these are 0, meaning that 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the current width or height is requested as an explicit size from 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the window manager. You can supply 9785435a30ae552391f14009c4459731ae149675b18Alan Viverette * {@link ViewGroup.LayoutParams#WRAP_CONTENT} or 979980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * {@link ViewGroup.LayoutParams#MATCH_PARENT} to have that measure 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * spec supplied instead, replacing the absolute width and height that 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * has been set in the popup.</p> 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown.</p> 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param widthSpec an explicit width measure spec mode, either 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link ViewGroup.LayoutParams#WRAP_CONTENT}, 988980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * {@link ViewGroup.LayoutParams#MATCH_PARENT}, or 0 to use the absolute 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * width. 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param heightSpec an explicit height measure spec mode, either 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link ViewGroup.LayoutParams#WRAP_CONTENT}, 992980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * {@link ViewGroup.LayoutParams#MATCH_PARENT}, or 0 to use the absolute 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * height. 994259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * 995259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @deprecated Use {@link #setWidth(int)} and {@link #setHeight(int)}. 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 997259c2840691a79634ffd8f63291ec21c21819542Alan Viverette @Deprecated 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setWindowLayoutMode(int widthSpec, int heightSpec) { 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWidthMode = widthSpec; 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeightMode = heightSpec; 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10025435a30ae552391f14009c4459731ae149675b18Alan Viverette 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1004c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * Returns the popup's requested height. May be a layout constant such as 1005c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * {@link LayoutParams#WRAP_CONTENT} or {@link LayoutParams#MATCH_PARENT}. 1006c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * <p> 1007c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * The actual size of the popup may depend on other factors such as 1008c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * clipping and window layout. 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1010c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @return the popup height in pixels or a layout constant 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setHeight(int) 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getHeight() { 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mHeight; 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1018c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * Sets the popup's requested height. May be a layout constant such as 1019c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * {@link LayoutParams#WRAP_CONTENT} or {@link LayoutParams#MATCH_PARENT}. 1020c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * <p> 1021c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * The actual size of the popup may depend on other factors such as 1022c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * clipping and window layout. 1023259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1024259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * If the popup is showing, calling this method will take effect the next 1025259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * time the popup is shown. 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1027c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param height the popup height in pixels or a layout constant 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getHeight() 10295435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setHeight(int height) { 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeight = height; 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1036c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * Returns the popup's requested width. May be a layout constant such as 1037c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * {@link LayoutParams#WRAP_CONTENT} or {@link LayoutParams#MATCH_PARENT}. 1038c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * <p> 1039c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * The actual size of the popup may depend on other factors such as 1040c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * clipping and window layout. 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1042c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @return the popup width in pixels or a layout constant 10435435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #setWidth(int) 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getWidth() { 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mWidth; 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1050c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * Sets the popup's requested width. May be a layout constant such as 1051c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * {@link LayoutParams#WRAP_CONTENT} or {@link LayoutParams#MATCH_PARENT}. 1052c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * <p> 1053c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * The actual size of the popup may depend on other factors such as 1054c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * clipping and window layout. 1055259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1056259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * If the popup is showing, calling this method will take effect the next 1057259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * time the popup is shown. 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1059c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param width the popup width in pixels or a layout constant 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getWidth() 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isShowing() 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setWidth(int width) { 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWidth = width; 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 106875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Sets whether the popup window should overlap its anchor view when 106975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * displayed as a drop-down. 107075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * <p> 107175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If the popup is showing, calling this method will take effect only 107275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * the next time the popup is shown. 107375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * 107475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @param overlapAnchor Whether the popup should overlap its anchor. 107575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * 107675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @see #getOverlapAnchor() 107775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @see #isShowing() 107875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette */ 107975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette public void setOverlapAnchor(boolean overlapAnchor) { 108075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette mOverlapAnchor = overlapAnchor; 108175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette } 108275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette 108375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette /** 108475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Returns whether the popup window should overlap its anchor view when 108575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * displayed as a drop-down. 108675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * 108775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @return Whether the popup should overlap its anchor. 108875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * 108975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @see #setOverlapAnchor(boolean) 109075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette */ 109175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette public boolean getOverlapAnchor() { 109275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette return mOverlapAnchor; 109375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette } 109475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette 109575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette /** 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicate whether this popup window is showing on screen.</p> 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is showing, false otherwise 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isShowing() { 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mIsShowing; 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Display the content view in a popup window at the specified location. If the popup window 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cannot fit on screen, it will be clipped. See {@link android.view.WindowManager.LayoutParams} 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for more information on how gravity and the x and y parameters are related. Specifying 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a gravity of {@link android.view.Gravity#NO_GRAVITY} is similar to specifying 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>Gravity.LEFT | Gravity.TOP</code>. 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p> 11125435a30ae552391f14009c4459731ae149675b18Alan Viverette * 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param parent a parent view to get the {@link android.view.View#getWindowToken()} token from 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param gravity the gravity which controls the placement of the popup window 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x the popup's x location offset 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y the popup's y location offset 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void showAtLocation(View parent, int gravity, int x, int y) { 11198ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell showAtLocation(parent.getWindowToken(), gravity, x, y); 11208ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell } 11218ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell 11228ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell /** 11238ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * Display the content view in a popup window at the specified location. 11248ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * 11258ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @param token Window token to use for creating the new window 11268ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @param gravity the gravity which controls the placement of the popup window 11278ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @param x the popup's x location offset 11288ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @param y the popup's y location offset 11298ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * 11308ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @hide Internal use only. Applications should use 11318ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * {@link #showAtLocation(View, int, int, int)} instead. 11328ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell */ 11338ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell public void showAtLocation(IBinder token, int gravity, int x, int y) { 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isShowing() || mContentView == null) { 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1138e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette TransitionManager.endTransitions(mDecorView); 1139e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1140f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette detachFromAnchor(); 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsShowing = true; 11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsDropdown = false; 11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1145e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final WindowManager.LayoutParams p = createPopupLayoutParams(token); 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project preparePopup(p); 1147e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1148e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // Only override the default if some gravity was specified. 1149e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette if (gravity != Gravity.NO_GRAVITY) { 1150e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.gravity = gravity; 11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1152e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.x = x; 11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.y = y; 1155e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokePopup(p); 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 116075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Display the content view in a popup window anchored to the bottom-left 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * corner of the anchor view. If there is not enough room on screen to show 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the popup in its entirety, this method tries to find a parent scroll 116375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * view to scroll. If no parent scroll view can be scrolled, the 116475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * bottom-left corner of the popup is pinned at the top left corner of the 116575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * anchor view. 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the view on which to pin the popup window 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #dismiss() 11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void showAsDropDown(View anchor) { 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project showAsDropDown(anchor, 0, 0); 11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 117675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Display the content view in a popup window anchored to the bottom-left 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * corner of the anchor view offset by the specified x and y coordinates. 117875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If there is not enough room on screen to show the popup in its entirety, 117975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * this method tries to find a parent scroll view to scroll. If no parent 118075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * scroll view can be scrolled, the bottom-left corner of the popup is 118175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * pinned at the top left corner of the anchor view. 118275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * <p> 118375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If the view later scrolls to move <code>anchor</code> to a different 118475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * location, the popup will be moved correspondingly. 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the view on which to pin the popup window 118754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param xoff A horizontal offset from the anchor in pixels 118854c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param yoff A vertical offset from the anchor in pixels 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #dismiss() 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void showAsDropDown(View anchor, int xoff, int yoff) { 119354c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell showAsDropDown(anchor, xoff, yoff, DEFAULT_ANCHORED_GRAVITY); 119454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell } 119554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 119654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell /** 119775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Displays the content view in a popup window anchored to the corner of 119875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * another view. The window is positioned according to the specified 119975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * gravity and offset by the specified x and y coordinates. 120075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * <p> 120175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If there is not enough room on screen to show the popup in its entirety, 120275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * this method tries to find a parent scroll view to scroll. If no parent 120375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * view can be scrolled, the specified vertical gravity will be ignored and 120475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * the popup will anchor itself such that it is visible. 120575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * <p> 120675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If the view later scrolls to move <code>anchor</code> to a different 120775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * location, the popup will be moved correspondingly. 120854c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * 120954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param anchor the view on which to pin the popup window 121054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param xoff A horizontal offset from the anchor in pixels 121154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param yoff A vertical offset from the anchor in pixels 121254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param gravity Alignment of the popup relative to the anchor 121354c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * 121454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @see #dismiss() 121554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell */ 121654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell public void showAsDropDown(View anchor, int xoff, int yoff, int gravity) { 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isShowing() || mContentView == null) { 12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1221e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette TransitionManager.endTransitions(mDecorView); 1222e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1223f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette attachToAnchor(anchor, xoff, yoff, gravity); 12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsShowing = true; 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsDropdown = true; 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1228e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final WindowManager.LayoutParams p = createPopupLayoutParams(anchor.getWindowToken()); 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project preparePopup(p); 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1231f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final boolean aboveAnchor = findDropDownPosition(anchor, p, xoff, yoff, 1232f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette p.width, p.height, gravity); 1233e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette updateAboveAnchor(aboveAnchor); 1234396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver p.accessibilityIdOfAnchor = (anchor != null) ? anchor.getAccessibilityViewId() : -1; 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokePopup(p); 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12393e141685003939a9addce21ba2492ea3a8aebee6Romain Guy private void updateAboveAnchor(boolean aboveAnchor) { 12403e141685003939a9addce21ba2492ea3a8aebee6Romain Guy if (aboveAnchor != mAboveAnchor) { 12413e141685003939a9addce21ba2492ea3a8aebee6Romain Guy mAboveAnchor = aboveAnchor; 12423e141685003939a9addce21ba2492ea3a8aebee6Romain Guy 1243697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette if (mBackground != null && mBackgroundView != null) { 1244697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette // If the background drawable provided was a StateListDrawable 1245697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette // with above-anchor and below-anchor states, use those. 1246697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette // Otherwise, rely on refreshDrawableState to do the job. 12473e141685003939a9addce21ba2492ea3a8aebee6Romain Guy if (mAboveAnchorBackgroundDrawable != null) { 12483e141685003939a9addce21ba2492ea3a8aebee6Romain Guy if (mAboveAnchor) { 1249697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView.setBackground(mAboveAnchorBackgroundDrawable); 12503e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } else { 1251697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView.setBackground(mBelowAnchorBackgroundDrawable); 12523e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 12533e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } else { 1254697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView.refreshDrawableState(); 12553e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 12563e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 12573e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 12583e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 12593e141685003939a9addce21ba2492ea3a8aebee6Romain Guy 12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Indicates whether the popup is showing above (the y coordinate of the popup's bottom 12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is less than the y coordinate of the anchor) or below the anchor view (the y coordinate 12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the popup is greater than y coordinate of the anchor's bottom). 12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The value returned 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by this method is meaningful only after {@link #showAsDropDown(android.view.View)} 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or {@link #showAsDropDown(android.view.View, int, int)} was invoked. 12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return True if this popup is showing above the anchor view, false otherwise. 12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isAboveAnchor() { 12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAboveAnchor; 12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1276e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette * Prepare the popup by embedding it into a new ViewGroup if the background 1277e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette * drawable is not null. If embedding is required, the layout parameters' 1278e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette * height is modified to take into account the background's padding. 12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param p the layout parameters of the popup's content view 12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void preparePopup(WindowManager.LayoutParams p) { 1283448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy if (mContentView == null || mContext == null || mWindowManager == null) { 1284448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy throw new IllegalStateException("You must specify a valid content view by " 1285448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy + "calling setContentView() before attempting to show the popup."); 1286448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy } 1287448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy 12888fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // The old decor view may be transitioning out. Make sure it finishes 12898fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // and cleans up before we try to create another one. 12908fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (mDecorView != null) { 12918fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mDecorView.cancelTransitions(); 12928fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 12938fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 12945435a30ae552391f14009c4459731ae149675b18Alan Viverette // When a background is available, we embed the content view within 12955435a30ae552391f14009c4459731ae149675b18Alan Viverette // another view that owns the background drawable. 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBackground != null) { 1297697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView = createBackgroundView(mContentView); 1298697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView.setBackground(mBackground); 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1300697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView = mContentView; 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1302ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette 1303697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mDecorView = createDecorView(mBackgroundView); 13045435a30ae552391f14009c4459731ae149675b18Alan Viverette 13055435a30ae552391f14009c4459731ae149675b18Alan Viverette // The background owner should be elevated so that it casts a shadow. 1306697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView.setElevation(mElevation); 13075435a30ae552391f14009c4459731ae149675b18Alan Viverette 13085435a30ae552391f14009c4459731ae149675b18Alan Viverette // We may wrap that in another view, so we'll need to manually specify 13095435a30ae552391f14009c4459731ae149675b18Alan Viverette // the surface insets. 1310246c209e4fe704c0745224be0ab05225e8431d11Wale Ogunwale p.setSurfaceInsets(mBackgroundView, true /*manual*/, true /*preservePrevious*/); 13115435a30ae552391f14009c4459731ae149675b18Alan Viverette 1312b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio mPopupViewInitialLayoutDirectionInherited = 13135435a30ae552391f14009c4459731ae149675b18Alan Viverette (mContentView.getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT); 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13175435a30ae552391f14009c4459731ae149675b18Alan Viverette * Wraps a content view in a PopupViewContainer. 13185435a30ae552391f14009c4459731ae149675b18Alan Viverette * 13195435a30ae552391f14009c4459731ae149675b18Alan Viverette * @param contentView the content view to wrap 13205435a30ae552391f14009c4459731ae149675b18Alan Viverette * @return a PopupViewContainer that wraps the content view 13215435a30ae552391f14009c4459731ae149675b18Alan Viverette */ 13225435a30ae552391f14009c4459731ae149675b18Alan Viverette private PopupBackgroundView createBackgroundView(View contentView) { 13235435a30ae552391f14009c4459731ae149675b18Alan Viverette final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams(); 13245435a30ae552391f14009c4459731ae149675b18Alan Viverette final int height; 13252665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr if (layoutParams != null && layoutParams.height == WRAP_CONTENT) { 13262665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr height = WRAP_CONTENT; 13275435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 13282665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr height = MATCH_PARENT; 13295435a30ae552391f14009c4459731ae149675b18Alan Viverette } 13305435a30ae552391f14009c4459731ae149675b18Alan Viverette 13315435a30ae552391f14009c4459731ae149675b18Alan Viverette final PopupBackgroundView backgroundView = new PopupBackgroundView(mContext); 13325435a30ae552391f14009c4459731ae149675b18Alan Viverette final PopupBackgroundView.LayoutParams listParams = new PopupBackgroundView.LayoutParams( 13332665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr MATCH_PARENT, height); 13345435a30ae552391f14009c4459731ae149675b18Alan Viverette backgroundView.addView(contentView, listParams); 13355435a30ae552391f14009c4459731ae149675b18Alan Viverette 13365435a30ae552391f14009c4459731ae149675b18Alan Viverette return backgroundView; 13375435a30ae552391f14009c4459731ae149675b18Alan Viverette } 13385435a30ae552391f14009c4459731ae149675b18Alan Viverette 13395435a30ae552391f14009c4459731ae149675b18Alan Viverette /** 13405435a30ae552391f14009c4459731ae149675b18Alan Viverette * Wraps a content view in a FrameLayout. 13415435a30ae552391f14009c4459731ae149675b18Alan Viverette * 13425435a30ae552391f14009c4459731ae149675b18Alan Viverette * @param contentView the content view to wrap 13435435a30ae552391f14009c4459731ae149675b18Alan Viverette * @return a FrameLayout that wraps the content view 13445435a30ae552391f14009c4459731ae149675b18Alan Viverette */ 13455435a30ae552391f14009c4459731ae149675b18Alan Viverette private PopupDecorView createDecorView(View contentView) { 13465435a30ae552391f14009c4459731ae149675b18Alan Viverette final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams(); 13475435a30ae552391f14009c4459731ae149675b18Alan Viverette final int height; 13482665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr if (layoutParams != null && layoutParams.height == WRAP_CONTENT) { 13492665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr height = WRAP_CONTENT; 13505435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 13512665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr height = MATCH_PARENT; 13525435a30ae552391f14009c4459731ae149675b18Alan Viverette } 13535435a30ae552391f14009c4459731ae149675b18Alan Viverette 13545435a30ae552391f14009c4459731ae149675b18Alan Viverette final PopupDecorView decorView = new PopupDecorView(mContext); 13552665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr decorView.addView(contentView, MATCH_PARENT, height); 13565435a30ae552391f14009c4459731ae149675b18Alan Viverette decorView.setClipChildren(false); 13575435a30ae552391f14009c4459731ae149675b18Alan Viverette decorView.setClipToPadding(false); 13585435a30ae552391f14009c4459731ae149675b18Alan Viverette 13595435a30ae552391f14009c4459731ae149675b18Alan Viverette return decorView; 13605435a30ae552391f14009c4459731ae149675b18Alan Viverette } 13615435a30ae552391f14009c4459731ae149675b18Alan Viverette 13625435a30ae552391f14009c4459731ae149675b18Alan Viverette /** 13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Invoke the popup window by adding the content view to the window 13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * manager.</p> 13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The content view must be non-null when this method is invoked.</p> 13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param p the layout parameters of the popup's content view 13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void invokePopup(WindowManager.LayoutParams p) { 13710c0b768e1514280812321854db6dfba723c3d169Romain Guy if (mContext != null) { 13720c0b768e1514280812321854db6dfba723c3d169Romain Guy p.packageName = mContext.getPackageName(); 13730c0b768e1514280812321854db6dfba723c3d169Romain Guy } 13745435a30ae552391f14009c4459731ae149675b18Alan Viverette 13758fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final PopupDecorView decorView = mDecorView; 13768fd949e680c15d397084430d4907c16cedfacddaAlan Viverette decorView.setFitsSystemWindows(mLayoutInsetDecor); 13775435a30ae552391f14009c4459731ae149675b18Alan Viverette 13788fd949e680c15d397084430d4907c16cedfacddaAlan Viverette setLayoutDirectionFromAnchor(); 13795435a30ae552391f14009c4459731ae149675b18Alan Viverette 13808fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mWindowManager.addView(decorView, p); 138195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 138295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette if (mEnterTransition != null) { 138395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette decorView.requestEnterTransition(mEnterTransition); 138495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette } 13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1387b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio private void setLayoutDirectionFromAnchor() { 1388b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio if (mAnchor != null) { 1389b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio View anchor = mAnchor.get(); 1390b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio if (anchor != null && mPopupViewInitialLayoutDirectionInherited) { 13915435a30ae552391f14009c4459731ae149675b18Alan Viverette mDecorView.setLayoutDirection(anchor.getLayoutDirection()); 1392b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio } 1393b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio } 1394b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio } 1395b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio 1396489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr private int computeGravity() { 1397489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr int gravity = Gravity.START | Gravity.TOP; 1398489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr if (mClipToScreen || mClippingEnabled) { 1399489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr gravity |= Gravity.DISPLAY_CLIP_VERTICAL | Gravity.DISPLAY_CLIP_HORIZONTAL; 1400489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr } 1401489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr return gravity; 1402489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr } 1403489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr 14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Generate the layout parameters for the popup window.</p> 14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param token the window token used to bind the popup's window 14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the layout parameters to pass to the window manager 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1411e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette private WindowManager.LayoutParams createPopupLayoutParams(IBinder token) { 1412e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final WindowManager.LayoutParams p = new WindowManager.LayoutParams(); 1413e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1414e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // These gravity settings put the view at the top left corner of the 1415e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // screen. The view is then positioned to the appropriate location by 1416e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // setting the x and y offsets to match the anchor's bottom-left 1417e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // corner. 1418489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr p.gravity = computeGravity(); 1419e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.flags = computeFlags(p.flags); 1420e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.type = mWindowLayoutType; 1421e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.token = token; 1422e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.softInputMode = mSoftInputMode; 1423e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.windowAnimations = computeAnimationResource(); 1424e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBackground != null) { 14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.format = mBackground.getOpacity(); 14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.format = PixelFormat.TRANSLUCENT; 14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1430e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1431e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette if (mHeightMode < 0) { 1432e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.height = mLastHeight = mHeightMode; 1433e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } else { 1434e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.height = mLastHeight = mHeight; 1435e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } 1436e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1437e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette if (mWidthMode < 0) { 1438e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.width = mLastWidth = mWidthMode; 1439e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } else { 1440e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.width = mLastWidth = mWidth; 1441e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } 1442e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 14438216eb2221ad5ad6615d3966f43844268756f3c8Wale Ogunwale p.privateFlags = PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH 14448216eb2221ad5ad6615d3966f43844268756f3c8Wale Ogunwale | PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME; 1445a1eb439eee65138280c560f96e2a6896f9c9112cRobert Carr 1446e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // Used for debugging. 14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.setTitle("PopupWindow:" + Integer.toHexString(hashCode())); 14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return p; 14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int computeFlags(int curFlags) { 14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags &= ~( 14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES | 14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | 14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | 14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | 14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | 1459ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM | 1460ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell WindowManager.LayoutParams.FLAG_SPLIT_TOUCH); 14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(mIgnoreCheekPress) { 14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES; 14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mFocusable) { 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mInputMethodMode == INPUT_METHOD_NEEDED) { 14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mInputMethodMode == INPUT_METHOD_NOT_NEEDED) { 14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mTouchable) { 14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1475c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project if (mOutsideTouchable) { 14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH; 14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1478cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr if (!mClippingEnabled || mClipToScreen) { 14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; 14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 148146e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown if (isSplitTouchEnabled()) { 148201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown curFlags |= WindowManager.LayoutParams.FLAG_SPLIT_TOUCH; 148301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown } 1484ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell if (mLayoutInScreen) { 1485ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; 1486ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell } 14870bd1d0a15294345bf88b20df28466907f982cec7Adam Powell if (mLayoutInsetDecor) { 14880bd1d0a15294345bf88b20df28466907f982cec7Adam Powell curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; 14890bd1d0a15294345bf88b20df28466907f982cec7Adam Powell } 1490e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell if (mNotTouchModal) { 1491e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; 1492e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell } 1493393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale if (mAttachedInDecor) { 1494393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR; 1495393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale } 14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return curFlags; 14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1498393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int computeAnimationResource() { 15005435a30ae552391f14009c4459731ae149675b18Alan Viverette if (mAnimationStyle == ANIMATION_STYLE_DEFAULT) { 15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsDropdown) { 15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAboveAnchor 15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ? com.android.internal.R.style.Animation_DropDownUp 15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : com.android.internal.R.style.Animation_DropDownDown; 15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAnimationStyle; 15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1510560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1512560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * Positions the popup window on screen. When the popup window is too tall 1513560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * to fit under the anchor, a parent scroll view is seeked and scrolled up 1514560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * to reclaim space. If scrolling is not possible or not enough, the popup 1515560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * window gets moved on top of the anchor. 1516560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * <p> 1517f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette * The results of positioning are placed in {@code outParams}. 15185435a30ae552391f14009c4459731ae149675b18Alan Viverette * 15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the view on which the popup window must be anchored 1520f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette * @param outParams the layout parameters used to display the drop down 15219125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette * @param xOffset absolute horizontal offset from the left of the anchor 15226acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette * @param yOffset absolute vertical offset from the top of the anchor 1523560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * @param gravity horizontal gravity specifying popup alignment 15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is translated upwards to fit on screen 15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1526f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette private boolean findDropDownPosition(View anchor, WindowManager.LayoutParams outParams, 1527f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette int xOffset, int yOffset, int width, int height, int gravity) { 152862e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell final int anchorHeight = anchor.getHeight(); 1529560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int anchorWidth = anchor.getWidth(); 1530560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette if (mOverlapAnchor) { 1531f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette yOffset -= anchorHeight; 1532560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette } 1533560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 15346acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette // Initially, align to the bottom-left corner of the anchor plus offsets. 1535f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int[] drawingLocation = mTmpDrawingLocation; 1536f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette anchor.getLocationInWindow(drawingLocation); 1537f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette outParams.x = drawingLocation[0] + xOffset; 1538f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette outParams.y = drawingLocation[1] + anchorHeight + yOffset; 153954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 1540f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr final Rect displayFrame = new Rect(); 1541f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr anchor.getWindowVisibleDisplayFrame(displayFrame); 15422665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr if (width == MATCH_PARENT) { 1543f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr width = displayFrame.right - displayFrame.left; 1544f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr } 15452665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr if (height == MATCH_PARENT) { 1546f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr height = displayFrame.bottom - displayFrame.top; 1547f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr } 1548f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr 1549cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr // Let the window manager know to align the top to y. 1550cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr outParams.gravity = Gravity.LEFT | Gravity.TOP; 1551cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr outParams.width = width; 1552cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr outParams.height = height; 1553cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr 15546acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette // If we need to adjust for gravity RIGHT, align to the bottom-right 15556acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette // corner of the anchor (still accounting for offsets). 1556560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int hgrav = Gravity.getAbsoluteGravity(gravity, anchor.getLayoutDirection()) 1557560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette & Gravity.HORIZONTAL_GRAVITY_MASK; 155854c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell if (hgrav == Gravity.RIGHT) { 1559f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette outParams.x -= width - anchorWidth; 156054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell } 1561560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 1562f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int[] screenLocation = mTmpScreenLocation; 1563f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette anchor.getLocationOnScreen(screenLocation); 156454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 15659125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // First, attempt to fit the popup vertically without resizing. 15669125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final boolean fitsVertical = tryFitVertical(outParams, yOffset, height, 15679125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette anchorHeight, drawingLocation[1], screenLocation[1], displayFrame.top, 15689125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette displayFrame.bottom, false); 15699125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 15709125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // Next, attempt to fit the popup horizontally without resizing. 15719125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final boolean fitsHorizontal = tryFitHorizontal(outParams, xOffset, width, 15729125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette anchorWidth, drawingLocation[0], screenLocation[0], displayFrame.left, 15739125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette displayFrame.right, false); 15749125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 15759125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // If the popup still doesn't fit, attempt to scroll the parent. 15769125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (!fitsVertical || !fitsHorizontal) { 15779125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int scrollX = anchor.getScrollX(); 15789125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int scrollY = anchor.getScrollY(); 15799125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final Rect r = new Rect(scrollX, scrollY, scrollX + width + xOffset, 15809125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette scrollY + height + anchorHeight + yOffset); 15819125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (mAllowScrollingAnchorParent && anchor.requestRectangleOnScreen(r, true)) { 15829125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // Reset for the new anchor position. 15839125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette anchor.getLocationInWindow(drawingLocation); 15849125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.x = drawingLocation[0] + xOffset; 15859125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.y = drawingLocation[1] + anchorHeight + yOffset; 15869125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 15879125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // Preserve the gravity adjustment. 15889125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (hgrav == Gravity.RIGHT) { 15899125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.x -= width - anchorWidth; 15909125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 1591b7c1b20c8a5a4d4378ae91b4a1f12a34100df452Adam Powell } 15923e141685003939a9addce21ba2492ea3a8aebee6Romain Guy 15939125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // Try to fit the popup again and allowing resizing. 15949125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette tryFitVertical(outParams, yOffset, height, anchorHeight, drawingLocation[1], 15959125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette screenLocation[1], displayFrame.top, displayFrame.bottom, mClipToScreen); 15969125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette tryFitHorizontal(outParams, xOffset, width, anchorWidth, drawingLocation[0], 15979125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette screenLocation[0], displayFrame.left, displayFrame.right, mClipToScreen); 15989125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 159954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 16009125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // Return whether the popup's top edge is above the anchor's top edge. 16019125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return outParams.y < drawingLocation[1]; 16029125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 1603560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 16049125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette private boolean tryFitVertical(@NonNull LayoutParams outParams, int yOffset, int height, 16059125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette int anchorHeight, int drawingLocationY, int screenLocationY, int displayFrameTop, 16069125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette int displayFrameBottom, boolean allowResize) { 160755f0a99076477b77e017454e4356d908c43c2d22Alan Viverette final int winOffsetY = screenLocationY - drawingLocationY; 160855f0a99076477b77e017454e4356d908c43c2d22Alan Viverette final int anchorTopInScreen = outParams.y + winOffsetY; 16099125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int spaceBelow = displayFrameBottom - anchorTopInScreen; 161055f0a99076477b77e017454e4356d908c43c2d22Alan Viverette if (anchorTopInScreen >= 0 && height <= spaceBelow) { 16119125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return true; 16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1614b8320f7c58b46fea23e2827c82b46783b8c71b63Robert Carr final int spaceAbove = anchorTopInScreen - anchorHeight - displayFrameTop; 16159125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (height <= spaceAbove) { 16169125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // Move everything up. 16179125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (mOverlapAnchor) { 16189125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette yOffset += anchorHeight; 161956c2d337e02a275397fc9d0460dca90977f199acAdam Powell } 16209125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.y = drawingLocationY - height + yOffset; 16219125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16229125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return true; 16239125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 1624560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 16259125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (positionInDisplayVertical(outParams, height, drawingLocationY, screenLocationY, 16269125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette displayFrameTop, displayFrameBottom, allowResize)) { 16279125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return true; 16289125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 1629f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette 16309125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return false; 16319125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 163256c2d337e02a275397fc9d0460dca90977f199acAdam Powell 16339125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette private boolean positionInDisplayVertical(@NonNull LayoutParams outParams, int height, 16349125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette int drawingLocationY, int screenLocationY, int displayFrameTop, int displayFrameBottom, 16359125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette boolean canResize) { 16369125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette boolean fitsInDisplay = true; 16376acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette 16389125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int winOffsetY = screenLocationY - drawingLocationY; 16399125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.y += winOffsetY; 16409125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.height = height; 16419125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16429125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int bottom = outParams.y + height; 16439125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (bottom > displayFrameBottom) { 16449125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // The popup is too far down, move it back in. 16459125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.y -= bottom - displayFrameBottom; 16469125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 16476acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette 16489125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (outParams.y < displayFrameTop) { 16499125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // The popup is too far up, move it back in and clip if 16509125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // it's still too large. 16519125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.y = displayFrameTop; 16529125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16539125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int displayFrameHeight = displayFrameBottom - displayFrameTop; 16549125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (canResize && height > displayFrameHeight) { 16559125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.height = displayFrameHeight; 16569125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } else { 16579125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette fitsInDisplay = false; 16585f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell } 16599125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 16609125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16619125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.y -= winOffsetY; 1662f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette 16639125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return fitsInDisplay; 16649125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 16659125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16669125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette private boolean tryFitHorizontal(@NonNull LayoutParams outParams, int xOffset, int width, 16679125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette int anchorWidth, int drawingLocationX, int screenLocationX, int displayFrameLeft, 16689125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette int displayFrameRight, boolean allowResize) { 166955f0a99076477b77e017454e4356d908c43c2d22Alan Viverette final int winOffsetX = screenLocationX - drawingLocationX; 167055f0a99076477b77e017454e4356d908c43c2d22Alan Viverette final int anchorLeftInScreen = outParams.x + winOffsetX; 16719125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int spaceRight = displayFrameRight - anchorLeftInScreen; 167255f0a99076477b77e017454e4356d908c43c2d22Alan Viverette if (anchorLeftInScreen >= 0 && width <= spaceRight) { 16739125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return true; 167456c2d337e02a275397fc9d0460dca90977f199acAdam Powell } 167556c2d337e02a275397fc9d0460dca90977f199acAdam Powell 16769125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (positionInDisplayHorizontal(outParams, width, drawingLocationX, screenLocationX, 16779125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette displayFrameLeft, displayFrameRight, allowResize)) { 16789125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return true; 16799125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 16809125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16819125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return false; 16829125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 16839125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16849125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette private boolean positionInDisplayHorizontal(@NonNull LayoutParams outParams, int width, 16859125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette int drawingLocationX, int screenLocationX, int displayFrameLeft, int displayFrameRight, 16869125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette boolean canResize) { 16879125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette boolean fitsInDisplay = true; 16889125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16899125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // Use screen coordinates for comparison against display frame. 16909125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int winOffsetX = screenLocationX - drawingLocationX; 16919125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.x += winOffsetX; 16929125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16939125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int right = outParams.x + width; 16949125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (right > displayFrameRight) { 16959125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // The popup is too far right, move it back in. 16969125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.x -= right - displayFrameRight; 16979125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 16989125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16999125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (outParams.x < displayFrameLeft) { 17009125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // The popup is too far left, move it back in and clip if it's 17019125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // still too large. 17029125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.x = displayFrameLeft; 17039125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 17049125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int displayFrameWidth = displayFrameRight - displayFrameLeft; 17059125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (canResize && width > displayFrameWidth) { 17069125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.width = displayFrameWidth; 17079125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } else { 17089125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette fitsInDisplay = false; 17099125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 17109125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 17119125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 17129125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.x -= winOffsetX; 1713560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 17149125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return fitsInDisplay; 17159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17165435a30ae552391f14009c4459731ae149675b18Alan Viverette 17179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 17189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the maximum height that is available for the popup to be 17199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * completely shown. It is recommended that this height be the maximum for 17209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the popup's height, otherwise it is possible that the popup will be 17219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clipped. 17225435a30ae552391f14009c4459731ae149675b18Alan Viverette * 17239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor The view on which the popup window must be anchored. 17249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The maximum available height for the popup to be completely 17259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * shown. 17269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1727b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette public int getMaxAvailableHeight(@NonNull View anchor) { 17289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return getMaxAvailableHeight(anchor, 0); 17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 17329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the maximum height that is available for the popup to be 17339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * completely shown. It is recommended that this height be the maximum for 17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the popup's height, otherwise it is possible that the popup will be 17359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clipped. 17369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor The view on which the popup window must be anchored. 17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param yOffset y offset from the view's bottom edge 17399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The maximum available height for the popup to be completely 17409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * shown. 17419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1742b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette public int getMaxAvailableHeight(@NonNull View anchor, int yOffset) { 174398acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau return getMaxAvailableHeight(anchor, yOffset, false); 174498acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau } 17455435a30ae552391f14009c4459731ae149675b18Alan Viverette 174698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau /** 174798acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * Returns the maximum height that is available for the popup to be 174898acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * completely shown, optionally ignoring any bottom decorations such as 174998acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * the input method. It is recommended that this height be the maximum for 175098acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * the popup's height, otherwise it is possible that the popup will be 175198acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * clipped. 17525435a30ae552391f14009c4459731ae149675b18Alan Viverette * 175398acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @param anchor The view on which the popup window must be anchored. 175498acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @param yOffset y offset from the view's bottom edge 175598acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @param ignoreBottomDecorations if true, the height returned will be 175698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * all the way to the bottom of the display, ignoring any 175798acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * bottom decorations 175898acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @return The maximum available height for the popup to be completely 175998acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * shown. 176098acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau */ 1761b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette public int getMaxAvailableHeight( 1762b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette @NonNull View anchor, int yOffset, boolean ignoreBottomDecorations) { 17639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect displayFrame = new Rect(); 17648175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi if (ignoreBottomDecorations) { 17658175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi anchor.getWindowDisplayFrame(displayFrame); 17668175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi } else { 17678175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi anchor.getWindowVisibleDisplayFrame(displayFrame); 17688175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi } 17699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1770f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int[] anchorPos = mTmpDrawingLocation; 17719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anchor.getLocationOnScreen(anchorPos); 17725435a30ae552391f14009c4459731ae149675b18Alan Viverette 17738175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi final int bottomEdge = displayFrame.bottom; 1774ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg 1775ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg final int distanceToBottom; 1776ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg if (mOverlapAnchor) { 1777ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg distanceToBottom = bottomEdge - anchorPos[1] - yOffset; 1778ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg } else { 1779ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset; 1780ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg } 17819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset; 17829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // anchorPos[1] is distance from anchor to top of screen 17849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int returnedHeight = Math.max(distanceToBottom, distanceToTop); 17859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBackground != null) { 17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBackground.getPadding(mTempRect); 17875435a30ae552391f14009c4459731ae149675b18Alan Viverette returnedHeight -= mTempRect.top + mTempRect.bottom; 17889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17895435a30ae552391f14009c4459731ae149675b18Alan Viverette 17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return returnedHeight; 17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17925435a30ae552391f14009c4459731ae149675b18Alan Viverette 17939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 17947878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette * Disposes of the popup window. This method can be invoked only after 17957878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette * {@link #showAsDropDown(android.view.View)} has been executed. Failing 17967878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette * that, calling this method will have no effect. 17979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 17985435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #showAsDropDown(android.view.View) 17999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 18009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dismiss() { 18018fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (!isShowing() || mIsTransitioningToDismiss) { 1802e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette return; 1803e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } 180406f938e8aa56cd89ab0bdb04c8b946392c428dd1Svetoslav Ganov 18058fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final PopupDecorView decorView = mDecorView; 18068fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View contentView = mContentView; 18078fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 18088fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewGroup contentHolder; 18098fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewParent contentParent = contentView.getParent(); 18108fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (contentParent instanceof ViewGroup) { 18118fd949e680c15d397084430d4907c16cedfacddaAlan Viverette contentHolder = ((ViewGroup) contentParent); 18128fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } else { 18138fd949e680c15d397084430d4907c16cedfacddaAlan Viverette contentHolder = null; 18148fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 18158fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 18168fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // Ensure any ongoing or pending transitions are canceled. 18178fd949e680c15d397084430d4907c16cedfacddaAlan Viverette decorView.cancelTransitions(); 18188fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 1819e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette mIsShowing = false; 18208fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mIsTransitioningToDismiss = true; 1821b82d074038f4c8d86e1bd4f3fa4d3780bd4bcba5Craig Mautner 1822634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // This method may be called as part of window detachment, in which 1823634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // case the anchor view (and its root) will still return true from 1824634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // isAttachedToWindow() during execution of this method; however, we 1825634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // can expect the OnAttachStateChangeListener to have been called prior 1826634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // to executing this method, so we can rely on that instead. 182795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final Transition exitTransition = mExitTransition; 182821d361806c9e2dce5bae5b30f44be5ad87f32c22Alan Viverette if (mIsAnchorRootAttached && exitTransition != null && decorView.isLaidOut()) { 1829dbd299de2a07a2a0a490d4f37cf92870bf87d6c1Yohei Yukawa // The decor view is non-interactive and non-IME-focusable during exit transitions. 183095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final LayoutParams p = (LayoutParams) decorView.getLayoutParams(); 183195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette p.flags |= LayoutParams.FLAG_NOT_TOUCHABLE; 183295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette p.flags |= LayoutParams.FLAG_NOT_FOCUSABLE; 1833dbd299de2a07a2a0a490d4f37cf92870bf87d6c1Yohei Yukawa p.flags &= ~LayoutParams.FLAG_ALT_FOCUSABLE_IM; 183495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette mWindowManager.updateViewLayout(decorView, p); 183595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 1836634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // Once we start dismissing the decor view, all state (including 1837634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // the anchor root) needs to be moved to the decor view since we 1838634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // may open another popup while it's busy exiting. 1839634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette final View anchorRoot = mAnchorRoot != null ? mAnchorRoot.get() : null; 184091098574f90277128415e9593cce1e495cc51465Alan Viverette final Rect epicenter = getTransitionEpicenter(); 184195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette exitTransition.setEpicenterCallback(new EpicenterCallback() { 184295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette @Override 184395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette public Rect onGetEpicenter(Transition transition) { 184495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette return epicenter; 184595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette } 184695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette }); 1847634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette decorView.startExitTransition(exitTransition, anchorRoot, 1848634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette new TransitionListenerAdapter() { 1849634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette @Override 1850634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette public void onTransitionEnd(Transition transition) { 18517970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette dismissImmediate(decorView, contentHolder, contentView); 1852634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette } 1853634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette }); 1854e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } else { 18557970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette dismissImmediate(decorView, contentHolder, contentView); 18567878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette } 18577878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette 185895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette // Clears the anchor view. 1859f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette detachFromAnchor(); 18607970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette 18617970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette if (mOnDismissListener != null) { 18627970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette mOnDismissListener.onDismiss(); 18637970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette } 18645435a30ae552391f14009c4459731ae149675b18Alan Viverette } 18655435a30ae552391f14009c4459731ae149675b18Alan Viverette 186691098574f90277128415e9593cce1e495cc51465Alan Viverette /** 186791098574f90277128415e9593cce1e495cc51465Alan Viverette * Returns the window-relative epicenter bounds to be used by enter and 186891098574f90277128415e9593cce1e495cc51465Alan Viverette * exit transitions. 186991098574f90277128415e9593cce1e495cc51465Alan Viverette * <p> 187091098574f90277128415e9593cce1e495cc51465Alan Viverette * <strong>Note:</strong> This is distinct from the rect passed to 187191098574f90277128415e9593cce1e495cc51465Alan Viverette * {@link #setEpicenterBounds(Rect)}, which is anchor-relative. 187291098574f90277128415e9593cce1e495cc51465Alan Viverette * 187391098574f90277128415e9593cce1e495cc51465Alan Viverette * @return the window-relative epicenter bounds to be used by enter and 187491098574f90277128415e9593cce1e495cc51465Alan Viverette * exit transitions 187591098574f90277128415e9593cce1e495cc51465Alan Viverette */ 187691098574f90277128415e9593cce1e495cc51465Alan Viverette private Rect getTransitionEpicenter() { 187795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final View anchor = mAnchor != null ? mAnchor.get() : null; 187895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final View decor = mDecorView; 187995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette if (anchor == null || decor == null) { 188095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette return null; 188195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette } 188295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 188395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final int[] anchorLocation = anchor.getLocationOnScreen(); 188495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final int[] popupLocation = mDecorView.getLocationOnScreen(); 188595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 188695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette // Compute the position of the anchor relative to the popup. 188795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final Rect bounds = new Rect(0, 0, anchor.getWidth(), anchor.getHeight()); 188895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette bounds.offset(anchorLocation[0] - popupLocation[0], anchorLocation[1] - popupLocation[1]); 188991098574f90277128415e9593cce1e495cc51465Alan Viverette 189091098574f90277128415e9593cce1e495cc51465Alan Viverette // Use anchor-relative epicenter, if specified. 189191098574f90277128415e9593cce1e495cc51465Alan Viverette if (mEpicenterBounds != null) { 189291098574f90277128415e9593cce1e495cc51465Alan Viverette final int offsetX = bounds.left; 189391098574f90277128415e9593cce1e495cc51465Alan Viverette final int offsetY = bounds.top; 189491098574f90277128415e9593cce1e495cc51465Alan Viverette bounds.set(mEpicenterBounds); 189591098574f90277128415e9593cce1e495cc51465Alan Viverette bounds.offset(offsetX, offsetY); 189691098574f90277128415e9593cce1e495cc51465Alan Viverette } 189791098574f90277128415e9593cce1e495cc51465Alan Viverette 189895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette return bounds; 189995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette } 190095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 19015435a30ae552391f14009c4459731ae149675b18Alan Viverette /** 19025435a30ae552391f14009c4459731ae149675b18Alan Viverette * Removes the popup from the window manager and tears down the supporting 19035435a30ae552391f14009c4459731ae149675b18Alan Viverette * view hierarchy, if necessary. 19045435a30ae552391f14009c4459731ae149675b18Alan Viverette */ 19057970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette private void dismissImmediate(View decorView, ViewGroup contentHolder, View contentView) { 19068fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // If this method gets called and the decor view doesn't have a parent, 19078fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // then it was either never added or was already removed. That should 19088fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // never happen, but it's worth checking to avoid potential crashes. 19098fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (decorView.getParent() != null) { 19108fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mWindowManager.removeViewImmediate(decorView); 1911df4639a0135ea643b493067b3f7cd1e092346c78Alan Viverette } 1912df4639a0135ea643b493067b3f7cd1e092346c78Alan Viverette 19138fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (contentHolder != null) { 19148fd949e680c15d397084430d4907c16cedfacddaAlan Viverette contentHolder.removeView(contentView); 19159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19168fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 19178fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // This needs to stay until after all transitions have ended since we 19188fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // need the reference to cancel transitions in preparePopup(). 19198fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mDecorView = null; 1920697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView = null; 19218fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mIsTransitioningToDismiss = false; 19229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 19259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the listener to be called when the window is dismissed. 19265435a30ae552391f14009c4459731ae149675b18Alan Viverette * 19279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param onDismissListener The listener. 19289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 19299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setOnDismissListener(OnDismissListener onDismissListener) { 19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnDismissListener = onDismissListener; 19319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19325435a30ae552391f14009c4459731ae149675b18Alan Viverette 19339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 19349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Updates the state of the popup window, if it is currently being displayed, 1935259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * from the currently set state. 1936259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1937259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * This includes: 1938259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <ul> 1939259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setClippingEnabled(boolean)}</li> 1940259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setFocusable(boolean)}</li> 1941259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setIgnoreCheekPress()}</li> 1942259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setInputMethodMode(int)}</li> 1943259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setTouchable(boolean)}</li> 1944259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setAnimationStyle(int)}</li> 1945259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * </ul> 19469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 19479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update() { 19489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isShowing() || mContentView == null) { 19499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 19509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19515435a30ae552391f14009c4459731ae149675b18Alan Viverette 19525435a30ae552391f14009c4459731ae149675b18Alan Viverette final WindowManager.LayoutParams p = 19535435a30ae552391f14009c4459731ae149675b18Alan Viverette (WindowManager.LayoutParams) mDecorView.getLayoutParams(); 19545435a30ae552391f14009c4459731ae149675b18Alan Viverette 19559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean update = false; 19565435a30ae552391f14009c4459731ae149675b18Alan Viverette 19579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newAnim = computeAnimationResource(); 19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newAnim != p.windowAnimations) { 19599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.windowAnimations = newAnim; 19609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 19619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newFlags = computeFlags(p.flags); 19649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newFlags != p.flags) { 19659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.flags = newFlags; 19669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 19679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1968b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio 1969489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr final int newGravity = computeGravity(); 1970489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr if (newGravity != p.gravity) { 1971489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr p.gravity = newGravity; 1972489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr update = true; 1973489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr } 1974489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr 19759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (update) { 1976b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio setLayoutDirectionFromAnchor(); 19775435a30ae552391f14009c4459731ae149675b18Alan Viverette mWindowManager.updateViewLayout(mDecorView, p); 19789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1980d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy 1981d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy /** 1982259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the dimension of the popup window. 1983259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1984259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Calling this function also updates the window with the current popup 1985259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * state as described for {@link #update()}. 1986d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy * 1987c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param width the new width in pixels, must be >= 0 or -1 to ignore 1988c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param height the new height in pixels, must be >= 0 or -1 to ignore 1989d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy */ 1990d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy public void update(int width, int height) { 19915435a30ae552391f14009c4459731ae149675b18Alan Viverette final WindowManager.LayoutParams p = 19925435a30ae552391f14009c4459731ae149675b18Alan Viverette (WindowManager.LayoutParams) mDecorView.getLayoutParams(); 1993d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy update(p.x, p.y, width, height, false); 1994d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy } 19955435a30ae552391f14009c4459731ae149675b18Alan Viverette 19969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1997259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 1998259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1999259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Width and height can be set to -1 to update location only. Calling this 2000259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * function also updates the window with the current popup state as 2001259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * described for {@link #update()}. 20029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 20039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x the new x location 20049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y the new y location 2005c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param width the new width in pixels, must be >= 0 or -1 to ignore 2006c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param height the new height in pixels, must be >= 0 or -1 to ignore 20079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 20089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(int x, int y, int width, int height) { 20099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update(x, y, width, height, false); 20109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2013259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 2014259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 2015259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Width and height can be set to -1 to update location only. Calling this 2016259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * function also updates the window with the current popup state as 2017259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * described for {@link #update()}. 20189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 20199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x the new x location 20209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y the new y location 2021c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param width the new width in pixels, must be >= 0 or -1 to ignore 2022c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param height the new height in pixels, must be >= 0 or -1 to ignore 2023259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param force {@code true} to reposition the window even if the specified 2024259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * position already seems to correspond to the LayoutParams, 2025259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * {@code false} to only reposition if needed 20269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 20279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(int x, int y, int width, int height, boolean force) { 2028259c2840691a79634ffd8f63291ec21c21819542Alan Viverette if (width >= 0) { 20299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastWidth = width; 20309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setWidth(width); 20319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2033259c2840691a79634ffd8f63291ec21c21819542Alan Viverette if (height >= 0) { 20349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastHeight = height; 20359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setHeight(height); 20369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isShowing() || mContentView == null) { 20399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 20409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20425435a30ae552391f14009c4459731ae149675b18Alan Viverette final WindowManager.LayoutParams p = 20435435a30ae552391f14009c4459731ae149675b18Alan Viverette (WindowManager.LayoutParams) mDecorView.getLayoutParams(); 20449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean update = force; 20469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int finalWidth = mWidthMode < 0 ? mWidthMode : mLastWidth; 20489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (width != -1 && p.width != finalWidth) { 20499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.width = mLastWidth = finalWidth; 20509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 20519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int finalHeight = mHeightMode < 0 ? mHeightMode : mLastHeight; 20549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (height != -1 && p.height != finalHeight) { 20559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.height = mLastHeight = finalHeight; 20569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 20579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p.x != x) { 20609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.x = x; 20619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 20629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p.y != y) { 20659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.y = y; 20669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 20679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newAnim = computeAnimationResource(); 20709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newAnim != p.windowAnimations) { 20719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.windowAnimations = newAnim; 20729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 20739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newFlags = computeFlags(p.flags); 20769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newFlags != p.flags) { 20779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.flags = newFlags; 20789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 20799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 208098acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau 2081489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr final int newGravity = computeGravity(); 2082489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr if (newGravity != p.gravity) { 2083489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr p.gravity = newGravity; 2084489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr update = true; 2085489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr } 2086489c39d2db3be43e34c5ac55e09d8c17a5a04688Robert Carr 2087396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver int newAccessibilityIdOfAnchor = 2088396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver (mAnchor != null) ? mAnchor.get().getAccessibilityViewId() : -1; 2089396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver if (newAccessibilityIdOfAnchor != p.accessibilityIdOfAnchor) { 2090396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver p.accessibilityIdOfAnchor = newAccessibilityIdOfAnchor; 2091396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver update = true; 2092396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver } 2093396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver 20949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (update) { 2095b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio setLayoutDirectionFromAnchor(); 20965435a30ae552391f14009c4459731ae149675b18Alan Viverette mWindowManager.updateViewLayout(mDecorView, p); 20979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2101259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 2102259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 2103259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Calling this function also updates the window with the current popup 2104259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * state as described for {@link #update()}. 21059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 21069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the popup's anchor view 2107c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param width the new width in pixels, must be >= 0 or -1 to ignore 2108c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param height the new height in pixels, must be >= 0 or -1 to ignore 21099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 21109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(View anchor, int width, int height) { 2111b91d6d06b824aab4076fb985304a602806429042Alan Viverette update(anchor, false, 0, 0, width, height); 21129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2115259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 2116259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 2117259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Width and height can be set to -1 to update location only. Calling this 2118259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * function also updates the window with the current popup state as 2119259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * described for {@link #update()}. 2120259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 2121259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * If the view later scrolls to move {@code anchor} to a different 2122259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * location, the popup will be moved correspondingly. 21239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 21249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the popup's anchor view 21259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param xoff x offset from the view's left edge 21269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param yoff y offset from the view's bottom edge 2127c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param width the new width in pixels, must be >= 0 or -1 to ignore 2128c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param height the new height in pixels, must be >= 0 or -1 to ignore 21299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 21309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(View anchor, int xoff, int yoff, int width, int height) { 2131b91d6d06b824aab4076fb985304a602806429042Alan Viverette update(anchor, true, xoff, yoff, width, height); 2132105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 2133105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 2134105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private void update(View anchor, boolean updateLocation, int xoff, int yoff, 2135b91d6d06b824aab4076fb985304a602806429042Alan Viverette int width, int height) { 2136105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 21379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isShowing() || mContentView == null) { 21389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 21399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 214175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette final WeakReference<View> oldAnchor = mAnchor; 2142f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int gravity = mAnchoredGravity; 2143f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette 214475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette final boolean needsUpdate = updateLocation && (mAnchorXoff != xoff || mAnchorYoff != yoff); 214581f08086b44a117097960195d2c9072e29644962Gilles Debunne if (oldAnchor == null || oldAnchor.get() != anchor || (needsUpdate && !mIsDropdown)) { 2146f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette attachToAnchor(anchor, xoff, yoff, gravity); 214781f08086b44a117097960195d2c9072e29644962Gilles Debunne } else if (needsUpdate) { 214881f08086b44a117097960195d2c9072e29644962Gilles Debunne // No need to register again if this is a DropDown, showAsDropDown already did. 214981f08086b44a117097960195d2c9072e29644962Gilles Debunne mAnchorXoff = xoff; 215081f08086b44a117097960195d2c9072e29644962Gilles Debunne mAnchorYoff = yoff; 21519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2153f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final LayoutParams p = (LayoutParams) mDecorView.getLayoutParams(); 2154f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int oldGravity = p.gravity; 2155f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int oldWidth = p.width; 2156f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int oldHeight = p.height; 2157f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int oldX = p.x; 2158f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int oldY = p.y; 2159f95b2d9aabc2e989bd1d665e728922b1c529589aAlan Viverette 2160b91d6d06b824aab4076fb985304a602806429042Alan Viverette // If an explicit width/height has not specified, use the most recent 2161b91d6d06b824aab4076fb985304a602806429042Alan Viverette // explicitly specified value (either from setWidth/Height or update). 2162f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr if (width < 0) { 2163b91d6d06b824aab4076fb985304a602806429042Alan Viverette width = mWidth; 2164b91d6d06b824aab4076fb985304a602806429042Alan Viverette } 2165f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr if (height < 0) { 2166b91d6d06b824aab4076fb985304a602806429042Alan Viverette height = mHeight; 21679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2168105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 2169f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final boolean aboveAnchor = findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff, 2170f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette width, height, gravity); 2171f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette updateAboveAnchor(aboveAnchor); 2172b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio 2173f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final boolean paramsChanged = oldGravity != p.gravity || oldX != p.x || oldY != p.y 2174f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette || oldWidth != p.width || oldHeight != p.height; 2175cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr // If width and mWidth were both < 0 then we have a MATCH_PARENT/WRAP_CONTENT case. 2176cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr // findDropDownPosition will have resolved this to absolute values, 2177cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr // but we don't want to update mWidth/mHeight to these absolute values. 2178cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr update(p.x, p.y, width < 0 ? width : p.width, height < 0 ? height : p.height, paramsChanged); 21799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 21829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Listener that is called when this popup window is dismissed. 21839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 21849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnDismissListener { 21859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 21869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called when this popup window is dismissed. 21879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 21889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onDismiss(); 21899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2191f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette private void detachFromAnchor() { 2192634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette final View anchor = mAnchor != null ? mAnchor.get() : null; 21939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (anchor != null) { 2194e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final ViewTreeObserver vto = anchor.getViewTreeObserver(); 21959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project vto.removeOnScrollChangedListener(mOnScrollChangedListener); 21969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2197e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 2198634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette final View anchorRoot = mAnchorRoot != null ? mAnchorRoot.get() : null; 2199634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette if (anchorRoot != null) { 2200634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette anchorRoot.removeOnAttachStateChangeListener(mOnAnchorRootDetachedListener); 2201634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette } 2202634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 22039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnchor = null; 2204634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette mAnchorRoot = null; 2205634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette mIsAnchorRootAttached = false; 22069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2208f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette private void attachToAnchor(View anchor, int xoff, int yoff, int gravity) { 2209f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette detachFromAnchor(); 2210e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 2211e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final ViewTreeObserver vto = anchor.getViewTreeObserver(); 22129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (vto != null) { 22139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project vto.addOnScrollChangedListener(mOnScrollChangedListener); 22149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2216634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette final View anchorRoot = anchor.getRootView(); 2217634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette anchorRoot.addOnAttachStateChangeListener(mOnAnchorRootDetachedListener); 2218634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 2219634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette mAnchor = new WeakReference<>(anchor); 2220634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette mAnchorRoot = new WeakReference<>(anchorRoot); 2221634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette mIsAnchorRootAttached = anchorRoot.isAttachedToWindow(); 2222634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 22239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnchorXoff = xoff; 22249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnchorYoff = yoff; 222554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell mAnchoredGravity = gravity; 22269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22285435a30ae552391f14009c4459731ae149675b18Alan Viverette private class PopupDecorView extends FrameLayout { 22298fd949e680c15d397084430d4907c16cedfacddaAlan Viverette private TransitionListenerAdapter mPendingExitListener; 22308fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 22315435a30ae552391f14009c4459731ae149675b18Alan Viverette public PopupDecorView(Context context) { 22325435a30ae552391f14009c4459731ae149675b18Alan Viverette super(context); 22335435a30ae552391f14009c4459731ae149675b18Alan Viverette } 22349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 22369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean dispatchKeyEvent(KeyEvent event) { 22379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { 22384ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson if (getKeyDispatcherState() == null) { 22394ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson return super.dispatchKeyEvent(event); 22404ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson } 22414ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson 22425435a30ae552391f14009c4459731ae149675b18Alan Viverette if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { 22435435a30ae552391f14009c4459731ae149675b18Alan Viverette final KeyEvent.DispatcherState state = getKeyDispatcherState(); 2244b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown if (state != null) { 2245b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown state.startTracking(event, this); 2246b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } 22478d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn return true; 2248b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } else if (event.getAction() == KeyEvent.ACTION_UP) { 22495435a30ae552391f14009c4459731ae149675b18Alan Viverette final KeyEvent.DispatcherState state = getKeyDispatcherState(); 2250b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown if (state != null && state.isTracking(event) && !event.isCanceled()) { 2251b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown dismiss(); 2252b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown return true; 2253b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } 22548d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn } 22558d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn return super.dispatchKeyEvent(event); 22569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 22579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.dispatchKeyEvent(event); 22589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 22629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean dispatchTouchEvent(MotionEvent ev) { 22639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTouchInterceptor != null && mTouchInterceptor.onTouch(this, ev)) { 22649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 22659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.dispatchTouchEvent(ev); 22679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 22709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onTouchEvent(MotionEvent event) { 22719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int x = (int) event.getX(); 22729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int y = (int) event.getY(); 22735435a30ae552391f14009c4459731ae149675b18Alan Viverette 22749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((event.getAction() == MotionEvent.ACTION_DOWN) 22759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && ((x < 0) || (x >= getWidth()) || (y < 0) || (y >= getHeight()))) { 22769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dismiss(); 22779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 22789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (event.getAction() == MotionEvent.ACTION_OUTSIDE) { 22799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dismiss(); 22809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 22819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 22829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.onTouchEvent(event); 22839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22858fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 22868fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 22878fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Requests that an enter transition run after the next layout pass. 22888fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 22898fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void requestEnterTransition(Transition transition) { 22908fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewTreeObserver observer = getViewTreeObserver(); 22918fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (observer != null && transition != null) { 22928fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final Transition enterTransition = transition.clone(); 22938fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 22948fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // Postpone the enter transition after the first layout pass. 22958fd949e680c15d397084430d4907c16cedfacddaAlan Viverette observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 22968fd949e680c15d397084430d4907c16cedfacddaAlan Viverette @Override 22978fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void onGlobalLayout() { 22988fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewTreeObserver observer = getViewTreeObserver(); 22998fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (observer != null) { 23008fd949e680c15d397084430d4907c16cedfacddaAlan Viverette observer.removeOnGlobalLayoutListener(this); 23018fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 23028fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 230391098574f90277128415e9593cce1e495cc51465Alan Viverette final Rect epicenter = getTransitionEpicenter(); 230495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette enterTransition.setEpicenterCallback(new EpicenterCallback() { 230595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette @Override 230695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette public Rect onGetEpicenter(Transition transition) { 230795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette return epicenter; 230895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette } 230995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette }); 23108fd949e680c15d397084430d4907c16cedfacddaAlan Viverette startEnterTransition(enterTransition); 23118fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 23128fd949e680c15d397084430d4907c16cedfacddaAlan Viverette }); 23138fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 23148fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 23158fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 23168fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 23178fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Starts the pending enter transition, if one is set. 23188fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 23198fd949e680c15d397084430d4907c16cedfacddaAlan Viverette private void startEnterTransition(Transition enterTransition) { 23208fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final int count = getChildCount(); 23218fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 23228fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 23238fd949e680c15d397084430d4907c16cedfacddaAlan Viverette enterTransition.addTarget(child); 23248fd949e680c15d397084430d4907c16cedfacddaAlan Viverette child.setVisibility(View.INVISIBLE); 23258fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 23268fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 23278fd949e680c15d397084430d4907c16cedfacddaAlan Viverette TransitionManager.beginDelayedTransition(this, enterTransition); 23288fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 23298fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 23308fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 23318fd949e680c15d397084430d4907c16cedfacddaAlan Viverette child.setVisibility(View.VISIBLE); 23328fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 23338fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 23348fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 23358fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 23368fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Starts an exit transition immediately. 23378fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * <p> 23388fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * <strong>Note:</strong> The transition listener is guaranteed to have 23398fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * its {@code onTransitionEnd} method called even if the transition 23408fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * never starts; however, it may be called with a {@code null} argument. 23418fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 2342634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette public void startExitTransition(Transition transition, final View anchorRoot, 2343634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette final TransitionListener listener) { 23448fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (transition == null) { 23458fd949e680c15d397084430d4907c16cedfacddaAlan Viverette return; 23468fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 23478fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 2348634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // The anchor view's window may go away while we're executing our 2349634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // transition, in which case we need to end the transition 2350634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // immediately and execute the listener to remove the popup. 2351634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette anchorRoot.addOnAttachStateChangeListener(mOnAnchorRootDetachedListener); 2352634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 23538fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // The exit listener MUST be called for cleanup, even if the 23548fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // transition never starts or ends. Stash it for later. 23558fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mPendingExitListener = new TransitionListenerAdapter() { 23568fd949e680c15d397084430d4907c16cedfacddaAlan Viverette @Override 23578fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void onTransitionEnd(Transition transition) { 2358634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette anchorRoot.removeOnAttachStateChangeListener(mOnAnchorRootDetachedListener); 23598fd949e680c15d397084430d4907c16cedfacddaAlan Viverette listener.onTransitionEnd(transition); 23608fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 23618fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // The listener was called. Our job here is done. 23628fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mPendingExitListener = null; 23638fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 23648fd949e680c15d397084430d4907c16cedfacddaAlan Viverette }; 23658fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 23668fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final Transition exitTransition = transition.clone(); 23678fd949e680c15d397084430d4907c16cedfacddaAlan Viverette exitTransition.addListener(mPendingExitListener); 23688fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 23698fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final int count = getChildCount(); 23708fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 23718fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 23728fd949e680c15d397084430d4907c16cedfacddaAlan Viverette exitTransition.addTarget(child); 23738fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 23748fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 23758fd949e680c15d397084430d4907c16cedfacddaAlan Viverette TransitionManager.beginDelayedTransition(this, exitTransition); 23768fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 23778fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 23788fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 23798fd949e680c15d397084430d4907c16cedfacddaAlan Viverette child.setVisibility(View.INVISIBLE); 23808fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 23818fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 23828fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 23838fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 23848fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Cancels all pending or current transitions. 23858fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 23868fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void cancelTransitions() { 23878fd949e680c15d397084430d4907c16cedfacddaAlan Viverette TransitionManager.endTransitions(this); 23888fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 23898fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (mPendingExitListener != null) { 23908fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mPendingExitListener.onTransitionEnd(null); 23918fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 23928fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 2393634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 2394634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette private final OnAttachStateChangeListener mOnAnchorRootDetachedListener = 2395634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette new OnAttachStateChangeListener() { 2396634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette @Override 2397634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette public void onViewAttachedToWindow(View v) {} 2398634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 2399634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette @Override 2400634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette public void onViewDetachedFromWindow(View v) { 2401634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette v.removeOnAttachStateChangeListener(this); 2402634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 2403634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette TransitionManager.endTransitions(PopupDecorView.this); 2404634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette } 2405634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette }; 24065435a30ae552391f14009c4459731ae149675b18Alan Viverette } 24075435a30ae552391f14009c4459731ae149675b18Alan Viverette 24085435a30ae552391f14009c4459731ae149675b18Alan Viverette private class PopupBackgroundView extends FrameLayout { 24095435a30ae552391f14009c4459731ae149675b18Alan Viverette public PopupBackgroundView(Context context) { 24105435a30ae552391f14009c4459731ae149675b18Alan Viverette super(context); 24115435a30ae552391f14009c4459731ae149675b18Alan Viverette } 241275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 241375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov @Override 24145435a30ae552391f14009c4459731ae149675b18Alan Viverette protected int[] onCreateDrawableState(int extraSpace) { 24155435a30ae552391f14009c4459731ae149675b18Alan Viverette if (mAboveAnchor) { 24165435a30ae552391f14009c4459731ae149675b18Alan Viverette final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 24175435a30ae552391f14009c4459731ae149675b18Alan Viverette View.mergeDrawableStates(drawableState, ABOVE_ANCHOR_STATE_SET); 24185435a30ae552391f14009c4459731ae149675b18Alan Viverette return drawableState; 241975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } else { 24205435a30ae552391f14009c4459731ae149675b18Alan Viverette return super.onCreateDrawableState(extraSpace); 242175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 242275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 24239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2425