PopupWindow.java revision 80ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89
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 2175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.Context; 22a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport android.content.res.Resources; 2375986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganovimport android.content.res.TypedArray; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PixelFormat; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.Drawable; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.StateListDrawable; 2846e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brownimport android.os.Build; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 305435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.Transition; 315435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.Transition.EpicenterCallback; 328fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.transition.Transition.TransitionListener; 338fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.transition.Transition.TransitionListenerAdapter; 345435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.TransitionInflater; 355435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.TransitionManager; 365435a30ae552391f14009c4459731ae149675b18Alan Viveretteimport android.transition.TransitionSet; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 38c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.Gravity; 39c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.KeyEvent; 40c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.MotionEvent; 41c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.View; 42a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport android.view.View.OnTouchListener; 43c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.ViewGroup; 448fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.view.ViewParent; 45c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.ViewTreeObserver; 468fd949e680c15d397084430d4907c16cedfacddaAlan Viveretteimport android.view.ViewTreeObserver.OnGlobalLayoutListener; 47c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.ViewTreeObserver.OnScrollChangedListener; 48a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport android.view.WindowManager; 49259c2840691a79634ffd8f63291ec21c21819542Alan Viveretteimport android.view.WindowManager.LayoutParams; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 51a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powellimport java.lang.ref.WeakReference; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>A popup window that can be used to display an arbitrary view. The popup 557ed189e457b16c06b0425bd28aeeb1df5c8ff5b8Scott Kennedy * window is a floating container that appears on top of the current 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * activity.</p> 575435a30ae552391f14009c4459731ae149675b18Alan Viverette * 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.widget.AutoCompleteTextView 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.widget.Spinner 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class PopupWindow { 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 63e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * Mode for {@link #setInputMethodMode(int)}: the requirements for the 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * input method should be based on the focusability of the popup. That is 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if it is focusable than it needs to work with the input method, else 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * it doesn't. 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int INPUT_METHOD_FROM_FOCUSABLE = 0; 695435a30ae552391f14009c4459731ae149675b18Alan Viverette 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 71e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * Mode for {@link #setInputMethodMode(int)}: this popup always needs to 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * work with an input method, regardless of whether it is focusable. This 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * means that it will always be displayed so that the user can also operate 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the input method while it is shown. 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int INPUT_METHOD_NEEDED = 1; 775435a30ae552391f14009c4459731ae149675b18Alan Viverette 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 79e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * Mode for {@link #setInputMethodMode(int)}: this popup never needs to 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * work with an input method, regardless of whether it is focusable. This 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * means that it will always be displayed to use as much space on the 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * screen as needed, regardless of whether this covers the input method. 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int INPUT_METHOD_NOT_NEEDED = 2; 8554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 8654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell private static final int DEFAULT_ANCHORED_GRAVITY = Gravity.TOP | Gravity.START; 8754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 885435a30ae552391f14009c4459731ae149675b18Alan Viverette /** 895435a30ae552391f14009c4459731ae149675b18Alan Viverette * Default animation style indicating that separate animations should be 905435a30ae552391f14009c4459731ae149675b18Alan Viverette * used for top/bottom anchoring states. 915435a30ae552391f14009c4459731ae149675b18Alan Viverette */ 925435a30ae552391f14009c4459731ae149675b18Alan Viverette private static final int ANIMATION_STYLE_DEFAULT = -1; 935435a30ae552391f14009c4459731ae149675b18Alan Viverette 945435a30ae552391f14009c4459731ae149675b18Alan Viverette private final int[] mDrawingLocation = new int[2]; 955435a30ae552391f14009c4459731ae149675b18Alan Viverette private final int[] mScreenLocation = new int[2]; 965435a30ae552391f14009c4459731ae149675b18Alan Viverette private final Rect mTempRect = new Rect(); 975435a30ae552391f14009c4459731ae149675b18Alan Viverette 98448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy private Context mContext; 99448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy private WindowManager mWindowManager; 1005435a30ae552391f14009c4459731ae149675b18Alan Viverette 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mIsShowing; 1028fd949e680c15d397084430d4907c16cedfacddaAlan Viverette private boolean mIsTransitioningToDismiss; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mIsDropdown; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1055435a30ae552391f14009c4459731ae149675b18Alan Viverette /** View that handles event dispatch and content transitions. */ 1065435a30ae552391f14009c4459731ae149675b18Alan Viverette private PopupDecorView mDecorView; 1075435a30ae552391f14009c4459731ae149675b18Alan Viverette 1085435a30ae552391f14009c4459731ae149675b18Alan Viverette /** The contents of the popup. */ 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View mContentView; 1105435a30ae552391f14009c4459731ae149675b18Alan Viverette 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mFocusable; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mInputMethodMode = INPUT_METHOD_FROM_FOCUSABLE; 1137eab094722af54717859b7dcce3cc050f059e00bDianne Hackborn private int mSoftInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mTouchable = true; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mOutsideTouchable = false; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mClippingEnabled = true; 11746e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown private int mSplitTouchEnabled = -1; 118ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell private boolean mLayoutInScreen; 11956c2d337e02a275397fc9d0460dca90977f199acAdam Powell private boolean mClipToScreen; 120348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell private boolean mAllowScrollingAnchorParent = true; 1210bd1d0a15294345bf88b20df28466907f982cec7Adam Powell private boolean mLayoutInsetDecor = false; 122e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell private boolean mNotTouchModal; 123393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale private boolean mAttachedInDecor = true; 124393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale private boolean mAttachedInDecorSet = false; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnTouchListener mTouchInterceptor; 127393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mWidthMode; 129259c2840691a79634ffd8f63291ec21c21819542Alan Viverette private int mWidth = LayoutParams.WRAP_CONTENT; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLastWidth; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mHeightMode; 132259c2840691a79634ffd8f63291ec21c21819542Alan Viverette private int mHeight = LayoutParams.WRAP_CONTENT; 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLastHeight; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mPopupWidth; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mPopupHeight; 13756c2d337e02a275397fc9d0460dca90977f199acAdam Powell 138ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette private float mElevation; 139ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Drawable mBackground; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Drawable mAboveAnchorBackgroundDrawable; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Drawable mBelowAnchorBackgroundDrawable; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1445435a30ae552391f14009c4459731ae149675b18Alan Viverette private Transition mEnterTransition; 1455435a30ae552391f14009c4459731ae149675b18Alan Viverette private Transition mExitTransition; 146560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mAboveAnchor; 148574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell private int mWindowLayoutType = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; 1495435a30ae552391f14009c4459731ae149675b18Alan Viverette 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnDismissListener mOnDismissListener; 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mIgnoreCheekPress = false; 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1535435a30ae552391f14009c4459731ae149675b18Alan Viverette private int mAnimationStyle = ANIMATION_STYLE_DEFAULT; 1545435a30ae552391f14009c4459731ae149675b18Alan Viverette 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int[] ABOVE_ANCHOR_STATE_SET = new int[] { 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.attr.state_above_anchor 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private WeakReference<View> mAnchor; 160560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 1615435a30ae552391f14009c4459731ae149675b18Alan Viverette private final OnScrollChangedListener mOnScrollChangedListener = new OnScrollChangedListener() { 1625435a30ae552391f14009c4459731ae149675b18Alan Viverette @Override 1635435a30ae552391f14009c4459731ae149675b18Alan Viverette public void onScrollChanged() { 1645435a30ae552391f14009c4459731ae149675b18Alan Viverette final View anchor = mAnchor != null ? mAnchor.get() : null; 1655435a30ae552391f14009c4459731ae149675b18Alan Viverette if (anchor != null && mDecorView != null) { 1665435a30ae552391f14009c4459731ae149675b18Alan Viverette final WindowManager.LayoutParams p = (WindowManager.LayoutParams) 1675435a30ae552391f14009c4459731ae149675b18Alan Viverette mDecorView.getLayoutParams(); 1685435a30ae552391f14009c4459731ae149675b18Alan Viverette 1695435a30ae552391f14009c4459731ae149675b18Alan Viverette updateAboveAnchor(findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff, 1705435a30ae552391f14009c4459731ae149675b18Alan Viverette mAnchoredGravity)); 1715435a30ae552391f14009c4459731ae149675b18Alan Viverette update(p.x, p.y, -1, -1, true); 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1735435a30ae552391f14009c4459731ae149675b18Alan Viverette } 1745435a30ae552391f14009c4459731ae149675b18Alan Viverette }; 175560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 1765435a30ae552391f14009c4459731ae149675b18Alan Viverette private int mAnchorXoff; 1775435a30ae552391f14009c4459731ae149675b18Alan Viverette private int mAnchorYoff; 1785435a30ae552391f14009c4459731ae149675b18Alan Viverette private int mAnchoredGravity; 179560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette private boolean mOverlapAnchor; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 181b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio private boolean mPopupViewInitialLayoutDirectionInherited; 182b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window of dimension (0,0).</p> 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does provide a background.</p> 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(Context context) { 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, null); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window of dimension (0,0).</p> 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does provide a background.</p> 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(Context context, AttributeSet attrs) { 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, attrs, com.android.internal.R.attr.popupWindowStyle); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window of dimension (0,0).</p> 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does provide a background.</p> 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 206617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr) { 207617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette this(context, attrs, defStyleAttr, 0); 208c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 2095435a30ae552391f14009c4459731ae149675b18Alan Viverette 210c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 211c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>Create a new, empty, non focusable popup window of dimension (0,0).</p> 2125435a30ae552391f14009c4459731ae149675b18Alan Viverette * 213c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>The popup does not provide a background.</p> 214c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 215c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 21775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 219617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette final TypedArray a = context.obtainStyledAttributes( 220ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette attrs, R.styleable.PopupWindow, defStyleAttr, defStyleRes); 221ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette final Drawable bg = a.getDrawable(R.styleable.PopupWindow_popupBackground); 222ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette mElevation = a.getDimension(R.styleable.PopupWindow_popupElevation, 0); 223560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette mOverlapAnchor = a.getBoolean(R.styleable.PopupWindow_overlapAnchor, false); 224c3808b5dc7d5873d04e8a0a247b179b2757764baAdam Powell 2255435a30ae552391f14009c4459731ae149675b18Alan Viverette // Preserve default behavior from Gingerbread. If the animation is 2265435a30ae552391f14009c4459731ae149675b18Alan Viverette // undefined or explicitly specifies the Gingerbread animation style, 2275435a30ae552391f14009c4459731ae149675b18Alan Viverette // use a sentinel value. 2285435a30ae552391f14009c4459731ae149675b18Alan Viverette if (a.hasValueOrEmpty(R.styleable.PopupWindow_popupAnimationStyle)) { 2295435a30ae552391f14009c4459731ae149675b18Alan Viverette final int animStyle = a.getResourceId(R.styleable.PopupWindow_popupAnimationStyle, 0); 2305435a30ae552391f14009c4459731ae149675b18Alan Viverette if (animStyle == R.style.Animation_PopupWindow) { 2315435a30ae552391f14009c4459731ae149675b18Alan Viverette mAnimationStyle = ANIMATION_STYLE_DEFAULT; 2325435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 2335435a30ae552391f14009c4459731ae149675b18Alan Viverette mAnimationStyle = animStyle; 2345435a30ae552391f14009c4459731ae149675b18Alan Viverette } 2355435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 2365435a30ae552391f14009c4459731ae149675b18Alan Viverette mAnimationStyle = ANIMATION_STYLE_DEFAULT; 2375435a30ae552391f14009c4459731ae149675b18Alan Viverette } 2385435a30ae552391f14009c4459731ae149675b18Alan Viverette 2395435a30ae552391f14009c4459731ae149675b18Alan Viverette final Transition enterTransition = getTransition(a.getResourceId( 2405435a30ae552391f14009c4459731ae149675b18Alan Viverette R.styleable.PopupWindow_popupEnterTransition, 0)); 2415435a30ae552391f14009c4459731ae149675b18Alan Viverette final Transition exitTransition; 2425435a30ae552391f14009c4459731ae149675b18Alan Viverette if (a.hasValueOrEmpty(R.styleable.PopupWindow_popupExitTransition)) { 2435435a30ae552391f14009c4459731ae149675b18Alan Viverette exitTransition = getTransition(a.getResourceId( 2445435a30ae552391f14009c4459731ae149675b18Alan Viverette R.styleable.PopupWindow_popupExitTransition, 0)); 2455435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 2465435a30ae552391f14009c4459731ae149675b18Alan Viverette exitTransition = enterTransition == null ? null : enterTransition.clone(); 2475435a30ae552391f14009c4459731ae149675b18Alan Viverette } 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 250ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 2515435a30ae552391f14009c4459731ae149675b18Alan Viverette setEnterTransition(enterTransition); 2525435a30ae552391f14009c4459731ae149675b18Alan Viverette setExitTransition(exitTransition); 253ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette setBackgroundDrawable(bg); 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window of dimension (0,0).</p> 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow() { 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(null, 0, 0); 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new non focusable popup window which can display the 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tt>contentView</tt>. The dimension of the window are (0,0).</p> 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param contentView the popup's content 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(View contentView) { 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(contentView, 0, 0); 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window. The dimension of the 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window must be passed to this constructor.</p> 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param width the popup's width 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param height the popup's height 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(int width, int height) { 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(null, width, height); 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new non focusable popup window which can display the 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tt>contentView</tt>. The dimension of the window must be passed to 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this constructor.</p> 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param contentView the popup's content 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param width the popup's width 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param height the popup's height 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(View contentView, int width, int height) { 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(contentView, width, height, false); 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new popup window which can display the <tt>contentView</tt>. 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The dimension of the window must be passed to this constructor.</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 * @param contentView the popup's content 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param width the popup's width 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param height the popup's height 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param focusable true if the popup can be focused, false otherwise 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 321448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy public PopupWindow(View contentView, int width, int height, boolean focusable) { 322448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy if (contentView != null) { 323448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy mContext = contentView.getContext(); 324448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); 325448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy } 326393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setContentView(contentView); 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setWidth(width); 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setHeight(height); 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setFocusable(focusable); 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3335435a30ae552391f14009c4459731ae149675b18Alan Viverette public void setEnterTransition(Transition enterTransition) { 3345435a30ae552391f14009c4459731ae149675b18Alan Viverette mEnterTransition = enterTransition; 3355435a30ae552391f14009c4459731ae149675b18Alan Viverette } 3365435a30ae552391f14009c4459731ae149675b18Alan Viverette 3375435a30ae552391f14009c4459731ae149675b18Alan Viverette public void setExitTransition(Transition exitTransition) { 3385435a30ae552391f14009c4459731ae149675b18Alan Viverette mExitTransition = exitTransition; 3395435a30ae552391f14009c4459731ae149675b18Alan Viverette } 3405435a30ae552391f14009c4459731ae149675b18Alan Viverette 3415435a30ae552391f14009c4459731ae149675b18Alan Viverette private Transition getTransition(int resId) { 3425435a30ae552391f14009c4459731ae149675b18Alan Viverette if (resId != 0 && resId != R.transition.no_transition) { 3435435a30ae552391f14009c4459731ae149675b18Alan Viverette final TransitionInflater inflater = TransitionInflater.from(mContext); 3445435a30ae552391f14009c4459731ae149675b18Alan Viverette final Transition transition = inflater.inflateTransition(resId); 3455435a30ae552391f14009c4459731ae149675b18Alan Viverette if (transition != null) { 3465435a30ae552391f14009c4459731ae149675b18Alan Viverette final boolean isEmpty = transition instanceof TransitionSet 3475435a30ae552391f14009c4459731ae149675b18Alan Viverette && ((TransitionSet) transition).getTransitionCount() == 0; 3485435a30ae552391f14009c4459731ae149675b18Alan Viverette if (!isEmpty) { 3495435a30ae552391f14009c4459731ae149675b18Alan Viverette return transition; 3505435a30ae552391f14009c4459731ae149675b18Alan Viverette } 3515435a30ae552391f14009c4459731ae149675b18Alan Viverette } 3525435a30ae552391f14009c4459731ae149675b18Alan Viverette } 3535435a30ae552391f14009c4459731ae149675b18Alan Viverette return null; 3545435a30ae552391f14009c4459731ae149675b18Alan Viverette } 3555435a30ae552391f14009c4459731ae149675b18Alan Viverette 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 357ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * Return the drawable used as the popup window's background. 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 359ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @return the background drawable or {@code null} if not set 360ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @see #setBackgroundDrawable(Drawable) 361ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @attr ref android.R.styleable#PopupWindow_popupBackground 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable getBackground() { 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBackground; 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 368ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * Specifies the background drawable for this popup window. The background 369ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * can be set to {@code null}. 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param background the popup's background 372ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @see #getBackground() 373ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @attr ref android.R.styleable#PopupWindow_popupBackground 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setBackgroundDrawable(Drawable background) { 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBackground = background; 377ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 378ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // If this is a StateListDrawable, try to find and store the drawable to be 379ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // used when the drop-down is placed above its anchor view, and the one to be 380ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // used when the drop-down is placed below its anchor view. We extract 381ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // the drawables ourselves to work around a problem with using refreshDrawableState 382ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // that it will take into account the padding of all drawables specified in a 383ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // StateListDrawable, thus adding superfluous padding to drop-down views. 384ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // 385ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // We assume a StateListDrawable will have a drawable for ABOVE_ANCHOR_STATE_SET and 386ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // at least one other drawable, intended for the 'below-anchor state'. 387ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette if (mBackground instanceof StateListDrawable) { 388ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette StateListDrawable stateList = (StateListDrawable) mBackground; 389ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 390ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // Find the above-anchor view - this one's easy, it should be labeled as such. 391ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette int aboveAnchorStateIndex = stateList.getStateDrawableIndex(ABOVE_ANCHOR_STATE_SET); 392ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 393ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // Now, for the below-anchor view, look for any other drawable specified in the 394ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // StateListDrawable which is not for the above-anchor state and use that. 395ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette int count = stateList.getStateCount(); 396ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette int belowAnchorStateIndex = -1; 397ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette for (int i = 0; i < count; i++) { 398ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette if (i != aboveAnchorStateIndex) { 399ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette belowAnchorStateIndex = i; 400ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette break; 401ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } 402ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } 403ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 404ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // Store the drawables we found, if we found them. Otherwise, set them both 405ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // to null so that we'll just use refreshDrawableState. 406ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette if (aboveAnchorStateIndex != -1 && belowAnchorStateIndex != -1) { 407ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette mAboveAnchorBackgroundDrawable = stateList.getStateDrawable(aboveAnchorStateIndex); 408ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette mBelowAnchorBackgroundDrawable = stateList.getStateDrawable(belowAnchorStateIndex); 409ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } else { 410ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette mBelowAnchorBackgroundDrawable = null; 411ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette mAboveAnchorBackgroundDrawable = null; 412ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } 413ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 417ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @return the elevation for this popup window in pixels 418ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @see #setElevation(float) 419ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @attr ref android.R.styleable#PopupWindow_popupElevation 420ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette */ 421ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette public float getElevation() { 422ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette return mElevation; 423ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette } 424ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette 425ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette /** 426ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * Specifies the elevation for this popup window. 427ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * 428ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @param elevation the popup's elevation in pixels 429ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @see #getElevation() 430ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @attr ref android.R.styleable#PopupWindow_popupElevation 431ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette */ 432ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette public void setElevation(float elevation) { 433ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette mElevation = elevation; 434ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette } 435ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette 436ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette /** 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Return the animation style to use the popup appears and disappears</p> 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the animation style to use the popup appears and disappears 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getAnimationStyle() { 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAnimationStyle; 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 444393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 44654ec76d81ac38284caa6d00ad5f2d2207206b9ceShuhrat Dehkanov * Set the flag on popup to ignore cheek press events; by default this flag 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is set to false 44854ec76d81ac38284caa6d00ad5f2d2207206b9ceShuhrat Dehkanov * which means the popup will not ignore cheek press dispatch events. 4495435a30ae552391f14009c4459731ae149675b18Alan Viverette * 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 453393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setIgnoreCheekPress() { 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIgnoreCheekPress = true; 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4595435a30ae552391f14009c4459731ae149675b18Alan Viverette 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Change the animation style resource for this popup.</p> 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param animationStyle animation style to use when the popup appears 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and disappears. Set to -1 for the default animation, 0 for no 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * animation, or a resource identifier for an explicit animation. 4715435a30ae552391f14009c4459731ae149675b18Alan Viverette * 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAnimationStyle(int animationStyle) { 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimationStyle = animationStyle; 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4775435a30ae552391f14009c4459731ae149675b18Alan Viverette 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Return the view used as the content of the popup window.</p> 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return a {@link android.view.View} representing the popup's content 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setContentView(android.view.View) 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public View getContentView() { 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mContentView; 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Change the popup's content. The content is represented by an instance 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of {@link android.view.View}.</p> 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49381f08086b44a117097960195d2c9072e29644962Gilles Debunne * <p>This method has no effect if called when the popup is showing.</p> 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param contentView the new content for the popup 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getContentView() 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isShowing() 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setContentView(View contentView) { 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isShowing()) { 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentView = contentView; 506448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy 5070c0b768e1514280812321854db6dfba723c3d169Romain Guy if (mContext == null && mContentView != null) { 508448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy mContext = mContentView.getContext(); 509448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy } 510448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy 5110c0b768e1514280812321854db6dfba723c3d169Romain Guy if (mWindowManager == null && mContentView != null) { 512448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); 513448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy } 514393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 515393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // Setting the default for attachedInDecor based on SDK version here 516393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // instead of in the constructor since we might not have the context 517393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // object in the constructor. We only want to set default here if the 518393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // app hasn't already set the attachedInDecor. 519393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale if (mContext != null && !mAttachedInDecorSet) { 520393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // Attach popup window in decor frame of parent window by default for 521393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // {@link Build.VERSION_CODES.LOLLIPOP_MR1} or greater. Keep current 522393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // behavior of not attaching to decor frame for older SDKs. 523393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale setAttachedInDecor(mContext.getApplicationInfo().targetSdkVersion 524393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale >= Build.VERSION_CODES.LOLLIPOP_MR1); 525393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale } 526393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set a callback for all touch events being dispatched to the popup 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window. 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTouchInterceptor(OnTouchListener l) { 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTouchInterceptor = l; 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 536393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicate whether the popup window can grab the focus.</p> 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is focusable, false otherwise 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setFocusable(boolean) 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isFocusable() { 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFocusable; 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Changes the focusability of the popup window. When focusable, the 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window will grab the focus from the current focused widget if the popup 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * contains a focusable {@link android.view.View}. By default a popup 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window is not focusable.</p> 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param focusable true if the popup should grab focus, false otherwise. 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isFocusable() 5615435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setFocusable(boolean focusable) { 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFocusable = focusable; 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the current value in {@link #setInputMethodMode(int)}. 5705435a30ae552391f14009c4459731ae149675b18Alan Viverette * 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setInputMethodMode(int) 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getInputMethodMode() { 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mInputMethodMode; 5755435a30ae552391f14009c4459731ae149675b18Alan Viverette 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5775435a30ae552391f14009c4459731ae149675b18Alan Viverette 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Control how the popup operates with an input method: one of 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #INPUT_METHOD_FROM_FOCUSABLE}, {@link #INPUT_METHOD_NEEDED}, 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or {@link #INPUT_METHOD_NOT_NEEDED}. 5825435a30ae552391f14009c4459731ae149675b18Alan Viverette * 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 5865435a30ae552391f14009c4459731ae149675b18Alan Viverette * 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getInputMethodMode() 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setInputMethodMode(int mode) { 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mInputMethodMode = mode; 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 593374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy 594374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy /** 595374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * Sets the operating mode for the soft input area. 596374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * 597374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @param mode The desired mode, see 598374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * {@link android.view.WindowManager.LayoutParams#softInputMode} 599374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * for the full list 600374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * 601374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @see android.view.WindowManager.LayoutParams#softInputMode 602374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @see #getSoftInputMode() 603374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy */ 604374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy public void setSoftInputMode(int mode) { 605374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy mSoftInputMode = mode; 606374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy } 607374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy 608374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy /** 609374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * Returns the current value in {@link #setSoftInputMode(int)}. 610374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * 611374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @see #setSoftInputMode(int) 612374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @see android.view.WindowManager.LayoutParams#softInputMode 613374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy */ 614374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy public int getSoftInputMode() { 615374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy return mSoftInputMode; 616374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy } 6175435a30ae552391f14009c4459731ae149675b18Alan Viverette 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicates whether the popup window receives touch events.</p> 6205435a30ae552391f14009c4459731ae149675b18Alan Viverette * 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is touchable, false otherwise 6225435a30ae552391f14009c4459731ae149675b18Alan Viverette * 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setTouchable(boolean) 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isTouchable() { 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mTouchable; 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Changes the touchability of the popup window. When touchable, the 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window will receive touch events, otherwise touch events will go to the 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window below it. By default the window is touchable.</p> 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param touchable true if the popup should receive touch events, false otherwise 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isTouchable() 6415435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTouchable(boolean touchable) { 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTouchable = touchable; 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicates whether the popup window will be informed of touch events 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * outside of its window.</p> 6515435a30ae552391f14009c4459731ae149675b18Alan Viverette * 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is outside touchable, false otherwise 6535435a30ae552391f14009c4459731ae149675b18Alan Viverette * 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setOutsideTouchable(boolean) 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isOutsideTouchable() { 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mOutsideTouchable; 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Controls whether the pop-up will be informed of touch events outside 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of its window. This only makes sense for pop-ups that are touchable 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * but not focusable, which means touches outside of the window will 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be delivered to the window behind. The default is false.</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 touchable true if the popup should receive outside 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * touch events, false otherwise 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isOutsideTouchable() 6745435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setOutsideTouchable(boolean touchable) { 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOutsideTouchable = touchable; 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicates whether clipping of the popup window is enabled.</p> 6835435a30ae552391f14009c4459731ae149675b18Alan Viverette * 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the clipping is enabled, false otherwise 6855435a30ae552391f14009c4459731ae149675b18Alan Viverette * 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setClippingEnabled(boolean) 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isClippingEnabled() { 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mClippingEnabled; 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Allows the popup window to extend beyond the bounds of the screen. By default the 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window is clipped to the screen boundaries. Setting this to false will allow windows to be 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * accurately positioned.</p> 6965435a30ae552391f14009c4459731ae149675b18Alan Viverette * 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param enabled false if the window should be allowed to extend outside of the screen 7025435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isClippingEnabled() 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setClippingEnabled(boolean enabled) { 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mClippingEnabled = enabled; 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 71156c2d337e02a275397fc9d0460dca90977f199acAdam Powell * Clip this popup window to the screen, but not to the containing window. 71256c2d337e02a275397fc9d0460dca90977f199acAdam Powell * 71356c2d337e02a275397fc9d0460dca90977f199acAdam Powell * @param enabled True to clip to the screen. 71456c2d337e02a275397fc9d0460dca90977f199acAdam Powell * @hide 71556c2d337e02a275397fc9d0460dca90977f199acAdam Powell */ 71656c2d337e02a275397fc9d0460dca90977f199acAdam Powell public void setClipToScreenEnabled(boolean enabled) { 71756c2d337e02a275397fc9d0460dca90977f199acAdam Powell mClipToScreen = enabled; 71856c2d337e02a275397fc9d0460dca90977f199acAdam Powell setClippingEnabled(!enabled); 71956c2d337e02a275397fc9d0460dca90977f199acAdam Powell } 720348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell 721348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell /** 722348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * Allow PopupWindow to scroll the anchor's parent to provide more room 723348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * for the popup. Enabled by default. 724348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * 725348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * @param enabled True to scroll the anchor's parent when more room is desired by the popup. 726348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell */ 727348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell void setAllowScrollingAnchorParent(boolean enabled) { 728348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell mAllowScrollingAnchorParent = enabled; 729348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell } 7305435a30ae552391f14009c4459731ae149675b18Alan Viverette 73156c2d337e02a275397fc9d0460dca90977f199acAdam Powell /** 73201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * <p>Indicates whether the popup window supports splitting touches.</p> 7335435a30ae552391f14009c4459731ae149675b18Alan Viverette * 73401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * @return true if the touch splitting is enabled, false otherwise 7355435a30ae552391f14009c4459731ae149675b18Alan Viverette * 73601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * @see #setSplitTouchEnabled(boolean) 73701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown */ 73801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown public boolean isSplitTouchEnabled() { 73946e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown if (mSplitTouchEnabled < 0 && mContext != null) { 74046e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown return mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB; 74146e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown } 74246e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown return mSplitTouchEnabled == 1; 74301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown } 74401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown 74501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown /** 74601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * <p>Allows the popup window to split touches across other windows that also 74746e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown * support split touch. When this flag is false, the first pointer 74801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * that goes down determines the window to which all subsequent touches 74946e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown * go until all pointers go up. When this flag is true, each pointer 75001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * (not necessarily the first) that goes down determines the window 75101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * to which all subsequent touches of that pointer will go until that 75201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * pointer goes up thereby enabling touches with multiple pointers 75301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * to be split across multiple windows.</p> 75401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * 75501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * @param enabled true if the split touches should be enabled, false otherwise 75601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * @see #isSplitTouchEnabled() 75701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown */ 75801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown public void setSplitTouchEnabled(boolean enabled) { 75946e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown mSplitTouchEnabled = enabled ? 1 : 0; 76001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown } 76101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown 76201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown /** 763ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * <p>Indicates whether the popup window will be forced into using absolute screen coordinates 764ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * for positioning.</p> 765ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * 766ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * @return true if the window will always be positioned in screen coordinates. 767ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * @hide 768ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell */ 769ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell public boolean isLayoutInScreenEnabled() { 770ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell return mLayoutInScreen; 771ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell } 772ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell 773ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell /** 774ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * <p>Allows the popup window to force the flag 775ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * {@link WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN}, overriding default behavior. 776ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * This will cause the popup to be positioned in absolute screen coordinates.</p> 777ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * 778ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * @param enabled true if the popup should always be positioned in screen coordinates 779ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * @hide 780ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell */ 781ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell public void setLayoutInScreenEnabled(boolean enabled) { 782ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell mLayoutInScreen = enabled; 783ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell } 784ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell 785ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell /** 786393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * <p>Indicates whether the popup window will be attached in the decor frame of its parent 787393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * window. 788393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 789393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @return true if the window will be attached to the decor frame of its parent window. 790393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 791393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @see #setAttachedInDecor(boolean) 792393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR 793393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale */ 794393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale public boolean isAttachedInDecor() { 795393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale return mAttachedInDecor; 796393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale } 797393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 798393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale /** 799393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * <p>This will attach the popup window to the decor frame of the parent window to avoid 800393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * overlaping with screen decorations like the navigation bar. Overrides the default behavior of 801393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * the flag {@link WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR}. 802393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 803393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * <p>By default the flag is set on SDK version {@link Build.VERSION_CODES#LOLLIPOP_MR1} or 804393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * greater and cleared on lesser SDK versions. 805393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 806393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @param enabled true if the popup should be attached to the decor frame of its parent window. 807393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 808393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR 809393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale */ 810393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale public void setAttachedInDecor(boolean enabled) { 811393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale mAttachedInDecor = enabled; 812393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale mAttachedInDecorSet = true; 813393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale } 814393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 815393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale /** 8160bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * Allows the popup window to force the flag 8170bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * {@link WindowManager.LayoutParams#FLAG_LAYOUT_INSET_DECOR}, overriding default behavior. 8180bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * This will cause the popup to inset its content to account for system windows overlaying 8190bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * the screen, such as the status bar. 8200bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * 8210bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * <p>This will often be combined with {@link #setLayoutInScreenEnabled(boolean)}. 8220bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * 8230bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * @param enabled true if the popup's views should inset content to account for system windows, 8240bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * the way that decor views behave for full-screen windows. 8250bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * @hide 8260bd1d0a15294345bf88b20df28466907f982cec7Adam Powell */ 8270bd1d0a15294345bf88b20df28466907f982cec7Adam Powell public void setLayoutInsetDecor(boolean enabled) { 8280bd1d0a15294345bf88b20df28466907f982cec7Adam Powell mLayoutInsetDecor = enabled; 8290bd1d0a15294345bf88b20df28466907f982cec7Adam Powell } 8300bd1d0a15294345bf88b20df28466907f982cec7Adam Powell 8310bd1d0a15294345bf88b20df28466907f982cec7Adam Powell /** 83280ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette * Set the layout type for this window. 83380ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette * <p> 83480ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette * See {@link WindowManager.LayoutParams#type} for possible values. 835574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell * 836574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell * @param layoutType Layout type for this window. 83736344a90c226c90243e4e02bfb13589e120431ddChris Banes * 83836344a90c226c90243e4e02bfb13589e120431ddChris Banes * @see WindowManager.LayoutParams#type 839574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell */ 840574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell public void setWindowLayoutType(int layoutType) { 841574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell mWindowLayoutType = layoutType; 842574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell } 843574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell 844574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell /** 84536344a90c226c90243e4e02bfb13589e120431ddChris Banes * Returns the layout type for this window. 84636344a90c226c90243e4e02bfb13589e120431ddChris Banes * 84736344a90c226c90243e4e02bfb13589e120431ddChris Banes * @see #setWindowLayoutType(int) 848574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell */ 849574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell public int getWindowLayoutType() { 850574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell return mWindowLayoutType; 851574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell } 852574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell 853574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell /** 854e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell * Set whether this window is touch modal or if outside touches will be sent to 855e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell * other windows behind it. 856e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell * @hide 857e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell */ 858e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell public void setTouchModal(boolean touchModal) { 859e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell mNotTouchModal = !touchModal; 860e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell } 861e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell 862e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell /** 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Change the width and height measure specs that are given to the 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window manager by the popup. By default these are 0, meaning that 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the current width or height is requested as an explicit size from 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the window manager. You can supply 8675435a30ae552391f14009c4459731ae149675b18Alan Viverette * {@link ViewGroup.LayoutParams#WRAP_CONTENT} or 868980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * {@link ViewGroup.LayoutParams#MATCH_PARENT} to have that measure 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * spec supplied instead, replacing the absolute width and height that 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * has been set in the popup.</p> 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown.</p> 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param widthSpec an explicit width measure spec mode, either 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link ViewGroup.LayoutParams#WRAP_CONTENT}, 877980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * {@link ViewGroup.LayoutParams#MATCH_PARENT}, or 0 to use the absolute 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * width. 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param heightSpec an explicit height measure spec mode, either 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link ViewGroup.LayoutParams#WRAP_CONTENT}, 881980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * {@link ViewGroup.LayoutParams#MATCH_PARENT}, or 0 to use the absolute 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * height. 883259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * 884259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @deprecated Use {@link #setWidth(int)} and {@link #setHeight(int)}. 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 886259c2840691a79634ffd8f63291ec21c21819542Alan Viverette @Deprecated 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setWindowLayoutMode(int widthSpec, int heightSpec) { 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWidthMode = widthSpec; 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeightMode = heightSpec; 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8915435a30ae552391f14009c4459731ae149675b18Alan Viverette 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 893259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Returns the popup's height MeasureSpec. 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the height MeasureSpec of the popup 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setHeight(int) 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getHeight() { 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mHeight; 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 903259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Sets the popup's height MeasureSpec. 904259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 905259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * If the popup is showing, calling this method will take effect the next 906259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * time the popup is shown. 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param height the height MeasureSpec of the popup 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getHeight() 9105435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setHeight(int height) { 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeight = height; 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 917259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Returns the popup's width MeasureSpec. 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the width MeasureSpec of the popup 9205435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #setWidth(int) 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getWidth() { 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mWidth; 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 927259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Sets the popup's width MeasureSpec. 928259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 929259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * If the popup is showing, calling this method will take effect the next 930259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * time the popup is shown. 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param width the width MeasureSpec of the popup 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getWidth() 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isShowing() 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setWidth(int width) { 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWidth = width; 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 94175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Sets whether the popup window should overlap its anchor view when 94275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * displayed as a drop-down. 94375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * <p> 94475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If the popup is showing, calling this method will take effect only 94575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * the next time the popup is shown. 94675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * 94775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @param overlapAnchor Whether the popup should overlap its anchor. 94875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * 94975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @see #getOverlapAnchor() 95075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @see #isShowing() 95175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette */ 95275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette public void setOverlapAnchor(boolean overlapAnchor) { 95375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette mOverlapAnchor = overlapAnchor; 95475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette } 95575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette 95675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette /** 95775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Returns whether the popup window should overlap its anchor view when 95875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * displayed as a drop-down. 95975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * 96075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @return Whether the popup should overlap its anchor. 96175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * 96275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @see #setOverlapAnchor(boolean) 96375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette */ 96475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette public boolean getOverlapAnchor() { 96575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette return mOverlapAnchor; 96675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette } 96775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette 96875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette /** 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicate whether this popup window is showing on screen.</p> 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is showing, false otherwise 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isShowing() { 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mIsShowing; 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Display the content view in a popup window at the specified location. If the popup window 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cannot fit on screen, it will be clipped. See {@link android.view.WindowManager.LayoutParams} 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for more information on how gravity and the x and y parameters are related. Specifying 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a gravity of {@link android.view.Gravity#NO_GRAVITY} is similar to specifying 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>Gravity.LEFT | Gravity.TOP</code>. 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p> 9855435a30ae552391f14009c4459731ae149675b18Alan Viverette * 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param parent a parent view to get the {@link android.view.View#getWindowToken()} token from 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param gravity the gravity which controls the placement of the popup window 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x the popup's x location offset 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y the popup's y location offset 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void showAtLocation(View parent, int gravity, int x, int y) { 9928ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell showAtLocation(parent.getWindowToken(), gravity, x, y); 9938ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell } 9948ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell 9958ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell /** 9968ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * Display the content view in a popup window at the specified location. 9978ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * 9988ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @param token Window token to use for creating the new window 9998ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @param gravity the gravity which controls the placement of the popup window 10008ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @param x the popup's x location offset 10018ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @param y the popup's y location offset 10028ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * 10038ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @hide Internal use only. Applications should use 10048ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * {@link #showAtLocation(View, int, int, int)} instead. 10058ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell */ 10068ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell public void showAtLocation(IBinder token, int gravity, int x, int y) { 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isShowing() || mContentView == null) { 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1011e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette TransitionManager.endTransitions(mDecorView); 1012e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterForScrollChanged(); 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsShowing = true; 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsDropdown = false; 10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1018e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final WindowManager.LayoutParams p = createPopupLayoutParams(token); 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project preparePopup(p); 1020e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1021e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // Only override the default if some gravity was specified. 1022e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette if (gravity != Gravity.NO_GRAVITY) { 1023e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.gravity = gravity; 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1025e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.x = x; 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.y = y; 1028e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokePopup(p); 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 103375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Display the content view in a popup window anchored to the bottom-left 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * corner of the anchor view. If there is not enough room on screen to show 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the popup in its entirety, this method tries to find a parent scroll 103675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * view to scroll. If no parent scroll view can be scrolled, the 103775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * bottom-left corner of the popup is pinned at the top left corner of the 103875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * anchor view. 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the view on which to pin the popup window 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #dismiss() 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void showAsDropDown(View anchor) { 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project showAsDropDown(anchor, 0, 0); 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 104975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Display the content view in a popup window anchored to the bottom-left 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * corner of the anchor view offset by the specified x and y coordinates. 105175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If there is not enough room on screen to show the popup in its entirety, 105275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * this method tries to find a parent scroll view to scroll. If no parent 105375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * scroll view can be scrolled, the bottom-left corner of the popup is 105475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * pinned at the top left corner of the anchor view. 105575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * <p> 105675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If the view later scrolls to move <code>anchor</code> to a different 105775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * location, the popup will be moved correspondingly. 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the view on which to pin the popup window 106054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param xoff A horizontal offset from the anchor in pixels 106154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param yoff A vertical offset from the anchor in pixels 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #dismiss() 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void showAsDropDown(View anchor, int xoff, int yoff) { 106654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell showAsDropDown(anchor, xoff, yoff, DEFAULT_ANCHORED_GRAVITY); 106754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell } 106854c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 106954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell /** 107075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Displays the content view in a popup window anchored to the corner of 107175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * another view. The window is positioned according to the specified 107275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * gravity and offset by the specified x and y coordinates. 107375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * <p> 107475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If there is not enough room on screen to show the popup in its entirety, 107575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * this method tries to find a parent scroll view to scroll. If no parent 107675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * view can be scrolled, the specified vertical gravity will be ignored and 107775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * the popup will anchor itself such that it is visible. 107875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * <p> 107975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If the view later scrolls to move <code>anchor</code> to a different 108075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * location, the popup will be moved correspondingly. 108154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * 108254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param anchor the view on which to pin the popup window 108354c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param xoff A horizontal offset from the anchor in pixels 108454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param yoff A vertical offset from the anchor in pixels 108554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param gravity Alignment of the popup relative to the anchor 108654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * 108754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @see #dismiss() 108854c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell */ 108954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell public void showAsDropDown(View anchor, int xoff, int yoff, int gravity) { 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isShowing() || mContentView == null) { 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1094e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette TransitionManager.endTransitions(mDecorView); 1095e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 109654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell registerForScrollChanged(anchor, xoff, yoff, gravity); 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsShowing = true; 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsDropdown = true; 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1101e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final WindowManager.LayoutParams p = createPopupLayoutParams(anchor.getWindowToken()); 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project preparePopup(p); 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1104e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final boolean aboveAnchor = findDropDownPosition(anchor, p, xoff, yoff, gravity); 1105e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette updateAboveAnchor(aboveAnchor); 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokePopup(p); 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11103e141685003939a9addce21ba2492ea3a8aebee6Romain Guy private void updateAboveAnchor(boolean aboveAnchor) { 11113e141685003939a9addce21ba2492ea3a8aebee6Romain Guy if (aboveAnchor != mAboveAnchor) { 11123e141685003939a9addce21ba2492ea3a8aebee6Romain Guy mAboveAnchor = aboveAnchor; 11133e141685003939a9addce21ba2492ea3a8aebee6Romain Guy 11143e141685003939a9addce21ba2492ea3a8aebee6Romain Guy if (mBackground != null) { 11153e141685003939a9addce21ba2492ea3a8aebee6Romain Guy // If the background drawable provided was a StateListDrawable with above-anchor 11163e141685003939a9addce21ba2492ea3a8aebee6Romain Guy // and below-anchor states, use those. Otherwise rely on refreshDrawableState to 11173e141685003939a9addce21ba2492ea3a8aebee6Romain Guy // do the job. 11183e141685003939a9addce21ba2492ea3a8aebee6Romain Guy if (mAboveAnchorBackgroundDrawable != null) { 11193e141685003939a9addce21ba2492ea3a8aebee6Romain Guy if (mAboveAnchor) { 11205435a30ae552391f14009c4459731ae149675b18Alan Viverette mDecorView.setBackground(mAboveAnchorBackgroundDrawable); 11213e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } else { 11225435a30ae552391f14009c4459731ae149675b18Alan Viverette mDecorView.setBackground(mBelowAnchorBackgroundDrawable); 11233e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 11243e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } else { 11255435a30ae552391f14009c4459731ae149675b18Alan Viverette mDecorView.refreshDrawableState(); 11263e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 11273e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 11283e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 11293e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 11303e141685003939a9addce21ba2492ea3a8aebee6Romain Guy 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Indicates whether the popup is showing above (the y coordinate of the popup's bottom 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is less than the y coordinate of the anchor) or below the anchor view (the y coordinate 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the popup is greater than y coordinate of the anchor's bottom). 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The value returned 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by this method is meaningful only after {@link #showAsDropDown(android.view.View)} 11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or {@link #showAsDropDown(android.view.View, int, int)} was invoked. 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return True if this popup is showing above the anchor view, false otherwise. 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isAboveAnchor() { 11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAboveAnchor; 11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1147e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette * Prepare the popup by embedding it into a new ViewGroup if the background 1148e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette * drawable is not null. If embedding is required, the layout parameters' 1149e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette * height is modified to take into account the background's padding. 11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param p the layout parameters of the popup's content view 11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void preparePopup(WindowManager.LayoutParams p) { 1154448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy if (mContentView == null || mContext == null || mWindowManager == null) { 1155448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy throw new IllegalStateException("You must specify a valid content view by " 1156448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy + "calling setContentView() before attempting to show the popup."); 1157448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy } 1158448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy 11598fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // The old decor view may be transitioning out. Make sure it finishes 11608fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // and cleans up before we try to create another one. 11618fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (mDecorView != null) { 11628fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mDecorView.cancelTransitions(); 11638fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 11648fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 11655435a30ae552391f14009c4459731ae149675b18Alan Viverette // When a background is available, we embed the content view within 11665435a30ae552391f14009c4459731ae149675b18Alan Viverette // another view that owns the background drawable. 11678fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View backgroundView; 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBackground != null) { 11698fd949e680c15d397084430d4907c16cedfacddaAlan Viverette backgroundView = createBackgroundView(mContentView); 11708fd949e680c15d397084430d4907c16cedfacddaAlan Viverette backgroundView.setBackground(mBackground); 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11728fd949e680c15d397084430d4907c16cedfacddaAlan Viverette backgroundView = mContentView; 11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1174ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette 11758fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mDecorView = createDecorView(backgroundView); 11765435a30ae552391f14009c4459731ae149675b18Alan Viverette 11775435a30ae552391f14009c4459731ae149675b18Alan Viverette // The background owner should be elevated so that it casts a shadow. 11788fd949e680c15d397084430d4907c16cedfacddaAlan Viverette backgroundView.setElevation(mElevation); 11795435a30ae552391f14009c4459731ae149675b18Alan Viverette 11805435a30ae552391f14009c4459731ae149675b18Alan Viverette // We may wrap that in another view, so we'll need to manually specify 11815435a30ae552391f14009c4459731ae149675b18Alan Viverette // the surface insets. 11828fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final int surfaceInset = (int) Math.ceil(backgroundView.getZ() * 2); 11835435a30ae552391f14009c4459731ae149675b18Alan Viverette p.surfaceInsets.set(surfaceInset, surfaceInset, surfaceInset, surfaceInset); 11845435a30ae552391f14009c4459731ae149675b18Alan Viverette p.hasManualSurfaceInsets = true; 11855435a30ae552391f14009c4459731ae149675b18Alan Viverette 1186b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio mPopupViewInitialLayoutDirectionInherited = 11875435a30ae552391f14009c4459731ae149675b18Alan Viverette (mContentView.getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT); 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPopupWidth = p.width; 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPopupHeight = p.height; 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11935435a30ae552391f14009c4459731ae149675b18Alan Viverette * Wraps a content view in a PopupViewContainer. 11945435a30ae552391f14009c4459731ae149675b18Alan Viverette * 11955435a30ae552391f14009c4459731ae149675b18Alan Viverette * @param contentView the content view to wrap 11965435a30ae552391f14009c4459731ae149675b18Alan Viverette * @return a PopupViewContainer that wraps the content view 11975435a30ae552391f14009c4459731ae149675b18Alan Viverette */ 11985435a30ae552391f14009c4459731ae149675b18Alan Viverette private PopupBackgroundView createBackgroundView(View contentView) { 11995435a30ae552391f14009c4459731ae149675b18Alan Viverette final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams(); 12005435a30ae552391f14009c4459731ae149675b18Alan Viverette final int height; 12015435a30ae552391f14009c4459731ae149675b18Alan Viverette if (layoutParams != null && layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) { 12025435a30ae552391f14009c4459731ae149675b18Alan Viverette height = ViewGroup.LayoutParams.WRAP_CONTENT; 12035435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 12045435a30ae552391f14009c4459731ae149675b18Alan Viverette height = ViewGroup.LayoutParams.MATCH_PARENT; 12055435a30ae552391f14009c4459731ae149675b18Alan Viverette } 12065435a30ae552391f14009c4459731ae149675b18Alan Viverette 12075435a30ae552391f14009c4459731ae149675b18Alan Viverette final PopupBackgroundView backgroundView = new PopupBackgroundView(mContext); 12085435a30ae552391f14009c4459731ae149675b18Alan Viverette final PopupBackgroundView.LayoutParams listParams = new PopupBackgroundView.LayoutParams( 12095435a30ae552391f14009c4459731ae149675b18Alan Viverette ViewGroup.LayoutParams.MATCH_PARENT, height); 12105435a30ae552391f14009c4459731ae149675b18Alan Viverette backgroundView.addView(contentView, listParams); 12115435a30ae552391f14009c4459731ae149675b18Alan Viverette 12125435a30ae552391f14009c4459731ae149675b18Alan Viverette return backgroundView; 12135435a30ae552391f14009c4459731ae149675b18Alan Viverette } 12145435a30ae552391f14009c4459731ae149675b18Alan Viverette 12155435a30ae552391f14009c4459731ae149675b18Alan Viverette /** 12165435a30ae552391f14009c4459731ae149675b18Alan Viverette * Wraps a content view in a FrameLayout. 12175435a30ae552391f14009c4459731ae149675b18Alan Viverette * 12185435a30ae552391f14009c4459731ae149675b18Alan Viverette * @param contentView the content view to wrap 12195435a30ae552391f14009c4459731ae149675b18Alan Viverette * @return a FrameLayout that wraps the content view 12205435a30ae552391f14009c4459731ae149675b18Alan Viverette */ 12215435a30ae552391f14009c4459731ae149675b18Alan Viverette private PopupDecorView createDecorView(View contentView) { 12225435a30ae552391f14009c4459731ae149675b18Alan Viverette final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams(); 12235435a30ae552391f14009c4459731ae149675b18Alan Viverette final int height; 12245435a30ae552391f14009c4459731ae149675b18Alan Viverette if (layoutParams != null && layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) { 12255435a30ae552391f14009c4459731ae149675b18Alan Viverette height = ViewGroup.LayoutParams.WRAP_CONTENT; 12265435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 12275435a30ae552391f14009c4459731ae149675b18Alan Viverette height = ViewGroup.LayoutParams.MATCH_PARENT; 12285435a30ae552391f14009c4459731ae149675b18Alan Viverette } 12295435a30ae552391f14009c4459731ae149675b18Alan Viverette 12305435a30ae552391f14009c4459731ae149675b18Alan Viverette final PopupDecorView decorView = new PopupDecorView(mContext); 12315435a30ae552391f14009c4459731ae149675b18Alan Viverette decorView.addView(contentView, ViewGroup.LayoutParams.MATCH_PARENT, height); 12325435a30ae552391f14009c4459731ae149675b18Alan Viverette decorView.setClipChildren(false); 12335435a30ae552391f14009c4459731ae149675b18Alan Viverette decorView.setClipToPadding(false); 12345435a30ae552391f14009c4459731ae149675b18Alan Viverette 12355435a30ae552391f14009c4459731ae149675b18Alan Viverette return decorView; 12365435a30ae552391f14009c4459731ae149675b18Alan Viverette } 12375435a30ae552391f14009c4459731ae149675b18Alan Viverette 12385435a30ae552391f14009c4459731ae149675b18Alan Viverette /** 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Invoke the popup window by adding the content view to the window 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * manager.</p> 12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The content view must be non-null when this method is invoked.</p> 12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param p the layout parameters of the popup's content view 12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void invokePopup(WindowManager.LayoutParams p) { 12470c0b768e1514280812321854db6dfba723c3d169Romain Guy if (mContext != null) { 12480c0b768e1514280812321854db6dfba723c3d169Romain Guy p.packageName = mContext.getPackageName(); 12490c0b768e1514280812321854db6dfba723c3d169Romain Guy } 12505435a30ae552391f14009c4459731ae149675b18Alan Viverette 12518fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final PopupDecorView decorView = mDecorView; 12528fd949e680c15d397084430d4907c16cedfacddaAlan Viverette decorView.setFitsSystemWindows(mLayoutInsetDecor); 12535435a30ae552391f14009c4459731ae149675b18Alan Viverette 12548fd949e680c15d397084430d4907c16cedfacddaAlan Viverette setLayoutDirectionFromAnchor(); 12555435a30ae552391f14009c4459731ae149675b18Alan Viverette 12568fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mWindowManager.addView(decorView, p); 125795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 125895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette if (mEnterTransition != null) { 125995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette decorView.requestEnterTransition(mEnterTransition); 126095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette } 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1263b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio private void setLayoutDirectionFromAnchor() { 1264b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio if (mAnchor != null) { 1265b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio View anchor = mAnchor.get(); 1266b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio if (anchor != null && mPopupViewInitialLayoutDirectionInherited) { 12675435a30ae552391f14009c4459731ae149675b18Alan Viverette mDecorView.setLayoutDirection(anchor.getLayoutDirection()); 1268b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio } 1269b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio } 1270b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio } 1271b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio 12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Generate the layout parameters for the popup window.</p> 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param token the window token used to bind the popup's window 12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the layout parameters to pass to the window manager 12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1279e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette private WindowManager.LayoutParams createPopupLayoutParams(IBinder token) { 1280e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final WindowManager.LayoutParams p = new WindowManager.LayoutParams(); 1281e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1282e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // These gravity settings put the view at the top left corner of the 1283e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // screen. The view is then positioned to the appropriate location by 1284e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // setting the x and y offsets to match the anchor's bottom-left 1285e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // corner. 1286aac0d4ed026d1cfbcf3fa81c6e4eb96f4347ca17Fabrice Di Meglio p.gravity = Gravity.START | Gravity.TOP; 1287e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.flags = computeFlags(p.flags); 1288e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.type = mWindowLayoutType; 1289e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.token = token; 1290e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.softInputMode = mSoftInputMode; 1291e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.windowAnimations = computeAnimationResource(); 1292e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBackground != null) { 12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.format = mBackground.getOpacity(); 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.format = PixelFormat.TRANSLUCENT; 12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1298e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1299e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette if (mHeightMode < 0) { 1300e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.height = mLastHeight = mHeightMode; 1301e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } else { 1302e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.height = mLastHeight = mHeight; 1303e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } 1304e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1305e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette if (mWidthMode < 0) { 1306e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.width = mLastWidth = mWidthMode; 1307e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } else { 1308e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.width = mLastWidth = mWidth; 1309e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } 1310e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1311e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // Used for debugging. 13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.setTitle("PopupWindow:" + Integer.toHexString(hashCode())); 13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return p; 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int computeFlags(int curFlags) { 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags &= ~( 13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES | 13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | 13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | 13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | 13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | 1324ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM | 1325ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell WindowManager.LayoutParams.FLAG_SPLIT_TOUCH); 13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(mIgnoreCheekPress) { 13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES; 13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mFocusable) { 13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mInputMethodMode == INPUT_METHOD_NEEDED) { 13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mInputMethodMode == INPUT_METHOD_NOT_NEEDED) { 13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mTouchable) { 13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1340c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project if (mOutsideTouchable) { 13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH; 13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mClippingEnabled) { 13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; 13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 134646e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown if (isSplitTouchEnabled()) { 134701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown curFlags |= WindowManager.LayoutParams.FLAG_SPLIT_TOUCH; 134801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown } 1349ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell if (mLayoutInScreen) { 1350ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; 1351ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell } 13520bd1d0a15294345bf88b20df28466907f982cec7Adam Powell if (mLayoutInsetDecor) { 13530bd1d0a15294345bf88b20df28466907f982cec7Adam Powell curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; 13540bd1d0a15294345bf88b20df28466907f982cec7Adam Powell } 1355e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell if (mNotTouchModal) { 1356e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; 1357e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell } 1358393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale if (mAttachedInDecor) { 1359393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR; 1360393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale } 13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return curFlags; 13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1363393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int computeAnimationResource() { 13655435a30ae552391f14009c4459731ae149675b18Alan Viverette if (mAnimationStyle == ANIMATION_STYLE_DEFAULT) { 13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsDropdown) { 13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAboveAnchor 13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ? com.android.internal.R.style.Animation_DropDownUp 13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : com.android.internal.R.style.Animation_DropDownDown; 13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAnimationStyle; 13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1375560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1377560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * Positions the popup window on screen. When the popup window is too tall 1378560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * to fit under the anchor, a parent scroll view is seeked and scrolled up 1379560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * to reclaim space. If scrolling is not possible or not enough, the popup 1380560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * window gets moved on top of the anchor. 1381560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * <p> 1382560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * The height must have been set on the layout parameters prior to calling 1383560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * this method. 13845435a30ae552391f14009c4459731ae149675b18Alan Viverette * 13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the view on which the popup window must be anchored 13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param p the layout parameters used to display the drop down 1387560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * @param xoff horizontal offset used to adjust for background padding 1388560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * @param yoff vertical offset used to adjust for background padding 1389560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * @param gravity horizontal gravity specifying popup alignment 13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is translated upwards to fit on screen 13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1392560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette private boolean findDropDownPosition(View anchor, WindowManager.LayoutParams p, int xoff, 1393560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette int yoff, int gravity) { 139462e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell final int anchorHeight = anchor.getHeight(); 1395560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int anchorWidth = anchor.getWidth(); 1396560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette if (mOverlapAnchor) { 1397560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette yoff -= anchorHeight; 1398560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette } 1399560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anchor.getLocationInWindow(mDrawingLocation); 14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.x = mDrawingLocation[0] + xoff; 140262e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell p.y = mDrawingLocation[1] + anchorHeight + yoff; 140354c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 1404560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int hgrav = Gravity.getAbsoluteGravity(gravity, anchor.getLayoutDirection()) 1405560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette & Gravity.HORIZONTAL_GRAVITY_MASK; 140654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell if (hgrav == Gravity.RIGHT) { 1407560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // Flip the location to align the right sides of the popup and 1408560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // anchor instead of left. 1409560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette p.x -= mPopupWidth - anchorWidth; 141054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell } 1411560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean onTop = false; 14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 141454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell p.gravity = Gravity.LEFT | Gravity.TOP; 141554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anchor.getLocationOnScreen(mScreenLocation); 14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect displayFrame = new Rect(); 14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anchor.getWindowVisibleDisplayFrame(displayFrame); 141962e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell 1420560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int screenY = mScreenLocation[1] + anchorHeight + yoff; 14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View root = anchor.getRootView(); 1422560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette if (screenY + mPopupHeight > displayFrame.bottom 1423560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette || p.x + mPopupWidth - root.getWidth() > 0) { 1424560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // If the drop down disappears at the bottom of the screen, we try 1425560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // to scroll a parent scrollview or move the drop down back up on 1426560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // top of the edit box. 1427b7c1b20c8a5a4d4378ae91b4a1f12a34100df452Adam Powell if (mAllowScrollingAnchorParent) { 1428560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int scrollX = anchor.getScrollX(); 1429560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int scrollY = anchor.getScrollY(); 1430560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final Rect r = new Rect(scrollX, scrollY, scrollX + mPopupWidth + xoff, 1431560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette scrollY + mPopupHeight + anchorHeight + yoff); 1432b7c1b20c8a5a4d4378ae91b4a1f12a34100df452Adam Powell anchor.requestRectangleOnScreen(r, true); 1433b7c1b20c8a5a4d4378ae91b4a1f12a34100df452Adam Powell } 14343e141685003939a9addce21ba2492ea3a8aebee6Romain Guy 1435560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // Now we re-evaluate the space available, and decide from that 14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // whether the pop-up will go above or below the anchor. 14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anchor.getLocationInWindow(mDrawingLocation); 14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.x = mDrawingLocation[0] + xoff; 1439560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette p.y = mDrawingLocation[1] + anchorHeight + yoff; 144054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 1441560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // Preserve the gravity adjustment. 144254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell if (hgrav == Gravity.RIGHT) { 1443560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette p.x -= mPopupWidth - anchorWidth; 144454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell } 1445560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 1446560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // Determine whether there is more space above or below the anchor. 14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anchor.getLocationOnScreen(mScreenLocation); 1448560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette onTop = (displayFrame.bottom - mScreenLocation[1] - anchorHeight - yoff) < 14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (mScreenLocation[1] - yoff - displayFrame.top); 14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (onTop) { 145154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell p.gravity = Gravity.LEFT | Gravity.BOTTOM; 14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.y = root.getHeight() - mDrawingLocation[1] + yoff; 14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1454560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette p.y = mDrawingLocation[1] + anchorHeight + yoff; 14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 145856c2d337e02a275397fc9d0460dca90977f199acAdam Powell if (mClipToScreen) { 145956c2d337e02a275397fc9d0460dca90977f199acAdam Powell final int displayFrameWidth = displayFrame.right - displayFrame.left; 1460560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int right = p.x + p.width; 146156c2d337e02a275397fc9d0460dca90977f199acAdam Powell if (right > displayFrameWidth) { 146256c2d337e02a275397fc9d0460dca90977f199acAdam Powell p.x -= right - displayFrameWidth; 146356c2d337e02a275397fc9d0460dca90977f199acAdam Powell } 1464560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 146556c2d337e02a275397fc9d0460dca90977f199acAdam Powell if (p.x < displayFrame.left) { 146656c2d337e02a275397fc9d0460dca90977f199acAdam Powell p.x = displayFrame.left; 146756c2d337e02a275397fc9d0460dca90977f199acAdam Powell p.width = Math.min(p.width, displayFrameWidth); 146856c2d337e02a275397fc9d0460dca90977f199acAdam Powell } 146956c2d337e02a275397fc9d0460dca90977f199acAdam Powell 14705f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell if (onTop) { 1471560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int popupTop = mScreenLocation[1] + yoff - mPopupHeight; 14725f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell if (popupTop < 0) { 14735f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell p.y += popupTop; 14745f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell } 14755f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell } else { 14765f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell p.y = Math.max(p.y, displayFrame.top); 14775f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell } 147856c2d337e02a275397fc9d0460dca90977f199acAdam Powell } 147956c2d337e02a275397fc9d0460dca90977f199acAdam Powell 14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.gravity |= Gravity.DISPLAY_CLIP_VERTICAL; 1481560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return onTop; 14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14845435a30ae552391f14009c4459731ae149675b18Alan Viverette 14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the maximum height that is available for the popup to be 14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * completely shown. It is recommended that this height be the maximum for 14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the popup's height, otherwise it is possible that the popup will be 14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clipped. 14905435a30ae552391f14009c4459731ae149675b18Alan Viverette * 14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor The view on which the popup window must be anchored. 14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The maximum available height for the popup to be completely 14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * shown. 14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getMaxAvailableHeight(View anchor) { 14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return getMaxAvailableHeight(anchor, 0); 14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the maximum height that is available for the popup to be 15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * completely shown. It is recommended that this height be the maximum for 15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the popup's height, otherwise it is possible that the popup will be 15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clipped. 15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor The view on which the popup window must be anchored. 15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param yOffset y offset from the view's bottom edge 15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The maximum available height for the popup to be completely 15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * shown. 15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getMaxAvailableHeight(View anchor, int yOffset) { 151198acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau return getMaxAvailableHeight(anchor, yOffset, false); 151298acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau } 15135435a30ae552391f14009c4459731ae149675b18Alan Viverette 151498acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau /** 151598acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * Returns the maximum height that is available for the popup to be 151698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * completely shown, optionally ignoring any bottom decorations such as 151798acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * the input method. It is recommended that this height be the maximum for 151898acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * the popup's height, otherwise it is possible that the popup will be 151998acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * clipped. 15205435a30ae552391f14009c4459731ae149675b18Alan Viverette * 152198acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @param anchor The view on which the popup window must be anchored. 152298acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @param yOffset y offset from the view's bottom edge 152398acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @param ignoreBottomDecorations if true, the height returned will be 152498acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * all the way to the bottom of the display, ignoring any 152598acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * bottom decorations 152698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @return The maximum available height for the popup to be completely 152798acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * shown. 15285435a30ae552391f14009c4459731ae149675b18Alan Viverette * 152998acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @hide Pending API council approval. 153098acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau */ 153198acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau public int getMaxAvailableHeight(View anchor, int yOffset, boolean ignoreBottomDecorations) { 15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect displayFrame = new Rect(); 15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anchor.getWindowVisibleDisplayFrame(displayFrame); 15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int[] anchorPos = mDrawingLocation; 15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anchor.getLocationOnScreen(anchorPos); 15375435a30ae552391f14009c4459731ae149675b18Alan Viverette 153898acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau int bottomEdge = displayFrame.bottom; 153998acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau if (ignoreBottomDecorations) { 1540a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powell Resources res = anchor.getContext().getResources(); 15413f4a764cf400aa209c1f8f76a1c73143eefc4905Adam Powell bottomEdge = res.getDisplayMetrics().heightPixels; 154298acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau } 154398acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau final int distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset; 15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset; 15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // anchorPos[1] is distance from anchor to top of screen 15479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int returnedHeight = Math.max(distanceToBottom, distanceToTop); 15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBackground != null) { 15499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBackground.getPadding(mTempRect); 15505435a30ae552391f14009c4459731ae149675b18Alan Viverette returnedHeight -= mTempRect.top + mTempRect.bottom; 15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15525435a30ae552391f14009c4459731ae149675b18Alan Viverette 15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return returnedHeight; 15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15555435a30ae552391f14009c4459731ae149675b18Alan Viverette 15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15577878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette * Disposes of the popup window. This method can be invoked only after 15587878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette * {@link #showAsDropDown(android.view.View)} has been executed. Failing 15597878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette * that, calling this method will have no effect. 15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15615435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #showAsDropDown(android.view.View) 15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dismiss() { 15648fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (!isShowing() || mIsTransitioningToDismiss) { 1565e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette return; 1566e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } 156706f938e8aa56cd89ab0bdb04c8b946392c428dd1Svetoslav Ganov 15688fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final PopupDecorView decorView = mDecorView; 15698fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View contentView = mContentView; 15708fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 15718fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewGroup contentHolder; 15728fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewParent contentParent = contentView.getParent(); 15738fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (contentParent instanceof ViewGroup) { 15748fd949e680c15d397084430d4907c16cedfacddaAlan Viverette contentHolder = ((ViewGroup) contentParent); 15758fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } else { 15768fd949e680c15d397084430d4907c16cedfacddaAlan Viverette contentHolder = null; 15778fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 15788fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 15798fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // Ensure any ongoing or pending transitions are canceled. 15808fd949e680c15d397084430d4907c16cedfacddaAlan Viverette decorView.cancelTransitions(); 15818fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 1582e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette mIsShowing = false; 15838fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mIsTransitioningToDismiss = true; 1584b82d074038f4c8d86e1bd4f3fa4d3780bd4bcba5Craig Mautner 158595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final Transition exitTransition = mExitTransition; 158695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette if (exitTransition != null && decorView.isLaidOut()) { 158795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette // The decor view is non-interactive during exit transitions. 158895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final LayoutParams p = (LayoutParams) decorView.getLayoutParams(); 158995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette p.flags |= LayoutParams.FLAG_NOT_TOUCHABLE; 159095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette p.flags |= LayoutParams.FLAG_NOT_FOCUSABLE; 159195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette mWindowManager.updateViewLayout(decorView, p); 159295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 159395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final Rect epicenter = getRelativeAnchorBounds(); 159495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette exitTransition.setEpicenterCallback(new EpicenterCallback() { 159595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette @Override 159695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette public Rect onGetEpicenter(Transition transition) { 159795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette return epicenter; 159895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette } 159995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette }); 160095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette decorView.startExitTransition(exitTransition, new TransitionListenerAdapter() { 1601e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette @Override 1602e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette public void onTransitionEnd(Transition transition) { 16038fd949e680c15d397084430d4907c16cedfacddaAlan Viverette dismissImmediate(decorView, contentHolder, contentView); 1604e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } 1605e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette }); 1606e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } else { 16078fd949e680c15d397084430d4907c16cedfacddaAlan Viverette dismissImmediate(decorView, contentHolder, contentView); 16087878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette } 16097878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette 161095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette // Clears the anchor view. 161195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette unregisterForScrollChanged(); 161295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 16137878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette if (mOnDismissListener != null) { 16147878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette mOnDismissListener.onDismiss(); 16155435a30ae552391f14009c4459731ae149675b18Alan Viverette } 16165435a30ae552391f14009c4459731ae149675b18Alan Viverette } 16175435a30ae552391f14009c4459731ae149675b18Alan Viverette 161895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette private Rect getRelativeAnchorBounds() { 161995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final View anchor = mAnchor != null ? mAnchor.get() : null; 162095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final View decor = mDecorView; 162195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette if (anchor == null || decor == null) { 162295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette return null; 162395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette } 162495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 162595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final int[] anchorLocation = anchor.getLocationOnScreen(); 162695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final int[] popupLocation = mDecorView.getLocationOnScreen(); 162795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 162895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette // Compute the position of the anchor relative to the popup. 162995888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final Rect bounds = new Rect(0, 0, anchor.getWidth(), anchor.getHeight()); 163095888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette bounds.offset(anchorLocation[0] - popupLocation[0], anchorLocation[1] - popupLocation[1]); 163195888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette return bounds; 163295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette } 163395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette 16345435a30ae552391f14009c4459731ae149675b18Alan Viverette /** 16355435a30ae552391f14009c4459731ae149675b18Alan Viverette * Removes the popup from the window manager and tears down the supporting 16365435a30ae552391f14009c4459731ae149675b18Alan Viverette * view hierarchy, if necessary. 16375435a30ae552391f14009c4459731ae149675b18Alan Viverette */ 16388fd949e680c15d397084430d4907c16cedfacddaAlan Viverette private void dismissImmediate(View decorView, ViewGroup contentHolder, View contentView) { 16398fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // If this method gets called and the decor view doesn't have a parent, 16408fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // then it was either never added or was already removed. That should 16418fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // never happen, but it's worth checking to avoid potential crashes. 16428fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (decorView.getParent() != null) { 16438fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mWindowManager.removeViewImmediate(decorView); 1644df4639a0135ea643b493067b3f7cd1e092346c78Alan Viverette } 1645df4639a0135ea643b493067b3f7cd1e092346c78Alan Viverette 16468fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (contentHolder != null) { 16478fd949e680c15d397084430d4907c16cedfacddaAlan Viverette contentHolder.removeView(contentView); 16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16498fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 16508fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // This needs to stay until after all transitions have ended since we 16518fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // need the reference to cancel transitions in preparePopup(). 16528fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mDecorView = null; 16538fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mIsTransitioningToDismiss = false; 16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the listener to be called when the window is dismissed. 16585435a30ae552391f14009c4459731ae149675b18Alan Viverette * 16599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param onDismissListener The listener. 16609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 16619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setOnDismissListener(OnDismissListener onDismissListener) { 16629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnDismissListener = onDismissListener; 16639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16645435a30ae552391f14009c4459731ae149675b18Alan Viverette 16659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Updates the state of the popup window, if it is currently being displayed, 1667259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * from the currently set state. 1668259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1669259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * This includes: 1670259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <ul> 1671259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setClippingEnabled(boolean)}</li> 1672259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setFocusable(boolean)}</li> 1673259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setIgnoreCheekPress()}</li> 1674259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setInputMethodMode(int)}</li> 1675259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setTouchable(boolean)}</li> 1676259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setAnimationStyle(int)}</li> 1677259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * </ul> 16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update() { 16809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isShowing() || mContentView == null) { 16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16835435a30ae552391f14009c4459731ae149675b18Alan Viverette 16845435a30ae552391f14009c4459731ae149675b18Alan Viverette final WindowManager.LayoutParams p = 16855435a30ae552391f14009c4459731ae149675b18Alan Viverette (WindowManager.LayoutParams) mDecorView.getLayoutParams(); 16865435a30ae552391f14009c4459731ae149675b18Alan Viverette 16879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean update = false; 16885435a30ae552391f14009c4459731ae149675b18Alan Viverette 16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newAnim = computeAnimationResource(); 16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newAnim != p.windowAnimations) { 16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.windowAnimations = newAnim; 16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newFlags = computeFlags(p.flags); 16969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newFlags != p.flags) { 16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.flags = newFlags; 16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1700b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio 17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (update) { 1702b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio setLayoutDirectionFromAnchor(); 17035435a30ae552391f14009c4459731ae149675b18Alan Viverette mWindowManager.updateViewLayout(mDecorView, p); 17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1706d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy 1707d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy /** 1708259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the dimension of the popup window. 1709259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1710259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Calling this function also updates the window with the current popup 1711259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * state as described for {@link #update()}. 1712d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy * 1713259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param width the new width, must be >= 0 or -1 to ignore 1714259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param height the new height, must be >= 0 or -1 to ignore 1715d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy */ 1716d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy public void update(int width, int height) { 17175435a30ae552391f14009c4459731ae149675b18Alan Viverette final WindowManager.LayoutParams p = 17185435a30ae552391f14009c4459731ae149675b18Alan Viverette (WindowManager.LayoutParams) mDecorView.getLayoutParams(); 1719d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy update(p.x, p.y, width, height, false); 1720d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy } 17215435a30ae552391f14009c4459731ae149675b18Alan Viverette 17229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1723259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 1724259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1725259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Width and height can be set to -1 to update location only. Calling this 1726259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * function also updates the window with the current popup state as 1727259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * described for {@link #update()}. 17289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x the new x location 17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y the new y location 1731259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param width the new width, must be >= 0 or -1 to ignore 1732259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param height the new height, must be >= 0 or -1 to ignore 17339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(int x, int y, int width, int height) { 17359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update(x, y, width, height, false); 17369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1739259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 1740259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1741259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Width and height can be set to -1 to update location only. Calling this 1742259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * function also updates the window with the current popup state as 1743259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * described for {@link #update()}. 17449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 17459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x the new x location 17469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y the new y location 1747259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param width the new width, must be >= 0 or -1 to ignore 1748259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param height the new height, must be >= 0 or -1 to ignore 1749259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param force {@code true} to reposition the window even if the specified 1750259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * position already seems to correspond to the LayoutParams, 1751259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * {@code false} to only reposition if needed 17529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 17539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(int x, int y, int width, int height, boolean force) { 1754259c2840691a79634ffd8f63291ec21c21819542Alan Viverette if (width >= 0) { 17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastWidth = width; 17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setWidth(width); 17579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1759259c2840691a79634ffd8f63291ec21c21819542Alan Viverette if (height >= 0) { 17609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastHeight = height; 17619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setHeight(height); 17629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isShowing() || mContentView == null) { 17659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 17669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17685435a30ae552391f14009c4459731ae149675b18Alan Viverette final WindowManager.LayoutParams p = 17695435a30ae552391f14009c4459731ae149675b18Alan Viverette (WindowManager.LayoutParams) mDecorView.getLayoutParams(); 17709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean update = force; 17729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int finalWidth = mWidthMode < 0 ? mWidthMode : mLastWidth; 17749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (width != -1 && p.width != finalWidth) { 17759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.width = mLastWidth = finalWidth; 17769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 17779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int finalHeight = mHeightMode < 0 ? mHeightMode : mLastHeight; 17809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (height != -1 && p.height != finalHeight) { 17819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.height = mLastHeight = finalHeight; 17829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 17839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p.x != x) { 17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.x = x; 17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 17889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p.y != y) { 17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.y = y; 17929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 17939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newAnim = computeAnimationResource(); 17969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newAnim != p.windowAnimations) { 17979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.windowAnimations = newAnim; 17989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 17999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newFlags = computeFlags(p.flags); 18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newFlags != p.flags) { 18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.flags = newFlags; 18049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 18059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 180698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau 18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (update) { 1808b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio setLayoutDirectionFromAnchor(); 18095435a30ae552391f14009c4459731ae149675b18Alan Viverette mWindowManager.updateViewLayout(mDecorView, p); 18109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1814259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 1815259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1816259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Calling this function also updates the window with the current popup 1817259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * state as described for {@link #update()}. 18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 18199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the popup's anchor view 1820259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param width the new width, must be >= 0 or -1 to ignore 1821259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param height the new height, must be >= 0 or -1 to ignore 18229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(View anchor, int width, int height) { 182475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette update(anchor, false, 0, 0, true, width, height); 18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1828259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 1829259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1830259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Width and height can be set to -1 to update location only. Calling this 1831259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * function also updates the window with the current popup state as 1832259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * described for {@link #update()}. 1833259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1834259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * If the view later scrolls to move {@code anchor} to a different 1835259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * location, the popup will be moved correspondingly. 18369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 18379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the popup's anchor view 18389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param xoff x offset from the view's left edge 18399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param yoff y offset from the view's bottom edge 1840259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param width the new width, must be >= 0 or -1 to ignore 1841259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param height the new height, must be >= 0 or -1 to ignore 18429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 18439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(View anchor, int xoff, int yoff, int width, int height) { 184475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette update(anchor, true, xoff, yoff, true, width, height); 1845105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 1846105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 1847105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private void update(View anchor, boolean updateLocation, int xoff, int yoff, 184875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette boolean updateDimension, int width, int height) { 1849105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 18509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isShowing() || mContentView == null) { 18519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 18529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 185475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette final WeakReference<View> oldAnchor = mAnchor; 185575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette final boolean needsUpdate = updateLocation && (mAnchorXoff != xoff || mAnchorYoff != yoff); 185681f08086b44a117097960195d2c9072e29644962Gilles Debunne if (oldAnchor == null || oldAnchor.get() != anchor || (needsUpdate && !mIsDropdown)) { 185775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette registerForScrollChanged(anchor, xoff, yoff, mAnchoredGravity); 185881f08086b44a117097960195d2c9072e29644962Gilles Debunne } else if (needsUpdate) { 185981f08086b44a117097960195d2c9072e29644962Gilles Debunne // No need to register again if this is a DropDown, showAsDropDown already did. 186081f08086b44a117097960195d2c9072e29644962Gilles Debunne mAnchorXoff = xoff; 186181f08086b44a117097960195d2c9072e29644962Gilles Debunne mAnchorYoff = yoff; 18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1864105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (updateDimension) { 1865105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (width == -1) { 1866105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project width = mPopupWidth; 1867105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } else { 1868105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mPopupWidth = width; 1869105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 1870105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (height == -1) { 1871105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project height = mPopupHeight; 1872105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } else { 1873105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mPopupHeight = height; 1874105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 18759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1876105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 187775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette final WindowManager.LayoutParams p = 18785435a30ae552391f14009c4459731ae149675b18Alan Viverette (WindowManager.LayoutParams) mDecorView.getLayoutParams(); 187975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette final int x = p.x; 188075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette final int y = p.y; 1881105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (updateLocation) { 188275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette updateAboveAnchor(findDropDownPosition(anchor, p, xoff, yoff, mAnchoredGravity)); 18839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 188454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell updateAboveAnchor(findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff, 188554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell mAnchoredGravity)); 18869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1887b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio 18883e141685003939a9addce21ba2492ea3a8aebee6Romain Guy update(p.x, p.y, width, height, x != p.x || y != p.y); 18899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Listener that is called when this popup window is dismissed. 18939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnDismissListener { 18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 18969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called when this popup window is dismissed. 18979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 18989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onDismiss(); 18999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void unregisterForScrollChanged() { 1902e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final WeakReference<View> anchorRef = mAnchor; 1903e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final View anchor = anchorRef == null ? null : anchorRef.get(); 19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (anchor != null) { 1905e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final ViewTreeObserver vto = anchor.getViewTreeObserver(); 19069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project vto.removeOnScrollChangedListener(mOnScrollChangedListener); 19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1908e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 19099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnchor = null; 19109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 191254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell private void registerForScrollChanged(View anchor, int xoff, int yoff, int gravity) { 19139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterForScrollChanged(); 19149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19155435a30ae552391f14009c4459731ae149675b18Alan Viverette mAnchor = new WeakReference<>(anchor); 1916e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1917e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final ViewTreeObserver vto = anchor.getViewTreeObserver(); 19189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (vto != null) { 19199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project vto.addOnScrollChangedListener(mOnScrollChangedListener); 19209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnchorXoff = xoff; 19239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnchorYoff = yoff; 192454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell mAnchoredGravity = gravity; 19259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19275435a30ae552391f14009c4459731ae149675b18Alan Viverette private class PopupDecorView extends FrameLayout { 19288fd949e680c15d397084430d4907c16cedfacddaAlan Viverette private TransitionListenerAdapter mPendingExitListener; 19298fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 19305435a30ae552391f14009c4459731ae149675b18Alan Viverette public PopupDecorView(Context context) { 19315435a30ae552391f14009c4459731ae149675b18Alan Viverette super(context); 19325435a30ae552391f14009c4459731ae149675b18Alan Viverette } 19339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 19359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean dispatchKeyEvent(KeyEvent event) { 19369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { 19374ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson if (getKeyDispatcherState() == null) { 19384ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson return super.dispatchKeyEvent(event); 19394ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson } 19404ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson 19415435a30ae552391f14009c4459731ae149675b18Alan Viverette if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { 19425435a30ae552391f14009c4459731ae149675b18Alan Viverette final KeyEvent.DispatcherState state = getKeyDispatcherState(); 1943b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown if (state != null) { 1944b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown state.startTracking(event, this); 1945b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } 19468d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn return true; 1947b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } else if (event.getAction() == KeyEvent.ACTION_UP) { 19485435a30ae552391f14009c4459731ae149675b18Alan Viverette final KeyEvent.DispatcherState state = getKeyDispatcherState(); 1949b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown if (state != null && state.isTracking(event) && !event.isCanceled()) { 1950b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown dismiss(); 1951b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown return true; 1952b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } 19538d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn } 19548d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn return super.dispatchKeyEvent(event); 19559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 19569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.dispatchKeyEvent(event); 19579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 19619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean dispatchTouchEvent(MotionEvent ev) { 19629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTouchInterceptor != null && mTouchInterceptor.onTouch(this, ev)) { 19639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 19649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.dispatchTouchEvent(ev); 19669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 19699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onTouchEvent(MotionEvent event) { 19709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int x = (int) event.getX(); 19719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int y = (int) event.getY(); 19725435a30ae552391f14009c4459731ae149675b18Alan Viverette 19739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((event.getAction() == MotionEvent.ACTION_DOWN) 19749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && ((x < 0) || (x >= getWidth()) || (y < 0) || (y >= getHeight()))) { 19759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dismiss(); 19769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 19779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (event.getAction() == MotionEvent.ACTION_OUTSIDE) { 19789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dismiss(); 19799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 19809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 19819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.onTouchEvent(event); 19829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19848fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 19858fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 19868fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Requests that an enter transition run after the next layout pass. 19878fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 19888fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void requestEnterTransition(Transition transition) { 19898fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewTreeObserver observer = getViewTreeObserver(); 19908fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (observer != null && transition != null) { 19918fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final Transition enterTransition = transition.clone(); 19928fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 19938fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // Postpone the enter transition after the first layout pass. 19948fd949e680c15d397084430d4907c16cedfacddaAlan Viverette observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 19958fd949e680c15d397084430d4907c16cedfacddaAlan Viverette @Override 19968fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void onGlobalLayout() { 19978fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewTreeObserver observer = getViewTreeObserver(); 19988fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (observer != null) { 19998fd949e680c15d397084430d4907c16cedfacddaAlan Viverette observer.removeOnGlobalLayoutListener(this); 20008fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20018fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 200295888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette final Rect epicenter = getRelativeAnchorBounds(); 200395888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette enterTransition.setEpicenterCallback(new EpicenterCallback() { 200495888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette @Override 200595888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette public Rect onGetEpicenter(Transition transition) { 200695888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette return epicenter; 200795888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette } 200895888c07e978f0d6af62ef96124acd228ac2ab13Alan Viverette }); 20098fd949e680c15d397084430d4907c16cedfacddaAlan Viverette startEnterTransition(enterTransition); 20108fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20118fd949e680c15d397084430d4907c16cedfacddaAlan Viverette }); 20128fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20138fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20148fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20158fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 20168fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Starts the pending enter transition, if one is set. 20178fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 20188fd949e680c15d397084430d4907c16cedfacddaAlan Viverette private void startEnterTransition(Transition enterTransition) { 20198fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final int count = getChildCount(); 20208fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 20218fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 20228fd949e680c15d397084430d4907c16cedfacddaAlan Viverette enterTransition.addTarget(child); 20238fd949e680c15d397084430d4907c16cedfacddaAlan Viverette child.setVisibility(View.INVISIBLE); 20248fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20258fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20268fd949e680c15d397084430d4907c16cedfacddaAlan Viverette TransitionManager.beginDelayedTransition(this, enterTransition); 20278fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20288fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 20298fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 20308fd949e680c15d397084430d4907c16cedfacddaAlan Viverette child.setVisibility(View.VISIBLE); 20318fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20328fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20338fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20348fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 20358fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Starts an exit transition immediately. 20368fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * <p> 20378fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * <strong>Note:</strong> The transition listener is guaranteed to have 20388fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * its {@code onTransitionEnd} method called even if the transition 20398fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * never starts; however, it may be called with a {@code null} argument. 20408fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 20418fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void startExitTransition(Transition transition, final TransitionListener listener) { 20428fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (transition == null) { 20438fd949e680c15d397084430d4907c16cedfacddaAlan Viverette return; 20448fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20458fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20468fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // The exit listener MUST be called for cleanup, even if the 20478fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // transition never starts or ends. Stash it for later. 20488fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mPendingExitListener = new TransitionListenerAdapter() { 20498fd949e680c15d397084430d4907c16cedfacddaAlan Viverette @Override 20508fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void onTransitionEnd(Transition transition) { 20518fd949e680c15d397084430d4907c16cedfacddaAlan Viverette listener.onTransitionEnd(transition); 20528fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20538fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // The listener was called. Our job here is done. 20548fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mPendingExitListener = null; 20558fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20568fd949e680c15d397084430d4907c16cedfacddaAlan Viverette }; 20578fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20588fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final Transition exitTransition = transition.clone(); 20598fd949e680c15d397084430d4907c16cedfacddaAlan Viverette exitTransition.addListener(mPendingExitListener); 20608fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20618fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final int count = getChildCount(); 20628fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 20638fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 20648fd949e680c15d397084430d4907c16cedfacddaAlan Viverette exitTransition.addTarget(child); 20658fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20668fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20678fd949e680c15d397084430d4907c16cedfacddaAlan Viverette TransitionManager.beginDelayedTransition(this, exitTransition); 20688fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20698fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 20708fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 20718fd949e680c15d397084430d4907c16cedfacddaAlan Viverette child.setVisibility(View.INVISIBLE); 20728fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20738fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20748fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20758fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 20768fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Cancels all pending or current transitions. 20778fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 20788fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void cancelTransitions() { 20798fd949e680c15d397084430d4907c16cedfacddaAlan Viverette TransitionManager.endTransitions(this); 20808fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20818fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (mPendingExitListener != null) { 20828fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mPendingExitListener.onTransitionEnd(null); 20838fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20848fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20855435a30ae552391f14009c4459731ae149675b18Alan Viverette } 20865435a30ae552391f14009c4459731ae149675b18Alan Viverette 20875435a30ae552391f14009c4459731ae149675b18Alan Viverette private class PopupBackgroundView extends FrameLayout { 20885435a30ae552391f14009c4459731ae149675b18Alan Viverette public PopupBackgroundView(Context context) { 20895435a30ae552391f14009c4459731ae149675b18Alan Viverette super(context); 20905435a30ae552391f14009c4459731ae149675b18Alan Viverette } 209175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 209275986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov @Override 20935435a30ae552391f14009c4459731ae149675b18Alan Viverette protected int[] onCreateDrawableState(int extraSpace) { 20945435a30ae552391f14009c4459731ae149675b18Alan Viverette if (mAboveAnchor) { 20955435a30ae552391f14009c4459731ae149675b18Alan Viverette final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 20965435a30ae552391f14009c4459731ae149675b18Alan Viverette View.mergeDrawableStates(drawableState, ABOVE_ANCHOR_STATE_SET); 20975435a30ae552391f14009c4459731ae149675b18Alan Viverette return drawableState; 209875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } else { 20995435a30ae552391f14009c4459731ae149675b18Alan Viverette return super.onCreateDrawableState(extraSpace); 210075986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 210175986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 21029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2104