PopupWindow.java revision c129b58ad108b898ab829b6389ccf2b9196211a7
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 13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Generate the layout parameters for the popup window.</p> 13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param token the window token used to bind the popup's window 14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the layout parameters to pass to the window manager 14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1403e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette private WindowManager.LayoutParams createPopupLayoutParams(IBinder token) { 1404e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final WindowManager.LayoutParams p = new WindowManager.LayoutParams(); 1405e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1406e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // These gravity settings put the view at the top left corner of the 1407e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // screen. The view is then positioned to the appropriate location by 1408e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // setting the x and y offsets to match the anchor's bottom-left 1409e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // corner. 1410aac0d4ed026d1cfbcf3fa81c6e4eb96f4347ca17Fabrice Di Meglio p.gravity = Gravity.START | Gravity.TOP; 1411e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.flags = computeFlags(p.flags); 1412e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.type = mWindowLayoutType; 1413e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.token = token; 1414e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.softInputMode = mSoftInputMode; 1415e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.windowAnimations = computeAnimationResource(); 1416e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBackground != null) { 14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.format = mBackground.getOpacity(); 14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.format = PixelFormat.TRANSLUCENT; 14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1422e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1423e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette if (mHeightMode < 0) { 1424e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.height = mLastHeight = mHeightMode; 1425e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } else { 1426e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.height = mLastHeight = mHeight; 1427e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } 1428e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1429e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette if (mWidthMode < 0) { 1430e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.width = mLastWidth = mWidthMode; 1431e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } else { 1432e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.width = mLastWidth = mWidth; 1433e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } 1434e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 14358216eb2221ad5ad6615d3966f43844268756f3c8Wale Ogunwale p.privateFlags = PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH 14368216eb2221ad5ad6615d3966f43844268756f3c8Wale Ogunwale | PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME; 1437a1eb439eee65138280c560f96e2a6896f9c9112cRobert Carr 1438e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // Used for debugging. 14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.setTitle("PopupWindow:" + Integer.toHexString(hashCode())); 14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return p; 14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int computeFlags(int curFlags) { 14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags &= ~( 14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES | 14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | 14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | 14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | 14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | 1451ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM | 1452ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell WindowManager.LayoutParams.FLAG_SPLIT_TOUCH); 14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(mIgnoreCheekPress) { 14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES; 14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mFocusable) { 14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mInputMethodMode == INPUT_METHOD_NEEDED) { 14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mInputMethodMode == INPUT_METHOD_NOT_NEEDED) { 14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mTouchable) { 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1467c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project if (mOutsideTouchable) { 14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH; 14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1470cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr if (!mClippingEnabled || mClipToScreen) { 14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; 14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 147346e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown if (isSplitTouchEnabled()) { 147401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown curFlags |= WindowManager.LayoutParams.FLAG_SPLIT_TOUCH; 147501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown } 1476ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell if (mLayoutInScreen) { 1477ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; 1478ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell } 14790bd1d0a15294345bf88b20df28466907f982cec7Adam Powell if (mLayoutInsetDecor) { 14800bd1d0a15294345bf88b20df28466907f982cec7Adam Powell curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; 14810bd1d0a15294345bf88b20df28466907f982cec7Adam Powell } 1482e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell if (mNotTouchModal) { 1483e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; 1484e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell } 1485393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale if (mAttachedInDecor) { 1486393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR; 1487393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale } 14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return curFlags; 14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1490393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int computeAnimationResource() { 14925435a30ae552391f14009c4459731ae149675b18Alan Viverette if (mAnimationStyle == ANIMATION_STYLE_DEFAULT) { 14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsDropdown) { 14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAboveAnchor 14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ? com.android.internal.R.style.Animation_DropDownUp 14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : com.android.internal.R.style.Animation_DropDownDown; 14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAnimationStyle; 15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1502560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1504560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * Positions the popup window on screen. When the popup window is too tall 1505560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * to fit under the anchor, a parent scroll view is seeked and scrolled up 1506560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * to reclaim space. If scrolling is not possible or not enough, the popup 1507560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * window gets moved on top of the anchor. 1508560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * <p> 1509f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette * The results of positioning are placed in {@code outParams}. 15105435a30ae552391f14009c4459731ae149675b18Alan Viverette * 15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the view on which the popup window must be anchored 1512f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette * @param outParams the layout parameters used to display the drop down 15139125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette * @param xOffset absolute horizontal offset from the left of the anchor 15146acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette * @param yOffset absolute vertical offset from the top of the anchor 1515560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * @param gravity horizontal gravity specifying popup alignment 15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is translated upwards to fit on screen 15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1518f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette private boolean findDropDownPosition(View anchor, WindowManager.LayoutParams outParams, 1519f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette int xOffset, int yOffset, int width, int height, int gravity) { 152062e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell final int anchorHeight = anchor.getHeight(); 1521560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int anchorWidth = anchor.getWidth(); 1522560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette if (mOverlapAnchor) { 1523f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette yOffset -= anchorHeight; 1524560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette } 1525560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 15266acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette // Initially, align to the bottom-left corner of the anchor plus offsets. 1527f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int[] drawingLocation = mTmpDrawingLocation; 1528f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette anchor.getLocationInWindow(drawingLocation); 1529f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette outParams.x = drawingLocation[0] + xOffset; 1530f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette outParams.y = drawingLocation[1] + anchorHeight + yOffset; 153154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 1532f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr final Rect displayFrame = new Rect(); 1533f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr anchor.getWindowVisibleDisplayFrame(displayFrame); 15342665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr if (width == MATCH_PARENT) { 1535f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr width = displayFrame.right - displayFrame.left; 15362665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr } else if (width == WRAP_CONTENT) { 15372665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr width = mContentView.getMeasuredWidth(); 1538f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr } 15392665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr if (height == MATCH_PARENT) { 1540f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr height = displayFrame.bottom - displayFrame.top; 15412665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr } else if (height == WRAP_CONTENT) { 15422665604edda9d5cfb6aa6b94a654982951ba20d3Robert Carr height = mContentView.getMeasuredHeight(); 1543f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr } 1544f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr 1545cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr // Let the window manager know to align the top to y. 1546cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr outParams.gravity = Gravity.LEFT | Gravity.TOP; 1547cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr outParams.width = width; 1548cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr outParams.height = height; 1549cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr 15506acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette // If we need to adjust for gravity RIGHT, align to the bottom-right 15516acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette // corner of the anchor (still accounting for offsets). 1552560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int hgrav = Gravity.getAbsoluteGravity(gravity, anchor.getLayoutDirection()) 1553560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette & Gravity.HORIZONTAL_GRAVITY_MASK; 155454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell if (hgrav == Gravity.RIGHT) { 1555f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette outParams.x -= width - anchorWidth; 155654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell } 1557560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 1558f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int[] screenLocation = mTmpScreenLocation; 1559f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette anchor.getLocationOnScreen(screenLocation); 156054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 15619125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // First, attempt to fit the popup vertically without resizing. 15629125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final boolean fitsVertical = tryFitVertical(outParams, yOffset, height, 15639125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette anchorHeight, drawingLocation[1], screenLocation[1], displayFrame.top, 15649125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette displayFrame.bottom, false); 15659125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 15669125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // Next, attempt to fit the popup horizontally without resizing. 15679125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final boolean fitsHorizontal = tryFitHorizontal(outParams, xOffset, width, 15689125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette anchorWidth, drawingLocation[0], screenLocation[0], displayFrame.left, 15699125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette displayFrame.right, false); 15709125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 15719125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // If the popup still doesn't fit, attempt to scroll the parent. 15729125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (!fitsVertical || !fitsHorizontal) { 15739125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int scrollX = anchor.getScrollX(); 15749125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int scrollY = anchor.getScrollY(); 15759125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final Rect r = new Rect(scrollX, scrollY, scrollX + width + xOffset, 15769125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette scrollY + height + anchorHeight + yOffset); 15779125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (mAllowScrollingAnchorParent && anchor.requestRectangleOnScreen(r, true)) { 15789125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // Reset for the new anchor position. 15799125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette anchor.getLocationInWindow(drawingLocation); 15809125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.x = drawingLocation[0] + xOffset; 15819125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.y = drawingLocation[1] + anchorHeight + yOffset; 15829125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 15839125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // Preserve the gravity adjustment. 15849125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (hgrav == Gravity.RIGHT) { 15859125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.x -= width - anchorWidth; 15869125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 1587b7c1b20c8a5a4d4378ae91b4a1f12a34100df452Adam Powell } 15883e141685003939a9addce21ba2492ea3a8aebee6Romain Guy 15899125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // Try to fit the popup again and allowing resizing. 15909125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette tryFitVertical(outParams, yOffset, height, anchorHeight, drawingLocation[1], 15919125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette screenLocation[1], displayFrame.top, displayFrame.bottom, mClipToScreen); 15929125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette tryFitHorizontal(outParams, xOffset, width, anchorWidth, drawingLocation[0], 15939125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette screenLocation[0], displayFrame.left, displayFrame.right, mClipToScreen); 15949125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 159554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 15969125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // Return whether the popup's top edge is above the anchor's top edge. 15979125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return outParams.y < drawingLocation[1]; 15989125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 1599560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 16009125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette private boolean tryFitVertical(@NonNull LayoutParams outParams, int yOffset, int height, 16019125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette int anchorHeight, int drawingLocationY, int screenLocationY, int displayFrameTop, 16029125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette int displayFrameBottom, boolean allowResize) { 160355f0a99076477b77e017454e4356d908c43c2d22Alan Viverette final int winOffsetY = screenLocationY - drawingLocationY; 160455f0a99076477b77e017454e4356d908c43c2d22Alan Viverette final int anchorTopInScreen = outParams.y + winOffsetY; 16059125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int spaceBelow = displayFrameBottom - anchorTopInScreen; 160655f0a99076477b77e017454e4356d908c43c2d22Alan Viverette if (anchorTopInScreen >= 0 && height <= spaceBelow) { 16079125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return true; 16089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1610b8320f7c58b46fea23e2827c82b46783b8c71b63Robert Carr final int spaceAbove = anchorTopInScreen - anchorHeight - displayFrameTop; 16119125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (height <= spaceAbove) { 16129125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // Move everything up. 16139125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (mOverlapAnchor) { 16149125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette yOffset += anchorHeight; 161556c2d337e02a275397fc9d0460dca90977f199acAdam Powell } 16169125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.y = drawingLocationY - height + yOffset; 16179125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16189125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return true; 16199125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 1620560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 16219125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (positionInDisplayVertical(outParams, height, drawingLocationY, screenLocationY, 16229125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette displayFrameTop, displayFrameBottom, allowResize)) { 16239125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return true; 16249125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 1625f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette 16269125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return false; 16279125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 162856c2d337e02a275397fc9d0460dca90977f199acAdam Powell 16299125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette private boolean positionInDisplayVertical(@NonNull LayoutParams outParams, int height, 16309125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette int drawingLocationY, int screenLocationY, int displayFrameTop, int displayFrameBottom, 16319125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette boolean canResize) { 16329125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette boolean fitsInDisplay = true; 16336acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette 16349125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int winOffsetY = screenLocationY - drawingLocationY; 16359125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.y += winOffsetY; 16369125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.height = height; 16379125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16389125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int bottom = outParams.y + height; 16399125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (bottom > displayFrameBottom) { 16409125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // The popup is too far down, move it back in. 16419125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.y -= bottom - displayFrameBottom; 16429125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 16436acf2f909b3f2a8f00775cfe3bd48cd0f44a577dAlan Viverette 16449125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (outParams.y < displayFrameTop) { 16459125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // The popup is too far up, move it back in and clip if 16469125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // it's still too large. 16479125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.y = displayFrameTop; 16489125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16499125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int displayFrameHeight = displayFrameBottom - displayFrameTop; 16509125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (canResize && height > displayFrameHeight) { 16519125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.height = displayFrameHeight; 16529125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } else { 16539125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette fitsInDisplay = false; 16545f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell } 16559125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 16569125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16579125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.y -= winOffsetY; 1658f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette 16599125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return fitsInDisplay; 16609125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 16619125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16629125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette private boolean tryFitHorizontal(@NonNull LayoutParams outParams, int xOffset, int width, 16639125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette int anchorWidth, int drawingLocationX, int screenLocationX, int displayFrameLeft, 16649125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette int displayFrameRight, boolean allowResize) { 166555f0a99076477b77e017454e4356d908c43c2d22Alan Viverette final int winOffsetX = screenLocationX - drawingLocationX; 166655f0a99076477b77e017454e4356d908c43c2d22Alan Viverette final int anchorLeftInScreen = outParams.x + winOffsetX; 16679125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int spaceRight = displayFrameRight - anchorLeftInScreen; 166855f0a99076477b77e017454e4356d908c43c2d22Alan Viverette if (anchorLeftInScreen >= 0 && width <= spaceRight) { 16699125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return true; 167056c2d337e02a275397fc9d0460dca90977f199acAdam Powell } 167156c2d337e02a275397fc9d0460dca90977f199acAdam Powell 16729125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (positionInDisplayHorizontal(outParams, width, drawingLocationX, screenLocationX, 16739125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette displayFrameLeft, displayFrameRight, allowResize)) { 16749125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return true; 16759125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 16769125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16779125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return false; 16789125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 16799125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16809125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette private boolean positionInDisplayHorizontal(@NonNull LayoutParams outParams, int width, 16819125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette int drawingLocationX, int screenLocationX, int displayFrameLeft, int displayFrameRight, 16829125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette boolean canResize) { 16839125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette boolean fitsInDisplay = true; 16849125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16859125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // Use screen coordinates for comparison against display frame. 16869125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int winOffsetX = screenLocationX - drawingLocationX; 16879125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.x += winOffsetX; 16889125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16899125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int right = outParams.x + width; 16909125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (right > displayFrameRight) { 16919125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // The popup is too far right, move it back in. 16929125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.x -= right - displayFrameRight; 16939125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 16949125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 16959125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (outParams.x < displayFrameLeft) { 16969125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // The popup is too far left, move it back in and clip if it's 16979125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette // still too large. 16989125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.x = displayFrameLeft; 16999125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 17009125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette final int displayFrameWidth = displayFrameRight - displayFrameLeft; 17019125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette if (canResize && width > displayFrameWidth) { 17029125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.width = displayFrameWidth; 17039125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } else { 17049125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette fitsInDisplay = false; 17059125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 17069125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette } 17079125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette 17089125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette outParams.x -= winOffsetX; 1709560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 17109125fbacd85a4a0b8993886aacfe66091cd4f463Alan Viverette return fitsInDisplay; 17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17125435a30ae552391f14009c4459731ae149675b18Alan Viverette 17139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 17149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the maximum height that is available for the popup to be 17159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * completely shown. It is recommended that this height be the maximum for 17169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the popup's height, otherwise it is possible that the popup will be 17179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clipped. 17185435a30ae552391f14009c4459731ae149675b18Alan Viverette * 17199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor The view on which the popup window must be anchored. 17209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The maximum available height for the popup to be completely 17219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * shown. 17229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1723b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette public int getMaxAvailableHeight(@NonNull View anchor) { 17249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return getMaxAvailableHeight(anchor, 0); 17259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 17289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the maximum height that is available for the popup to be 17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * completely shown. It is recommended that this height be the maximum for 17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the popup's height, otherwise it is possible that the popup will be 17319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clipped. 17329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 17339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor The view on which the popup window must be anchored. 17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param yOffset y offset from the view's bottom edge 17359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The maximum available height for the popup to be completely 17369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * shown. 17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1738b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette public int getMaxAvailableHeight(@NonNull View anchor, int yOffset) { 173998acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau return getMaxAvailableHeight(anchor, yOffset, false); 174098acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau } 17415435a30ae552391f14009c4459731ae149675b18Alan Viverette 174298acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau /** 174398acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * Returns the maximum height that is available for the popup to be 174498acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * completely shown, optionally ignoring any bottom decorations such as 174598acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * the input method. It is recommended that this height be the maximum for 174698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * the popup's height, otherwise it is possible that the popup will be 174798acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * clipped. 17485435a30ae552391f14009c4459731ae149675b18Alan Viverette * 174998acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @param anchor The view on which the popup window must be anchored. 175098acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @param yOffset y offset from the view's bottom edge 175198acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @param ignoreBottomDecorations if true, the height returned will be 175298acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * all the way to the bottom of the display, ignoring any 175398acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * bottom decorations 175498acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @return The maximum available height for the popup to be completely 175598acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * shown. 175698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau */ 1757b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette public int getMaxAvailableHeight( 1758b854d07a1a0fcd29c8f10255e616d387b9d436ccAlan Viverette @NonNull View anchor, int yOffset, boolean ignoreBottomDecorations) { 17599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect displayFrame = new Rect(); 17608175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi if (ignoreBottomDecorations) { 17618175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi anchor.getWindowDisplayFrame(displayFrame); 17628175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi } else { 17638175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi anchor.getWindowVisibleDisplayFrame(displayFrame); 17648175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi } 17659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1766f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int[] anchorPos = mTmpDrawingLocation; 17679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anchor.getLocationOnScreen(anchorPos); 17685435a30ae552391f14009c4459731ae149675b18Alan Viverette 17698175846ed686077736c985f0ae4d236b7a4c647cJorim Jaggi final int bottomEdge = displayFrame.bottom; 1770ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg 1771ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg final int distanceToBottom; 1772ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg if (mOverlapAnchor) { 1773ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg distanceToBottom = bottomEdge - anchorPos[1] - yOffset; 1774ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg } else { 1775ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset; 1776ed3912692f0ba8a647d795462e20fcdb67adbacbOren Blasberg } 17779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset; 17789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // anchorPos[1] is distance from anchor to top of screen 17809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int returnedHeight = Math.max(distanceToBottom, distanceToTop); 17819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBackground != null) { 17829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBackground.getPadding(mTempRect); 17835435a30ae552391f14009c4459731ae149675b18Alan Viverette returnedHeight -= mTempRect.top + mTempRect.bottom; 17849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17855435a30ae552391f14009c4459731ae149675b18Alan Viverette 17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return returnedHeight; 17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17885435a30ae552391f14009c4459731ae149675b18Alan Viverette 17899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 17907878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette * Disposes of the popup window. This method can be invoked only after 17917878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette * {@link #showAsDropDown(android.view.View)} has been executed. Failing 17927878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette * that, calling this method will have no effect. 17939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 17945435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #showAsDropDown(android.view.View) 17959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 17969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dismiss() { 17978fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (!isShowing() || mIsTransitioningToDismiss) { 1798e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette return; 1799e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } 180006f938e8aa56cd89ab0bdb04c8b946392c428dd1Svetoslav Ganov 18018fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final PopupDecorView decorView = mDecorView; 18028fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View contentView = mContentView; 18038fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 18048fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewGroup contentHolder; 18058fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewParent contentParent = contentView.getParent(); 18068fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (contentParent instanceof ViewGroup) { 18078fd949e680c15d397084430d4907c16cedfacddaAlan Viverette contentHolder = ((ViewGroup) contentParent); 18088fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } else { 18098fd949e680c15d397084430d4907c16cedfacddaAlan Viverette contentHolder = null; 18108fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 18118fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 18128fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // Ensure any ongoing or pending transitions are canceled. 18138fd949e680c15d397084430d4907c16cedfacddaAlan Viverette decorView.cancelTransitions(); 18148fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 1815e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette mIsShowing = false; 18168fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mIsTransitioningToDismiss = true; 1817b82d074038f4c8d86e1bd4f3fa4d3780bd4bcba5Craig Mautner 1818634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // This method may be called as part of window detachment, in which 1819634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // case the anchor view (and its root) will still return true from 1820634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // isAttachedToWindow() during execution of this method; however, we 1821634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // can expect the OnAttachStateChangeListener to have been called prior 1822634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // to executing this method, so we can rely on that instead. 182395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final Transition exitTransition = mExitTransition; 182421d361806c9e2dce5bae5b30f44be5ad87f32c22Alan Viverette if (mIsAnchorRootAttached && exitTransition != null && decorView.isLaidOut()) { 1825dbd299de2a07a2a0a490d4f37cf92870bf87d6c1Yohei Yukawa // The decor view is non-interactive and non-IME-focusable during exit transitions. 182695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final LayoutParams p = (LayoutParams) decorView.getLayoutParams(); 182795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette p.flags |= LayoutParams.FLAG_NOT_TOUCHABLE; 182895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette p.flags |= LayoutParams.FLAG_NOT_FOCUSABLE; 1829dbd299de2a07a2a0a490d4f37cf92870bf87d6c1Yohei Yukawa p.flags &= ~LayoutParams.FLAG_ALT_FOCUSABLE_IM; 183095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette mWindowManager.updateViewLayout(decorView, p); 183195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 1832634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // Once we start dismissing the decor view, all state (including 1833634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // the anchor root) needs to be moved to the decor view since we 1834634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // may open another popup while it's busy exiting. 1835634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette final View anchorRoot = mAnchorRoot != null ? mAnchorRoot.get() : null; 183691098574f90277128415e9593cce1e495cc51465Alan Viverette final Rect epicenter = getTransitionEpicenter(); 183795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette exitTransition.setEpicenterCallback(new EpicenterCallback() { 183895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette @Override 183995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette public Rect onGetEpicenter(Transition transition) { 184095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette return epicenter; 184195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette } 184295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette }); 1843634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette decorView.startExitTransition(exitTransition, anchorRoot, 1844634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette new TransitionListenerAdapter() { 1845634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette @Override 1846634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette public void onTransitionEnd(Transition transition) { 18477970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette dismissImmediate(decorView, contentHolder, contentView); 1848634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette } 1849634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette }); 1850e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } else { 18517970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette dismissImmediate(decorView, contentHolder, contentView); 18527878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette } 18537878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette 185495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette // Clears the anchor view. 1855f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette detachFromAnchor(); 18567970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette 18577970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette if (mOnDismissListener != null) { 18587970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette mOnDismissListener.onDismiss(); 18597970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette } 18605435a30ae552391f14009c4459731ae149675b18Alan Viverette } 18615435a30ae552391f14009c4459731ae149675b18Alan Viverette 186291098574f90277128415e9593cce1e495cc51465Alan Viverette /** 186391098574f90277128415e9593cce1e495cc51465Alan Viverette * Returns the window-relative epicenter bounds to be used by enter and 186491098574f90277128415e9593cce1e495cc51465Alan Viverette * exit transitions. 186591098574f90277128415e9593cce1e495cc51465Alan Viverette * <p> 186691098574f90277128415e9593cce1e495cc51465Alan Viverette * <strong>Note:</strong> This is distinct from the rect passed to 186791098574f90277128415e9593cce1e495cc51465Alan Viverette * {@link #setEpicenterBounds(Rect)}, which is anchor-relative. 186891098574f90277128415e9593cce1e495cc51465Alan Viverette * 186991098574f90277128415e9593cce1e495cc51465Alan Viverette * @return the window-relative epicenter bounds to be used by enter and 187091098574f90277128415e9593cce1e495cc51465Alan Viverette * exit transitions 187191098574f90277128415e9593cce1e495cc51465Alan Viverette */ 187291098574f90277128415e9593cce1e495cc51465Alan Viverette private Rect getTransitionEpicenter() { 187395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final View anchor = mAnchor != null ? mAnchor.get() : null; 187495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final View decor = mDecorView; 187595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette if (anchor == null || decor == null) { 187695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette return null; 187795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette } 187895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 187995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final int[] anchorLocation = anchor.getLocationOnScreen(); 188095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final int[] popupLocation = mDecorView.getLocationOnScreen(); 188195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 188295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette // Compute the position of the anchor relative to the popup. 188395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final Rect bounds = new Rect(0, 0, anchor.getWidth(), anchor.getHeight()); 188495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette bounds.offset(anchorLocation[0] - popupLocation[0], anchorLocation[1] - popupLocation[1]); 188591098574f90277128415e9593cce1e495cc51465Alan Viverette 188691098574f90277128415e9593cce1e495cc51465Alan Viverette // Use anchor-relative epicenter, if specified. 188791098574f90277128415e9593cce1e495cc51465Alan Viverette if (mEpicenterBounds != null) { 188891098574f90277128415e9593cce1e495cc51465Alan Viverette final int offsetX = bounds.left; 188991098574f90277128415e9593cce1e495cc51465Alan Viverette final int offsetY = bounds.top; 189091098574f90277128415e9593cce1e495cc51465Alan Viverette bounds.set(mEpicenterBounds); 189191098574f90277128415e9593cce1e495cc51465Alan Viverette bounds.offset(offsetX, offsetY); 189291098574f90277128415e9593cce1e495cc51465Alan Viverette } 189391098574f90277128415e9593cce1e495cc51465Alan Viverette 189495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette return bounds; 189595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette } 189695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 18975435a30ae552391f14009c4459731ae149675b18Alan Viverette /** 18985435a30ae552391f14009c4459731ae149675b18Alan Viverette * Removes the popup from the window manager and tears down the supporting 18995435a30ae552391f14009c4459731ae149675b18Alan Viverette * view hierarchy, if necessary. 19005435a30ae552391f14009c4459731ae149675b18Alan Viverette */ 19017970894a9c446a6c8260d28b5b5ec922cc3e7010Alan Viverette private void dismissImmediate(View decorView, ViewGroup contentHolder, View contentView) { 19028fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // If this method gets called and the decor view doesn't have a parent, 19038fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // then it was either never added or was already removed. That should 19048fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // never happen, but it's worth checking to avoid potential crashes. 19058fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (decorView.getParent() != null) { 19068fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mWindowManager.removeViewImmediate(decorView); 1907df4639a0135ea643b493067b3f7cd1e092346c78Alan Viverette } 1908df4639a0135ea643b493067b3f7cd1e092346c78Alan Viverette 19098fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (contentHolder != null) { 19108fd949e680c15d397084430d4907c16cedfacddaAlan Viverette contentHolder.removeView(contentView); 19119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19128fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 19138fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // This needs to stay until after all transitions have ended since we 19148fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // need the reference to cancel transitions in preparePopup(). 19158fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mDecorView = null; 1916697804e8de9f0a838a90c571baad19c5ed4d1647Alan Viverette mBackgroundView = null; 19178fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mIsTransitioningToDismiss = false; 19189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 19219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the listener to be called when the window is dismissed. 19225435a30ae552391f14009c4459731ae149675b18Alan Viverette * 19239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param onDismissListener The listener. 19249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 19259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setOnDismissListener(OnDismissListener onDismissListener) { 19269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnDismissListener = onDismissListener; 19279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19285435a30ae552391f14009c4459731ae149675b18Alan Viverette 19299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Updates the state of the popup window, if it is currently being displayed, 1931259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * from the currently set state. 1932259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1933259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * This includes: 1934259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <ul> 1935259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setClippingEnabled(boolean)}</li> 1936259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setFocusable(boolean)}</li> 1937259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setIgnoreCheekPress()}</li> 1938259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setInputMethodMode(int)}</li> 1939259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setTouchable(boolean)}</li> 1940259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setAnimationStyle(int)}</li> 1941259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * </ul> 19429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 19439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update() { 19449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isShowing() || mContentView == null) { 19459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 19469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19475435a30ae552391f14009c4459731ae149675b18Alan Viverette 19485435a30ae552391f14009c4459731ae149675b18Alan Viverette final WindowManager.LayoutParams p = 19495435a30ae552391f14009c4459731ae149675b18Alan Viverette (WindowManager.LayoutParams) mDecorView.getLayoutParams(); 19505435a30ae552391f14009c4459731ae149675b18Alan Viverette 19519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean update = false; 19525435a30ae552391f14009c4459731ae149675b18Alan Viverette 19539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newAnim = computeAnimationResource(); 19549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newAnim != p.windowAnimations) { 19559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.windowAnimations = newAnim; 19569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 19579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newFlags = computeFlags(p.flags); 19609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newFlags != p.flags) { 19619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.flags = newFlags; 19629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 19639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1964b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio 19659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (update) { 1966b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio setLayoutDirectionFromAnchor(); 19675435a30ae552391f14009c4459731ae149675b18Alan Viverette mWindowManager.updateViewLayout(mDecorView, p); 19689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1970d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy 1971d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy /** 1972259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the dimension of the popup window. 1973259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1974259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Calling this function also updates the window with the current popup 1975259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * state as described for {@link #update()}. 1976d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy * 1977c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param width the new width in pixels, must be >= 0 or -1 to ignore 1978c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param height the new height in pixels, must be >= 0 or -1 to ignore 1979d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy */ 1980d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy public void update(int width, int height) { 19815435a30ae552391f14009c4459731ae149675b18Alan Viverette final WindowManager.LayoutParams p = 19825435a30ae552391f14009c4459731ae149675b18Alan Viverette (WindowManager.LayoutParams) mDecorView.getLayoutParams(); 1983d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy update(p.x, p.y, width, height, false); 1984d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy } 19855435a30ae552391f14009c4459731ae149675b18Alan Viverette 19869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1987259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 1988259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1989259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Width and height can be set to -1 to update location only. Calling this 1990259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * function also updates the window with the current popup state as 1991259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * described for {@link #update()}. 19929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 19939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x the new x location 19949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y the new y location 1995c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param width the new width in pixels, must be >= 0 or -1 to ignore 1996c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param height the new height in pixels, must be >= 0 or -1 to ignore 19979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 19989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(int x, int y, int width, int height) { 19999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update(x, y, width, height, false); 20009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2003259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 2004259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 2005259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Width and height can be set to -1 to update location only. Calling this 2006259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * function also updates the window with the current popup state as 2007259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * described for {@link #update()}. 20089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 20099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x the new x location 20109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y the new y location 2011c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param width the new width in pixels, must be >= 0 or -1 to ignore 2012c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param height the new height in pixels, must be >= 0 or -1 to ignore 2013259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param force {@code true} to reposition the window even if the specified 2014259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * position already seems to correspond to the LayoutParams, 2015259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * {@code false} to only reposition if needed 20169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 20179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(int x, int y, int width, int height, boolean force) { 2018259c2840691a79634ffd8f63291ec21c21819542Alan Viverette if (width >= 0) { 20199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastWidth = width; 20209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setWidth(width); 20219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2023259c2840691a79634ffd8f63291ec21c21819542Alan Viverette if (height >= 0) { 20249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastHeight = height; 20259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setHeight(height); 20269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isShowing() || mContentView == null) { 20299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 20309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20325435a30ae552391f14009c4459731ae149675b18Alan Viverette final WindowManager.LayoutParams p = 20335435a30ae552391f14009c4459731ae149675b18Alan Viverette (WindowManager.LayoutParams) mDecorView.getLayoutParams(); 20349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean update = force; 20369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int finalWidth = mWidthMode < 0 ? mWidthMode : mLastWidth; 20389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (width != -1 && p.width != finalWidth) { 20399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.width = mLastWidth = finalWidth; 20409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 20419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int finalHeight = mHeightMode < 0 ? mHeightMode : mLastHeight; 20449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (height != -1 && p.height != finalHeight) { 20459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.height = mLastHeight = finalHeight; 20469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 20479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p.x != x) { 20509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.x = x; 20519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 20529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p.y != y) { 20559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.y = y; 20569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 20579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newAnim = computeAnimationResource(); 20609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newAnim != p.windowAnimations) { 20619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.windowAnimations = newAnim; 20629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 20639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newFlags = computeFlags(p.flags); 20669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newFlags != p.flags) { 20679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.flags = newFlags; 20689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 20699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 207098acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau 2071396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver int newAccessibilityIdOfAnchor = 2072396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver (mAnchor != null) ? mAnchor.get().getAccessibilityViewId() : -1; 2073396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver if (newAccessibilityIdOfAnchor != p.accessibilityIdOfAnchor) { 2074396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver p.accessibilityIdOfAnchor = newAccessibilityIdOfAnchor; 2075396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver update = true; 2076396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver } 2077396d549113bc633f719acc643c7dfc5f2a8fae4ePhil Weaver 20789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (update) { 2079b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio setLayoutDirectionFromAnchor(); 20805435a30ae552391f14009c4459731ae149675b18Alan Viverette mWindowManager.updateViewLayout(mDecorView, p); 20819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2085259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 2086259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 2087259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Calling this function also updates the window with the current popup 2088259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * state as described for {@link #update()}. 20899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 20909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the popup's anchor view 2091c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param width the new width in pixels, must be >= 0 or -1 to ignore 2092c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param height the new height in pixels, must be >= 0 or -1 to ignore 20939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 20949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(View anchor, int width, int height) { 2095b91d6d06b824aab4076fb985304a602806429042Alan Viverette update(anchor, false, 0, 0, width, height); 20969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2099259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 2100259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 2101259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Width and height can be set to -1 to update location only. Calling this 2102259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * function also updates the window with the current popup state as 2103259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * described for {@link #update()}. 2104259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 2105259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * If the view later scrolls to move {@code anchor} to a different 2106259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * location, the popup will be moved correspondingly. 21079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 21089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the popup's anchor view 21099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param xoff x offset from the view's left edge 21109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param yoff y offset from the view's bottom edge 2111c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param width the new width in pixels, must be >= 0 or -1 to ignore 2112c129b58ad108b898ab829b6389ccf2b9196211a7Alan Viverette * @param height the new height in pixels, must be >= 0 or -1 to ignore 21139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 21149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(View anchor, int xoff, int yoff, int width, int height) { 2115b91d6d06b824aab4076fb985304a602806429042Alan Viverette update(anchor, true, xoff, yoff, width, height); 2116105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 2117105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 2118105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private void update(View anchor, boolean updateLocation, int xoff, int yoff, 2119b91d6d06b824aab4076fb985304a602806429042Alan Viverette int width, int height) { 2120105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 21219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isShowing() || mContentView == null) { 21229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 21239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 212575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette final WeakReference<View> oldAnchor = mAnchor; 2126f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int gravity = mAnchoredGravity; 2127f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette 212875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette final boolean needsUpdate = updateLocation && (mAnchorXoff != xoff || mAnchorYoff != yoff); 212981f08086b44a117097960195d2c9072e29644962Gilles Debunne if (oldAnchor == null || oldAnchor.get() != anchor || (needsUpdate && !mIsDropdown)) { 2130f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette attachToAnchor(anchor, xoff, yoff, gravity); 213181f08086b44a117097960195d2c9072e29644962Gilles Debunne } else if (needsUpdate) { 213281f08086b44a117097960195d2c9072e29644962Gilles Debunne // No need to register again if this is a DropDown, showAsDropDown already did. 213381f08086b44a117097960195d2c9072e29644962Gilles Debunne mAnchorXoff = xoff; 213481f08086b44a117097960195d2c9072e29644962Gilles Debunne mAnchorYoff = yoff; 21359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2137f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final LayoutParams p = (LayoutParams) mDecorView.getLayoutParams(); 2138f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int oldGravity = p.gravity; 2139f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int oldWidth = p.width; 2140f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int oldHeight = p.height; 2141f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int oldX = p.x; 2142f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final int oldY = p.y; 2143f95b2d9aabc2e989bd1d665e728922b1c529589aAlan Viverette 2144b91d6d06b824aab4076fb985304a602806429042Alan Viverette // If an explicit width/height has not specified, use the most recent 2145b91d6d06b824aab4076fb985304a602806429042Alan Viverette // explicitly specified value (either from setWidth/Height or update). 2146f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr if (width < 0) { 2147b91d6d06b824aab4076fb985304a602806429042Alan Viverette width = mWidth; 2148b91d6d06b824aab4076fb985304a602806429042Alan Viverette } 2149f6e801da1a45b2458679e20f5e6061442a434e1bRobert Carr if (height < 0) { 2150b91d6d06b824aab4076fb985304a602806429042Alan Viverette height = mHeight; 21519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2152105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 2153f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final boolean aboveAnchor = findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff, 2154f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette width, height, gravity); 2155f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette updateAboveAnchor(aboveAnchor); 2156b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio 2157f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette final boolean paramsChanged = oldGravity != p.gravity || oldX != p.x || oldY != p.y 2158f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette || oldWidth != p.width || oldHeight != p.height; 2159cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr // If width and mWidth were both < 0 then we have a MATCH_PARENT/WRAP_CONTENT case. 2160cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr // findDropDownPosition will have resolved this to absolute values, 2161cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr // but we don't want to update mWidth/mHeight to these absolute values. 2162cb8dcec66aa68e576bfd1520d1ad39a961f22c56Robert Carr update(p.x, p.y, width < 0 ? width : p.width, height < 0 ? height : p.height, paramsChanged); 21639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 21669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Listener that is called when this popup window is dismissed. 21679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 21689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnDismissListener { 21699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 21709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called when this popup window is dismissed. 21719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 21729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onDismiss(); 21739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2175f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette private void detachFromAnchor() { 2176634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette final View anchor = mAnchor != null ? mAnchor.get() : null; 21779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (anchor != null) { 2178e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final ViewTreeObserver vto = anchor.getViewTreeObserver(); 21799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project vto.removeOnScrollChangedListener(mOnScrollChangedListener); 21809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2181e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 2182634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette final View anchorRoot = mAnchorRoot != null ? mAnchorRoot.get() : null; 2183634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette if (anchorRoot != null) { 2184634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette anchorRoot.removeOnAttachStateChangeListener(mOnAnchorRootDetachedListener); 2185634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette } 2186634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 21879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnchor = null; 2188634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette mAnchorRoot = null; 2189634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette mIsAnchorRootAttached = false; 21909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2192f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette private void attachToAnchor(View anchor, int xoff, int yoff, int gravity) { 2193f50df4362a8ec8c79ff1b9508a57be51f293897aAlan Viverette detachFromAnchor(); 2194e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 2195e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final ViewTreeObserver vto = anchor.getViewTreeObserver(); 21969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (vto != null) { 21979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project vto.addOnScrollChangedListener(mOnScrollChangedListener); 21989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2200634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette final View anchorRoot = anchor.getRootView(); 2201634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette anchorRoot.addOnAttachStateChangeListener(mOnAnchorRootDetachedListener); 2202634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 2203634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette mAnchor = new WeakReference<>(anchor); 2204634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette mAnchorRoot = new WeakReference<>(anchorRoot); 2205634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette mIsAnchorRootAttached = anchorRoot.isAttachedToWindow(); 2206634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 22079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnchorXoff = xoff; 22089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnchorYoff = yoff; 220954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell mAnchoredGravity = gravity; 22109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22125435a30ae552391f14009c4459731ae149675b18Alan Viverette private class PopupDecorView extends FrameLayout { 22138fd949e680c15d397084430d4907c16cedfacddaAlan Viverette private TransitionListenerAdapter mPendingExitListener; 22148fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 22155435a30ae552391f14009c4459731ae149675b18Alan Viverette public PopupDecorView(Context context) { 22165435a30ae552391f14009c4459731ae149675b18Alan Viverette super(context); 22175435a30ae552391f14009c4459731ae149675b18Alan Viverette } 22189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 22209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean dispatchKeyEvent(KeyEvent event) { 22219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { 22224ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson if (getKeyDispatcherState() == null) { 22234ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson return super.dispatchKeyEvent(event); 22244ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson } 22254ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson 22265435a30ae552391f14009c4459731ae149675b18Alan Viverette if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { 22275435a30ae552391f14009c4459731ae149675b18Alan Viverette final KeyEvent.DispatcherState state = getKeyDispatcherState(); 2228b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown if (state != null) { 2229b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown state.startTracking(event, this); 2230b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } 22318d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn return true; 2232b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } else if (event.getAction() == KeyEvent.ACTION_UP) { 22335435a30ae552391f14009c4459731ae149675b18Alan Viverette final KeyEvent.DispatcherState state = getKeyDispatcherState(); 2234b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown if (state != null && state.isTracking(event) && !event.isCanceled()) { 2235b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown dismiss(); 2236b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown return true; 2237b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } 22388d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn } 22398d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn return super.dispatchKeyEvent(event); 22409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 22419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.dispatchKeyEvent(event); 22429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 22469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean dispatchTouchEvent(MotionEvent ev) { 22479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTouchInterceptor != null && mTouchInterceptor.onTouch(this, ev)) { 22489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 22499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.dispatchTouchEvent(ev); 22519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 22549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onTouchEvent(MotionEvent event) { 22559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int x = (int) event.getX(); 22569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int y = (int) event.getY(); 22575435a30ae552391f14009c4459731ae149675b18Alan Viverette 22589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((event.getAction() == MotionEvent.ACTION_DOWN) 22599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && ((x < 0) || (x >= getWidth()) || (y < 0) || (y >= getHeight()))) { 22609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dismiss(); 22619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 22629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (event.getAction() == MotionEvent.ACTION_OUTSIDE) { 22639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dismiss(); 22649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 22659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 22669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.onTouchEvent(event); 22679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22698fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 22708fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 22718fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Requests that an enter transition run after the next layout pass. 22728fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 22738fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void requestEnterTransition(Transition transition) { 22748fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewTreeObserver observer = getViewTreeObserver(); 22758fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (observer != null && transition != null) { 22768fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final Transition enterTransition = transition.clone(); 22778fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 22788fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // Postpone the enter transition after the first layout pass. 22798fd949e680c15d397084430d4907c16cedfacddaAlan Viverette observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 22808fd949e680c15d397084430d4907c16cedfacddaAlan Viverette @Override 22818fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void onGlobalLayout() { 22828fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewTreeObserver observer = getViewTreeObserver(); 22838fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (observer != null) { 22848fd949e680c15d397084430d4907c16cedfacddaAlan Viverette observer.removeOnGlobalLayoutListener(this); 22858fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 22868fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 228791098574f90277128415e9593cce1e495cc51465Alan Viverette final Rect epicenter = getTransitionEpicenter(); 228895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette enterTransition.setEpicenterCallback(new EpicenterCallback() { 228995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette @Override 229095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette public Rect onGetEpicenter(Transition transition) { 229195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette return epicenter; 229295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette } 229395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette }); 22948fd949e680c15d397084430d4907c16cedfacddaAlan Viverette startEnterTransition(enterTransition); 22958fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 22968fd949e680c15d397084430d4907c16cedfacddaAlan Viverette }); 22978fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 22988fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 22998fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 23008fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 23018fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Starts the pending enter transition, if one is set. 23028fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 23038fd949e680c15d397084430d4907c16cedfacddaAlan Viverette private void startEnterTransition(Transition enterTransition) { 23048fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final int count = getChildCount(); 23058fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 23068fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 23078fd949e680c15d397084430d4907c16cedfacddaAlan Viverette enterTransition.addTarget(child); 23088fd949e680c15d397084430d4907c16cedfacddaAlan Viverette child.setVisibility(View.INVISIBLE); 23098fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 23108fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 23118fd949e680c15d397084430d4907c16cedfacddaAlan Viverette TransitionManager.beginDelayedTransition(this, enterTransition); 23128fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 23138fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 23148fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 23158fd949e680c15d397084430d4907c16cedfacddaAlan Viverette child.setVisibility(View.VISIBLE); 23168fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 23178fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 23188fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 23198fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 23208fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Starts an exit transition immediately. 23218fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * <p> 23228fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * <strong>Note:</strong> The transition listener is guaranteed to have 23238fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * its {@code onTransitionEnd} method called even if the transition 23248fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * never starts; however, it may be called with a {@code null} argument. 23258fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 2326634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette public void startExitTransition(Transition transition, final View anchorRoot, 2327634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette final TransitionListener listener) { 23288fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (transition == null) { 23298fd949e680c15d397084430d4907c16cedfacddaAlan Viverette return; 23308fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 23318fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 2332634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // The anchor view's window may go away while we're executing our 2333634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // transition, in which case we need to end the transition 2334634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette // immediately and execute the listener to remove the popup. 2335634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette anchorRoot.addOnAttachStateChangeListener(mOnAnchorRootDetachedListener); 2336634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 23378fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // The exit listener MUST be called for cleanup, even if the 23388fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // transition never starts or ends. Stash it for later. 23398fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mPendingExitListener = new TransitionListenerAdapter() { 23408fd949e680c15d397084430d4907c16cedfacddaAlan Viverette @Override 23418fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void onTransitionEnd(Transition transition) { 2342634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette anchorRoot.removeOnAttachStateChangeListener(mOnAnchorRootDetachedListener); 23438fd949e680c15d397084430d4907c16cedfacddaAlan Viverette listener.onTransitionEnd(transition); 23448fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 23458fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // The listener was called. Our job here is done. 23468fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mPendingExitListener = null; 23478fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 23488fd949e680c15d397084430d4907c16cedfacddaAlan Viverette }; 23498fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 23508fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final Transition exitTransition = transition.clone(); 23518fd949e680c15d397084430d4907c16cedfacddaAlan Viverette exitTransition.addListener(mPendingExitListener); 23528fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 23538fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final int count = getChildCount(); 23548fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 23558fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 23568fd949e680c15d397084430d4907c16cedfacddaAlan Viverette exitTransition.addTarget(child); 23578fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 23588fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 23598fd949e680c15d397084430d4907c16cedfacddaAlan Viverette TransitionManager.beginDelayedTransition(this, exitTransition); 23608fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 23618fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 23628fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 23638fd949e680c15d397084430d4907c16cedfacddaAlan Viverette child.setVisibility(View.INVISIBLE); 23648fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 23658fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 23668fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 23678fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 23688fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Cancels all pending or current transitions. 23698fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 23708fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void cancelTransitions() { 23718fd949e680c15d397084430d4907c16cedfacddaAlan Viverette TransitionManager.endTransitions(this); 23728fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 23738fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (mPendingExitListener != null) { 23748fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mPendingExitListener.onTransitionEnd(null); 23758fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 23768fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 2377634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 2378634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette private final OnAttachStateChangeListener mOnAnchorRootDetachedListener = 2379634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette new OnAttachStateChangeListener() { 2380634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette @Override 2381634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette public void onViewAttachedToWindow(View v) {} 2382634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 2383634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette @Override 2384634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette public void onViewDetachedFromWindow(View v) { 2385634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette v.removeOnAttachStateChangeListener(this); 2386634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette 2387634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette TransitionManager.endTransitions(PopupDecorView.this); 2388634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette } 2389634a808226cc5d00bd6897bdc881cafe064e37acAlan Viverette }; 23905435a30ae552391f14009c4459731ae149675b18Alan Viverette } 23915435a30ae552391f14009c4459731ae149675b18Alan Viverette 23925435a30ae552391f14009c4459731ae149675b18Alan Viverette private class PopupBackgroundView extends FrameLayout { 23935435a30ae552391f14009c4459731ae149675b18Alan Viverette public PopupBackgroundView(Context context) { 23945435a30ae552391f14009c4459731ae149675b18Alan Viverette super(context); 23955435a30ae552391f14009c4459731ae149675b18Alan Viverette } 239675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 239775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov @Override 23985435a30ae552391f14009c4459731ae149675b18Alan Viverette protected int[] onCreateDrawableState(int extraSpace) { 23995435a30ae552391f14009c4459731ae149675b18Alan Viverette if (mAboveAnchor) { 24005435a30ae552391f14009c4459731ae149675b18Alan Viverette final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 24015435a30ae552391f14009c4459731ae149675b18Alan Viverette View.mergeDrawableStates(drawableState, ABOVE_ANCHOR_STATE_SET); 24025435a30ae552391f14009c4459731ae149675b18Alan Viverette return drawableState; 240375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } else { 24045435a30ae552391f14009c4459731ae149675b18Alan Viverette return super.onCreateDrawableState(extraSpace); 240575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 240675986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 24079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2409