PopupWindow.java revision 259c2840691a79634ffd8f63291ec21c21819542
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 private final Rect mAnchorBounds = new Rect(); 985435a30ae552391f14009c4459731ae149675b18Alan Viverette 99448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy private Context mContext; 100448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy private WindowManager mWindowManager; 1015435a30ae552391f14009c4459731ae149675b18Alan Viverette 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mIsShowing; 1038fd949e680c15d397084430d4907c16cedfacddaAlan Viverette private boolean mIsTransitioningToDismiss; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mIsDropdown; 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1065435a30ae552391f14009c4459731ae149675b18Alan Viverette /** View that handles event dispatch and content transitions. */ 1075435a30ae552391f14009c4459731ae149675b18Alan Viverette private PopupDecorView mDecorView; 1085435a30ae552391f14009c4459731ae149675b18Alan Viverette 1095435a30ae552391f14009c4459731ae149675b18Alan Viverette /** The contents of the popup. */ 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View mContentView; 1115435a30ae552391f14009c4459731ae149675b18Alan Viverette 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mFocusable; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mInputMethodMode = INPUT_METHOD_FROM_FOCUSABLE; 1147eab094722af54717859b7dcce3cc050f059e00bDianne Hackborn private int mSoftInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mTouchable = true; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mOutsideTouchable = false; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mClippingEnabled = true; 11846e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown private int mSplitTouchEnabled = -1; 119ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell private boolean mLayoutInScreen; 12056c2d337e02a275397fc9d0460dca90977f199acAdam Powell private boolean mClipToScreen; 121348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell private boolean mAllowScrollingAnchorParent = true; 1220bd1d0a15294345bf88b20df28466907f982cec7Adam Powell private boolean mLayoutInsetDecor = false; 123e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell private boolean mNotTouchModal; 124393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale private boolean mAttachedInDecor = true; 125393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale private boolean mAttachedInDecorSet = false; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnTouchListener mTouchInterceptor; 128393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mWidthMode; 130259c2840691a79634ffd8f63291ec21c21819542Alan Viverette private int mWidth = LayoutParams.WRAP_CONTENT; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLastWidth; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mHeightMode; 133259c2840691a79634ffd8f63291ec21c21819542Alan Viverette private int mHeight = LayoutParams.WRAP_CONTENT; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLastHeight; 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mPopupWidth; 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mPopupHeight; 13856c2d337e02a275397fc9d0460dca90977f199acAdam Powell 139ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette private float mElevation; 140ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Drawable mBackground; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Drawable mAboveAnchorBackgroundDrawable; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Drawable mBelowAnchorBackgroundDrawable; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1455435a30ae552391f14009c4459731ae149675b18Alan Viverette private Transition mEnterTransition; 1465435a30ae552391f14009c4459731ae149675b18Alan Viverette private Transition mExitTransition; 147560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mAboveAnchor; 149574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell private int mWindowLayoutType = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; 1505435a30ae552391f14009c4459731ae149675b18Alan Viverette 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnDismissListener mOnDismissListener; 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mIgnoreCheekPress = false; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1545435a30ae552391f14009c4459731ae149675b18Alan Viverette private int mAnimationStyle = ANIMATION_STYLE_DEFAULT; 1555435a30ae552391f14009c4459731ae149675b18Alan Viverette 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int[] ABOVE_ANCHOR_STATE_SET = new int[] { 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.attr.state_above_anchor 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private WeakReference<View> mAnchor; 161560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 1625435a30ae552391f14009c4459731ae149675b18Alan Viverette private final EpicenterCallback mEpicenterCallback = new EpicenterCallback() { 1635435a30ae552391f14009c4459731ae149675b18Alan Viverette @Override 1645435a30ae552391f14009c4459731ae149675b18Alan Viverette public Rect onGetEpicenter(Transition transition) { 165df4639a0135ea643b493067b3f7cd1e092346c78Alan Viverette final View anchor = mAnchor != null ? mAnchor.get() : null; 1667878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette final View decor = mDecorView; 1677878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette if (anchor == null || decor == null) { 1687878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette return null; 1697878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette } 1707878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette 1717878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette final Rect anchorBounds = mAnchorBounds; 172df4639a0135ea643b493067b3f7cd1e092346c78Alan Viverette final int[] anchorLocation = anchor.getLocationOnScreen(); 1737878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette final int[] popupLocation = mDecorView.getLocationOnScreen(); 1747878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette 1757878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette // Compute the position of the anchor relative to the popup. 1767878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette anchorBounds.set(0, 0, anchor.getWidth(), anchor.getHeight()); 1777878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette anchorBounds.offset(anchorLocation[0] - popupLocation[0], 1787878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette anchorLocation[1] - popupLocation[1]); 1797878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette 1807878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette return anchorBounds; 1815435a30ae552391f14009c4459731ae149675b18Alan Viverette } 1825435a30ae552391f14009c4459731ae149675b18Alan Viverette }; 1835435a30ae552391f14009c4459731ae149675b18Alan Viverette 1845435a30ae552391f14009c4459731ae149675b18Alan Viverette private final OnScrollChangedListener mOnScrollChangedListener = new OnScrollChangedListener() { 1855435a30ae552391f14009c4459731ae149675b18Alan Viverette @Override 1865435a30ae552391f14009c4459731ae149675b18Alan Viverette public void onScrollChanged() { 1875435a30ae552391f14009c4459731ae149675b18Alan Viverette final View anchor = mAnchor != null ? mAnchor.get() : null; 1885435a30ae552391f14009c4459731ae149675b18Alan Viverette if (anchor != null && mDecorView != null) { 1895435a30ae552391f14009c4459731ae149675b18Alan Viverette final WindowManager.LayoutParams p = (WindowManager.LayoutParams) 1905435a30ae552391f14009c4459731ae149675b18Alan Viverette mDecorView.getLayoutParams(); 1915435a30ae552391f14009c4459731ae149675b18Alan Viverette 1925435a30ae552391f14009c4459731ae149675b18Alan Viverette updateAboveAnchor(findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff, 1935435a30ae552391f14009c4459731ae149675b18Alan Viverette mAnchoredGravity)); 1945435a30ae552391f14009c4459731ae149675b18Alan Viverette update(p.x, p.y, -1, -1, true); 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1965435a30ae552391f14009c4459731ae149675b18Alan Viverette } 1975435a30ae552391f14009c4459731ae149675b18Alan Viverette }; 198560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 1995435a30ae552391f14009c4459731ae149675b18Alan Viverette private int mAnchorXoff; 2005435a30ae552391f14009c4459731ae149675b18Alan Viverette private int mAnchorYoff; 2015435a30ae552391f14009c4459731ae149675b18Alan Viverette private int mAnchoredGravity; 202560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette private boolean mOverlapAnchor; 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 204b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio private boolean mPopupViewInitialLayoutDirectionInherited; 205b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window of dimension (0,0).</p> 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does provide a background.</p> 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(Context context) { 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, null); 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window of dimension (0,0).</p> 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does provide a background.</p> 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(Context context, AttributeSet attrs) { 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, attrs, com.android.internal.R.attr.popupWindowStyle); 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window of dimension (0,0).</p> 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does provide a background.</p> 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 229617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr) { 230617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette this(context, attrs, defStyleAttr, 0); 231c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 2325435a30ae552391f14009c4459731ae149675b18Alan Viverette 233c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 234c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>Create a new, empty, non focusable popup window of dimension (0,0).</p> 2355435a30ae552391f14009c4459731ae149675b18Alan Viverette * 236c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>The popup does not provide a background.</p> 237c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 238c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 24075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 242617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette final TypedArray a = context.obtainStyledAttributes( 243ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette attrs, R.styleable.PopupWindow, defStyleAttr, defStyleRes); 244ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette final Drawable bg = a.getDrawable(R.styleable.PopupWindow_popupBackground); 245ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette mElevation = a.getDimension(R.styleable.PopupWindow_popupElevation, 0); 246560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette mOverlapAnchor = a.getBoolean(R.styleable.PopupWindow_overlapAnchor, false); 247c3808b5dc7d5873d04e8a0a247b179b2757764baAdam Powell 2485435a30ae552391f14009c4459731ae149675b18Alan Viverette // Preserve default behavior from Gingerbread. If the animation is 2495435a30ae552391f14009c4459731ae149675b18Alan Viverette // undefined or explicitly specifies the Gingerbread animation style, 2505435a30ae552391f14009c4459731ae149675b18Alan Viverette // use a sentinel value. 2515435a30ae552391f14009c4459731ae149675b18Alan Viverette if (a.hasValueOrEmpty(R.styleable.PopupWindow_popupAnimationStyle)) { 2525435a30ae552391f14009c4459731ae149675b18Alan Viverette final int animStyle = a.getResourceId(R.styleable.PopupWindow_popupAnimationStyle, 0); 2535435a30ae552391f14009c4459731ae149675b18Alan Viverette if (animStyle == R.style.Animation_PopupWindow) { 2545435a30ae552391f14009c4459731ae149675b18Alan Viverette mAnimationStyle = ANIMATION_STYLE_DEFAULT; 2555435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 2565435a30ae552391f14009c4459731ae149675b18Alan Viverette mAnimationStyle = animStyle; 2575435a30ae552391f14009c4459731ae149675b18Alan Viverette } 2585435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 2595435a30ae552391f14009c4459731ae149675b18Alan Viverette mAnimationStyle = ANIMATION_STYLE_DEFAULT; 2605435a30ae552391f14009c4459731ae149675b18Alan Viverette } 2615435a30ae552391f14009c4459731ae149675b18Alan Viverette 2625435a30ae552391f14009c4459731ae149675b18Alan Viverette final Transition enterTransition = getTransition(a.getResourceId( 2635435a30ae552391f14009c4459731ae149675b18Alan Viverette R.styleable.PopupWindow_popupEnterTransition, 0)); 2645435a30ae552391f14009c4459731ae149675b18Alan Viverette final Transition exitTransition; 2655435a30ae552391f14009c4459731ae149675b18Alan Viverette if (a.hasValueOrEmpty(R.styleable.PopupWindow_popupExitTransition)) { 2665435a30ae552391f14009c4459731ae149675b18Alan Viverette exitTransition = getTransition(a.getResourceId( 2675435a30ae552391f14009c4459731ae149675b18Alan Viverette R.styleable.PopupWindow_popupExitTransition, 0)); 2685435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 2695435a30ae552391f14009c4459731ae149675b18Alan Viverette exitTransition = enterTransition == null ? null : enterTransition.clone(); 2705435a30ae552391f14009c4459731ae149675b18Alan Viverette } 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 273ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 2745435a30ae552391f14009c4459731ae149675b18Alan Viverette setEnterTransition(enterTransition); 2755435a30ae552391f14009c4459731ae149675b18Alan Viverette setExitTransition(exitTransition); 276ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette setBackgroundDrawable(bg); 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 of dimension (0,0).</p> 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow() { 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(null, 0, 0); 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new non focusable popup window which can display the 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tt>contentView</tt>. The dimension of the window are (0,0).</p> 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param contentView the popup's content 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(View contentView) { 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(contentView, 0, 0); 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new empty, non focusable popup window. The dimension of the 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window must be passed to this constructor.</p> 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param width the popup's width 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param height the popup's height 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(int width, int height) { 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(null, width, height); 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new non focusable popup window which can display the 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <tt>contentView</tt>. The dimension of the window must be passed to 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this constructor.</p> 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param contentView the popup's content 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param width the popup's width 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param height the popup's height 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PopupWindow(View contentView, int width, int height) { 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(contentView, width, height, false); 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new popup window which can display the <tt>contentView</tt>. 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The dimension of the window must be passed to this constructor.</p> 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The popup does not provide any background. This should be handled 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the content view.</p> 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param contentView the popup's content 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param width the popup's width 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param height the popup's height 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param focusable true if the popup can be focused, false otherwise 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 344448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy public PopupWindow(View contentView, int width, int height, boolean focusable) { 345448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy if (contentView != null) { 346448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy mContext = contentView.getContext(); 347448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); 348448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy } 349393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setContentView(contentView); 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setWidth(width); 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setHeight(height); 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setFocusable(focusable); 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3565435a30ae552391f14009c4459731ae149675b18Alan Viverette public void setEnterTransition(Transition enterTransition) { 3575435a30ae552391f14009c4459731ae149675b18Alan Viverette mEnterTransition = enterTransition; 3585435a30ae552391f14009c4459731ae149675b18Alan Viverette 3595435a30ae552391f14009c4459731ae149675b18Alan Viverette if (mEnterTransition != null) { 3605435a30ae552391f14009c4459731ae149675b18Alan Viverette mEnterTransition.setEpicenterCallback(mEpicenterCallback); 3615435a30ae552391f14009c4459731ae149675b18Alan Viverette } 3625435a30ae552391f14009c4459731ae149675b18Alan Viverette } 3635435a30ae552391f14009c4459731ae149675b18Alan Viverette 3645435a30ae552391f14009c4459731ae149675b18Alan Viverette public void setExitTransition(Transition exitTransition) { 3655435a30ae552391f14009c4459731ae149675b18Alan Viverette mExitTransition = exitTransition; 3665435a30ae552391f14009c4459731ae149675b18Alan Viverette 3675435a30ae552391f14009c4459731ae149675b18Alan Viverette if (mExitTransition != null) { 3685435a30ae552391f14009c4459731ae149675b18Alan Viverette mExitTransition.setEpicenterCallback(mEpicenterCallback); 3695435a30ae552391f14009c4459731ae149675b18Alan Viverette } 3705435a30ae552391f14009c4459731ae149675b18Alan Viverette } 3715435a30ae552391f14009c4459731ae149675b18Alan Viverette 3725435a30ae552391f14009c4459731ae149675b18Alan Viverette private Transition getTransition(int resId) { 3735435a30ae552391f14009c4459731ae149675b18Alan Viverette if (resId != 0 && resId != R.transition.no_transition) { 3745435a30ae552391f14009c4459731ae149675b18Alan Viverette final TransitionInflater inflater = TransitionInflater.from(mContext); 3755435a30ae552391f14009c4459731ae149675b18Alan Viverette final Transition transition = inflater.inflateTransition(resId); 3765435a30ae552391f14009c4459731ae149675b18Alan Viverette if (transition != null) { 3775435a30ae552391f14009c4459731ae149675b18Alan Viverette final boolean isEmpty = transition instanceof TransitionSet 3785435a30ae552391f14009c4459731ae149675b18Alan Viverette && ((TransitionSet) transition).getTransitionCount() == 0; 3795435a30ae552391f14009c4459731ae149675b18Alan Viverette if (!isEmpty) { 3805435a30ae552391f14009c4459731ae149675b18Alan Viverette return transition; 3815435a30ae552391f14009c4459731ae149675b18Alan Viverette } 3825435a30ae552391f14009c4459731ae149675b18Alan Viverette } 3835435a30ae552391f14009c4459731ae149675b18Alan Viverette } 3845435a30ae552391f14009c4459731ae149675b18Alan Viverette return null; 3855435a30ae552391f14009c4459731ae149675b18Alan Viverette } 3865435a30ae552391f14009c4459731ae149675b18Alan Viverette 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 388ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * Return the drawable used as the popup window's background. 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 390ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @return the background drawable or {@code null} if not set 391ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @see #setBackgroundDrawable(Drawable) 392ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @attr ref android.R.styleable#PopupWindow_popupBackground 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable getBackground() { 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBackground; 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 399ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * Specifies the background drawable for this popup window. The background 400ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * can be set to {@code null}. 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param background the popup's background 403ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @see #getBackground() 404ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @attr ref android.R.styleable#PopupWindow_popupBackground 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setBackgroundDrawable(Drawable background) { 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBackground = background; 408ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 409ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // If this is a StateListDrawable, try to find and store the drawable to be 410ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // used when the drop-down is placed above its anchor view, and the one to be 411ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // used when the drop-down is placed below its anchor view. We extract 412ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // the drawables ourselves to work around a problem with using refreshDrawableState 413ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // that it will take into account the padding of all drawables specified in a 414ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // StateListDrawable, thus adding superfluous padding to drop-down views. 415ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // 416ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // We assume a StateListDrawable will have a drawable for ABOVE_ANCHOR_STATE_SET and 417ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // at least one other drawable, intended for the 'below-anchor state'. 418ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette if (mBackground instanceof StateListDrawable) { 419ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette StateListDrawable stateList = (StateListDrawable) mBackground; 420ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 421ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // Find the above-anchor view - this one's easy, it should be labeled as such. 422ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette int aboveAnchorStateIndex = stateList.getStateDrawableIndex(ABOVE_ANCHOR_STATE_SET); 423ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 424ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // Now, for the below-anchor view, look for any other drawable specified in the 425ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // StateListDrawable which is not for the above-anchor state and use that. 426ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette int count = stateList.getStateCount(); 427ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette int belowAnchorStateIndex = -1; 428ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette for (int i = 0; i < count; i++) { 429ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette if (i != aboveAnchorStateIndex) { 430ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette belowAnchorStateIndex = i; 431ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette break; 432ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } 433ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } 434ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette 435ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // Store the drawables we found, if we found them. Otherwise, set them both 436ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette // to null so that we'll just use refreshDrawableState. 437ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette if (aboveAnchorStateIndex != -1 && belowAnchorStateIndex != -1) { 438ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette mAboveAnchorBackgroundDrawable = stateList.getStateDrawable(aboveAnchorStateIndex); 439ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette mBelowAnchorBackgroundDrawable = stateList.getStateDrawable(belowAnchorStateIndex); 440ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } else { 441ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette mBelowAnchorBackgroundDrawable = null; 442ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette mAboveAnchorBackgroundDrawable = null; 443ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } 444ce8c358712414e4fa98e4504e6a1b8ad36d37c6cAlan Viverette } 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 448ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @return the elevation for this popup window in pixels 449ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @see #setElevation(float) 450ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @attr ref android.R.styleable#PopupWindow_popupElevation 451ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette */ 452ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette public float getElevation() { 453ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette return mElevation; 454ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette } 455ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette 456ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette /** 457ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * Specifies the elevation for this popup window. 458ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * 459ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @param elevation the popup's elevation in pixels 460ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @see #getElevation() 461ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette * @attr ref android.R.styleable#PopupWindow_popupElevation 462ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette */ 463ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette public void setElevation(float elevation) { 464ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette mElevation = elevation; 465ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette } 466ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette 467ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette /** 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Return the animation style to use the popup appears and disappears</p> 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the animation style to use the popup appears and disappears 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getAnimationStyle() { 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAnimationStyle; 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 475393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 47754ec76d81ac38284caa6d00ad5f2d2207206b9ceShuhrat Dehkanov * Set the flag on popup to ignore cheek press events; by default this flag 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is set to false 47954ec76d81ac38284caa6d00ad5f2d2207206b9ceShuhrat Dehkanov * which means the popup will not ignore cheek press dispatch events. 4805435a30ae552391f14009c4459731ae149675b18Alan Viverette * 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 484393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setIgnoreCheekPress() { 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIgnoreCheekPress = true; 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4905435a30ae552391f14009c4459731ae149675b18Alan Viverette 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Change the animation style resource for this popup.</p> 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param animationStyle animation style to use when the popup appears 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and disappears. Set to -1 for the default animation, 0 for no 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * animation, or a resource identifier for an explicit animation. 5025435a30ae552391f14009c4459731ae149675b18Alan Viverette * 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAnimationStyle(int animationStyle) { 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimationStyle = animationStyle; 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5085435a30ae552391f14009c4459731ae149675b18Alan Viverette 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Return the view used as the content of the popup window.</p> 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return a {@link android.view.View} representing the popup's content 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setContentView(android.view.View) 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public View getContentView() { 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mContentView; 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Change the popup's content. The content is represented by an instance 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of {@link android.view.View}.</p> 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 52481f08086b44a117097960195d2c9072e29644962Gilles Debunne * <p>This method has no effect if called when the popup is showing.</p> 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param contentView the new content for the popup 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getContentView() 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isShowing() 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setContentView(View contentView) { 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isShowing()) { 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentView = contentView; 537448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy 5380c0b768e1514280812321854db6dfba723c3d169Romain Guy if (mContext == null && mContentView != null) { 539448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy mContext = mContentView.getContext(); 540448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy } 541448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy 5420c0b768e1514280812321854db6dfba723c3d169Romain Guy if (mWindowManager == null && mContentView != null) { 543448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); 544448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy } 545393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 546393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // Setting the default for attachedInDecor based on SDK version here 547393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // instead of in the constructor since we might not have the context 548393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // object in the constructor. We only want to set default here if the 549393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // app hasn't already set the attachedInDecor. 550393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale if (mContext != null && !mAttachedInDecorSet) { 551393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // Attach popup window in decor frame of parent window by default for 552393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // {@link Build.VERSION_CODES.LOLLIPOP_MR1} or greater. Keep current 553393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale // behavior of not attaching to decor frame for older SDKs. 554393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale setAttachedInDecor(mContext.getApplicationInfo().targetSdkVersion 555393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale >= Build.VERSION_CODES.LOLLIPOP_MR1); 556393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale } 557393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set a callback for all touch events being dispatched to the popup 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window. 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTouchInterceptor(OnTouchListener l) { 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTouchInterceptor = l; 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 567393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicate whether the popup window can grab the focus.</p> 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is focusable, false otherwise 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setFocusable(boolean) 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isFocusable() { 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFocusable; 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Changes the focusability of the popup window. When focusable, the 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window will grab the focus from the current focused widget if the popup 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * contains a focusable {@link android.view.View}. By default a popup 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window is not focusable.</p> 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param focusable true if the popup should grab focus, false otherwise. 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isFocusable() 5925435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setFocusable(boolean focusable) { 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFocusable = focusable; 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the current value in {@link #setInputMethodMode(int)}. 6015435a30ae552391f14009c4459731ae149675b18Alan Viverette * 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setInputMethodMode(int) 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getInputMethodMode() { 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mInputMethodMode; 6065435a30ae552391f14009c4459731ae149675b18Alan Viverette 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6085435a30ae552391f14009c4459731ae149675b18Alan Viverette 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Control how the popup operates with an input method: one of 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #INPUT_METHOD_FROM_FOCUSABLE}, {@link #INPUT_METHOD_NEEDED}, 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or {@link #INPUT_METHOD_NOT_NEEDED}. 6135435a30ae552391f14009c4459731ae149675b18Alan Viverette * 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 6175435a30ae552391f14009c4459731ae149675b18Alan Viverette * 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getInputMethodMode() 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setInputMethodMode(int mode) { 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mInputMethodMode = mode; 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 624374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy 625374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy /** 626374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * Sets the operating mode for the soft input area. 627374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * 628374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @param mode The desired mode, see 629374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * {@link android.view.WindowManager.LayoutParams#softInputMode} 630374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * for the full list 631374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * 632374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @see android.view.WindowManager.LayoutParams#softInputMode 633374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @see #getSoftInputMode() 634374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy */ 635374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy public void setSoftInputMode(int mode) { 636374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy mSoftInputMode = mode; 637374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy } 638374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy 639374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy /** 640374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * Returns the current value in {@link #setSoftInputMode(int)}. 641374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * 642374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @see #setSoftInputMode(int) 643374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy * @see android.view.WindowManager.LayoutParams#softInputMode 644374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy */ 645374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy public int getSoftInputMode() { 646374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy return mSoftInputMode; 647374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy } 6485435a30ae552391f14009c4459731ae149675b18Alan Viverette 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicates whether the popup window receives touch events.</p> 6515435a30ae552391f14009c4459731ae149675b18Alan Viverette * 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is touchable, false otherwise 6535435a30ae552391f14009c4459731ae149675b18Alan Viverette * 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setTouchable(boolean) 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isTouchable() { 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mTouchable; 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Changes the touchability of the popup window. When touchable, the 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window will receive touch events, otherwise touch events will go to the 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window below it. By default the window is touchable.</p> 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param touchable true if the popup should receive touch events, false otherwise 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isTouchable() 6725435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTouchable(boolean touchable) { 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTouchable = touchable; 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicates whether the popup window will be informed of touch events 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * outside of its window.</p> 6825435a30ae552391f14009c4459731ae149675b18Alan Viverette * 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is outside touchable, false otherwise 6845435a30ae552391f14009c4459731ae149675b18Alan Viverette * 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setOutsideTouchable(boolean) 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isOutsideTouchable() { 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mOutsideTouchable; 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Controls whether the pop-up will be informed of touch events outside 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of its window. This only makes sense for pop-ups that are touchable 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * but not focusable, which means touches outside of the window will 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be delivered to the window behind. The default is false.</p> 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 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 touchable true if the popup should receive outside 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * touch events, false otherwise 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isOutsideTouchable() 7055435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setOutsideTouchable(boolean touchable) { 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOutsideTouchable = touchable; 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicates whether clipping of the popup window is enabled.</p> 7145435a30ae552391f14009c4459731ae149675b18Alan Viverette * 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the clipping is enabled, false otherwise 7165435a30ae552391f14009c4459731ae149675b18Alan Viverette * 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setClippingEnabled(boolean) 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isClippingEnabled() { 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mClippingEnabled; 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Allows the popup window to extend beyond the bounds of the screen. By default the 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window is clipped to the screen boundaries. Setting this to false will allow windows to be 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * accurately positioned.</p> 7275435a30ae552391f14009c4459731ae149675b18Alan Viverette * 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown or through a manual call to one of 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #update()} methods.</p> 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param enabled false if the window should be allowed to extend outside of the screen 7335435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isClippingEnabled() 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #update() 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setClippingEnabled(boolean enabled) { 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mClippingEnabled = enabled; 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 74256c2d337e02a275397fc9d0460dca90977f199acAdam Powell * Clip this popup window to the screen, but not to the containing window. 74356c2d337e02a275397fc9d0460dca90977f199acAdam Powell * 74456c2d337e02a275397fc9d0460dca90977f199acAdam Powell * @param enabled True to clip to the screen. 74556c2d337e02a275397fc9d0460dca90977f199acAdam Powell * @hide 74656c2d337e02a275397fc9d0460dca90977f199acAdam Powell */ 74756c2d337e02a275397fc9d0460dca90977f199acAdam Powell public void setClipToScreenEnabled(boolean enabled) { 74856c2d337e02a275397fc9d0460dca90977f199acAdam Powell mClipToScreen = enabled; 74956c2d337e02a275397fc9d0460dca90977f199acAdam Powell setClippingEnabled(!enabled); 75056c2d337e02a275397fc9d0460dca90977f199acAdam Powell } 751348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell 752348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell /** 753348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * Allow PopupWindow to scroll the anchor's parent to provide more room 754348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * for the popup. Enabled by default. 755348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * 756348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * @param enabled True to scroll the anchor's parent when more room is desired by the popup. 757348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell */ 758348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell void setAllowScrollingAnchorParent(boolean enabled) { 759348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell mAllowScrollingAnchorParent = enabled; 760348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell } 7615435a30ae552391f14009c4459731ae149675b18Alan Viverette 76256c2d337e02a275397fc9d0460dca90977f199acAdam Powell /** 76301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * <p>Indicates whether the popup window supports splitting touches.</p> 7645435a30ae552391f14009c4459731ae149675b18Alan Viverette * 76501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * @return true if the touch splitting is enabled, false otherwise 7665435a30ae552391f14009c4459731ae149675b18Alan Viverette * 76701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * @see #setSplitTouchEnabled(boolean) 76801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown */ 76901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown public boolean isSplitTouchEnabled() { 77046e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown if (mSplitTouchEnabled < 0 && mContext != null) { 77146e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown return mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB; 77246e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown } 77346e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown return mSplitTouchEnabled == 1; 77401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown } 77501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown 77601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown /** 77701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * <p>Allows the popup window to split touches across other windows that also 77846e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown * support split touch. When this flag is false, the first pointer 77901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * that goes down determines the window to which all subsequent touches 78046e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown * go until all pointers go up. When this flag is true, each pointer 78101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * (not necessarily the first) that goes down determines the window 78201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * to which all subsequent touches of that pointer will go until that 78301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * pointer goes up thereby enabling touches with multiple pointers 78401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * to be split across multiple windows.</p> 78501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * 78601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * @param enabled true if the split touches should be enabled, false otherwise 78701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown * @see #isSplitTouchEnabled() 78801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown */ 78901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown public void setSplitTouchEnabled(boolean enabled) { 79046e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown mSplitTouchEnabled = enabled ? 1 : 0; 79101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown } 79201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown 79301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown /** 794ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * <p>Indicates whether the popup window will be forced into using absolute screen coordinates 795ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * for positioning.</p> 796ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * 797ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * @return true if the window will always be positioned in screen coordinates. 798ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * @hide 799ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell */ 800ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell public boolean isLayoutInScreenEnabled() { 801ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell return mLayoutInScreen; 802ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell } 803ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell 804ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell /** 805ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * <p>Allows the popup window to force the flag 806ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * {@link WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN}, overriding default behavior. 807ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * This will cause the popup to be positioned in absolute screen coordinates.</p> 808ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * 809ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * @param enabled true if the popup should always be positioned in screen coordinates 810ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell * @hide 811ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell */ 812ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell public void setLayoutInScreenEnabled(boolean enabled) { 813ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell mLayoutInScreen = enabled; 814ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell } 815ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell 816ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell /** 817393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * <p>Indicates whether the popup window will be attached in the decor frame of its parent 818393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * window. 819393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 820393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @return true if the window will be attached to the decor frame of its parent window. 821393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 822393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @see #setAttachedInDecor(boolean) 823393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR 824393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale */ 825393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale public boolean isAttachedInDecor() { 826393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale return mAttachedInDecor; 827393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale } 828393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 829393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale /** 830393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * <p>This will attach the popup window to the decor frame of the parent window to avoid 831393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * overlaping with screen decorations like the navigation bar. Overrides the default behavior of 832393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * the flag {@link WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR}. 833393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 834393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * <p>By default the flag is set on SDK version {@link Build.VERSION_CODES#LOLLIPOP_MR1} or 835393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * greater and cleared on lesser SDK versions. 836393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 837393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @param enabled true if the popup should be attached to the decor frame of its parent window. 838393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * 839393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale * @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR 840393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale */ 841393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale public void setAttachedInDecor(boolean enabled) { 842393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale mAttachedInDecor = enabled; 843393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale mAttachedInDecorSet = true; 844393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale } 845393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 846393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale /** 8470bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * Allows the popup window to force the flag 8480bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * {@link WindowManager.LayoutParams#FLAG_LAYOUT_INSET_DECOR}, overriding default behavior. 8490bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * This will cause the popup to inset its content to account for system windows overlaying 8500bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * the screen, such as the status bar. 8510bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * 8520bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * <p>This will often be combined with {@link #setLayoutInScreenEnabled(boolean)}. 8530bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * 8540bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * @param enabled true if the popup's views should inset content to account for system windows, 8550bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * the way that decor views behave for full-screen windows. 8560bd1d0a15294345bf88b20df28466907f982cec7Adam Powell * @hide 8570bd1d0a15294345bf88b20df28466907f982cec7Adam Powell */ 8580bd1d0a15294345bf88b20df28466907f982cec7Adam Powell public void setLayoutInsetDecor(boolean enabled) { 8590bd1d0a15294345bf88b20df28466907f982cec7Adam Powell mLayoutInsetDecor = enabled; 8600bd1d0a15294345bf88b20df28466907f982cec7Adam Powell } 8610bd1d0a15294345bf88b20df28466907f982cec7Adam Powell 8620bd1d0a15294345bf88b20df28466907f982cec7Adam Powell /** 863574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell * Set the layout type for this window. Should be one of the TYPE constants defined in 864574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell * {@link WindowManager.LayoutParams}. 865574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell * 866574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell * @param layoutType Layout type for this window. 867574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell * @hide 868574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell */ 869574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell public void setWindowLayoutType(int layoutType) { 870574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell mWindowLayoutType = layoutType; 871574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell } 872574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell 873574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell /** 874574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell * @return The layout type for this window. 875574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell * @hide 876574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell */ 877574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell public int getWindowLayoutType() { 878574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell return mWindowLayoutType; 879574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell } 880574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell 881574b37ecc20a5358cb6147dae6d633385467ab55Adam Powell /** 882e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell * Set whether this window is touch modal or if outside touches will be sent to 883e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell * other windows behind it. 884e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell * @hide 885e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell */ 886e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell public void setTouchModal(boolean touchModal) { 887e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell mNotTouchModal = !touchModal; 888e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell } 889e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell 890e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell /** 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Change the width and height measure specs that are given to the 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window manager by the popup. By default these are 0, meaning that 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the current width or height is requested as an explicit size from 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the window manager. You can supply 8955435a30ae552391f14009c4459731ae149675b18Alan Viverette * {@link ViewGroup.LayoutParams#WRAP_CONTENT} or 896980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * {@link ViewGroup.LayoutParams#MATCH_PARENT} to have that measure 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * spec supplied instead, replacing the absolute width and height that 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * has been set in the popup.</p> 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the popup is showing, calling this method will take effect only 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the next time the popup is shown.</p> 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param widthSpec an explicit width measure spec mode, either 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link ViewGroup.LayoutParams#WRAP_CONTENT}, 905980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * {@link ViewGroup.LayoutParams#MATCH_PARENT}, or 0 to use the absolute 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * width. 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param heightSpec an explicit height measure spec mode, either 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link ViewGroup.LayoutParams#WRAP_CONTENT}, 909980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * {@link ViewGroup.LayoutParams#MATCH_PARENT}, or 0 to use the absolute 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * height. 911259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * 912259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @deprecated Use {@link #setWidth(int)} and {@link #setHeight(int)}. 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 914259c2840691a79634ffd8f63291ec21c21819542Alan Viverette @Deprecated 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setWindowLayoutMode(int widthSpec, int heightSpec) { 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWidthMode = widthSpec; 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeightMode = heightSpec; 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9195435a30ae552391f14009c4459731ae149675b18Alan Viverette 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 921259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Returns the popup's height MeasureSpec. 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the height MeasureSpec of the popup 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setHeight(int) 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getHeight() { 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mHeight; 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 931259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Sets the popup's height MeasureSpec. 932259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 933259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * If the popup is showing, calling this method will take effect the next 934259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * time the popup is shown. 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param height the height MeasureSpec of the popup 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getHeight() 9385435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #isShowing() 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setHeight(int height) { 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeight = height; 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 945259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Returns the popup's width MeasureSpec. 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the width MeasureSpec of the popup 9485435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #setWidth(int) 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getWidth() { 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mWidth; 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 955259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Sets the popup's width MeasureSpec. 956259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 957259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * If the popup is showing, calling this method will take effect the next 958259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * time the popup is shown. 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param width the width MeasureSpec of the popup 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getWidth() 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isShowing() 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setWidth(int width) { 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWidth = width; 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 96975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Sets whether the popup window should overlap its anchor view when 97075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * displayed as a drop-down. 97175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * <p> 97275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If the popup is showing, calling this method will take effect only 97375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * the next time the popup is shown. 97475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * 97575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @param overlapAnchor Whether the popup should overlap its anchor. 97675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * 97775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @see #getOverlapAnchor() 97875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @see #isShowing() 97975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette */ 98075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette public void setOverlapAnchor(boolean overlapAnchor) { 98175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette mOverlapAnchor = overlapAnchor; 98275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette } 98375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette 98475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette /** 98575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Returns whether the popup window should overlap its anchor view when 98675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * displayed as a drop-down. 98775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * 98875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @return Whether the popup should overlap its anchor. 98975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * 99075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * @see #setOverlapAnchor(boolean) 99175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette */ 99275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette public boolean getOverlapAnchor() { 99375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette return mOverlapAnchor; 99475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette } 99575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette 99675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette /** 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicate whether this popup window is showing on screen.</p> 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is showing, false otherwise 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isShowing() { 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mIsShowing; 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Display the content view in a popup window at the specified location. If the popup window 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cannot fit on screen, it will be clipped. See {@link android.view.WindowManager.LayoutParams} 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for more information on how gravity and the x and y parameters are related. Specifying 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a gravity of {@link android.view.Gravity#NO_GRAVITY} is similar to specifying 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>Gravity.LEFT | Gravity.TOP</code>. 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p> 10135435a30ae552391f14009c4459731ae149675b18Alan Viverette * 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param parent a parent view to get the {@link android.view.View#getWindowToken()} token from 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param gravity the gravity which controls the placement of the popup window 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x the popup's x location offset 10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y the popup's y location offset 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void showAtLocation(View parent, int gravity, int x, int y) { 10208ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell showAtLocation(parent.getWindowToken(), gravity, x, y); 10218ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell } 10228ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell 10238ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell /** 10248ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * Display the content view in a popup window at the specified location. 10258ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * 10268ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @param token Window token to use for creating the new window 10278ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @param gravity the gravity which controls the placement of the popup window 10288ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @param x the popup's x location offset 10298ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @param y the popup's y location offset 10308ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * 10318ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * @hide Internal use only. Applications should use 10328ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell * {@link #showAtLocation(View, int, int, int)} instead. 10338ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell */ 10348ee6d7c20e7767c2f61f8db9a99d01e0a05f3842Adam Powell public void showAtLocation(IBinder token, int gravity, int x, int y) { 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isShowing() || mContentView == null) { 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1039e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette TransitionManager.endTransitions(mDecorView); 1040e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterForScrollChanged(); 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsShowing = true; 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsDropdown = false; 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1046e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final WindowManager.LayoutParams p = createPopupLayoutParams(token); 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project preparePopup(p); 1048e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1049e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // Only override the default if some gravity was specified. 1050e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette if (gravity != Gravity.NO_GRAVITY) { 1051e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.gravity = gravity; 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1053e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.x = x; 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.y = y; 1056e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokePopup(p); 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 106175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Display the content view in a popup window anchored to the bottom-left 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * corner of the anchor view. If there is not enough room on screen to show 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the popup in its entirety, this method tries to find a parent scroll 106475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * view to scroll. If no parent scroll view can be scrolled, the 106575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * bottom-left corner of the popup is pinned at the top left corner of the 106675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * anchor view. 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the view on which to pin the popup window 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #dismiss() 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void showAsDropDown(View anchor) { 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project showAsDropDown(anchor, 0, 0); 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 107775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Display the content view in a popup window anchored to the bottom-left 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * corner of the anchor view offset by the specified x and y coordinates. 107975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If there is not enough room on screen to show the popup in its entirety, 108075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * this method tries to find a parent scroll view to scroll. If no parent 108175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * scroll view can be scrolled, the bottom-left corner of the popup is 108275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * pinned at the top left corner of the anchor view. 108375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * <p> 108475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If the view later scrolls to move <code>anchor</code> to a different 108575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * location, the popup will be moved correspondingly. 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the view on which to pin the popup window 108854c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param xoff A horizontal offset from the anchor in pixels 108954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param yoff A vertical offset from the anchor in pixels 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #dismiss() 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void showAsDropDown(View anchor, int xoff, int yoff) { 109454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell showAsDropDown(anchor, xoff, yoff, DEFAULT_ANCHORED_GRAVITY); 109554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell } 109654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 109754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell /** 109875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * Displays the content view in a popup window anchored to the corner of 109975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * another view. The window is positioned according to the specified 110075d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * gravity and offset by the specified x and y coordinates. 110175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * <p> 110275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If there is not enough room on screen to show the popup in its entirety, 110375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * this method tries to find a parent scroll view to scroll. If no parent 110475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * view can be scrolled, the specified vertical gravity will be ignored and 110575d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * the popup will anchor itself such that it is visible. 110675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * <p> 110775d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * If the view later scrolls to move <code>anchor</code> to a different 110875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette * location, the popup will be moved correspondingly. 110954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * 111054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param anchor the view on which to pin the popup window 111154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param xoff A horizontal offset from the anchor in pixels 111254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param yoff A vertical offset from the anchor in pixels 111354c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param gravity Alignment of the popup relative to the anchor 111454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * 111554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @see #dismiss() 111654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell */ 111754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell public void showAsDropDown(View anchor, int xoff, int yoff, int gravity) { 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isShowing() || mContentView == null) { 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1122e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette TransitionManager.endTransitions(mDecorView); 1123e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 112454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell registerForScrollChanged(anchor, xoff, yoff, gravity); 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsShowing = true; 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsDropdown = true; 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1129e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final WindowManager.LayoutParams p = createPopupLayoutParams(anchor.getWindowToken()); 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project preparePopup(p); 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1132e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final boolean aboveAnchor = findDropDownPosition(anchor, p, xoff, yoff, gravity); 1133e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette updateAboveAnchor(aboveAnchor); 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokePopup(p); 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11383e141685003939a9addce21ba2492ea3a8aebee6Romain Guy private void updateAboveAnchor(boolean aboveAnchor) { 11393e141685003939a9addce21ba2492ea3a8aebee6Romain Guy if (aboveAnchor != mAboveAnchor) { 11403e141685003939a9addce21ba2492ea3a8aebee6Romain Guy mAboveAnchor = aboveAnchor; 11413e141685003939a9addce21ba2492ea3a8aebee6Romain Guy 11423e141685003939a9addce21ba2492ea3a8aebee6Romain Guy if (mBackground != null) { 11433e141685003939a9addce21ba2492ea3a8aebee6Romain Guy // If the background drawable provided was a StateListDrawable with above-anchor 11443e141685003939a9addce21ba2492ea3a8aebee6Romain Guy // and below-anchor states, use those. Otherwise rely on refreshDrawableState to 11453e141685003939a9addce21ba2492ea3a8aebee6Romain Guy // do the job. 11463e141685003939a9addce21ba2492ea3a8aebee6Romain Guy if (mAboveAnchorBackgroundDrawable != null) { 11473e141685003939a9addce21ba2492ea3a8aebee6Romain Guy if (mAboveAnchor) { 11485435a30ae552391f14009c4459731ae149675b18Alan Viverette mDecorView.setBackground(mAboveAnchorBackgroundDrawable); 11493e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } else { 11505435a30ae552391f14009c4459731ae149675b18Alan Viverette mDecorView.setBackground(mBelowAnchorBackgroundDrawable); 11513e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 11523e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } else { 11535435a30ae552391f14009c4459731ae149675b18Alan Viverette mDecorView.refreshDrawableState(); 11543e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 11553e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 11563e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 11573e141685003939a9addce21ba2492ea3a8aebee6Romain Guy } 11583e141685003939a9addce21ba2492ea3a8aebee6Romain Guy 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Indicates whether the popup is showing above (the y coordinate of the popup's bottom 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is less than the y coordinate of the anchor) or below the anchor view (the y coordinate 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the popup is greater than y coordinate of the anchor's bottom). 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The value returned 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by this method is meaningful only after {@link #showAsDropDown(android.view.View)} 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or {@link #showAsDropDown(android.view.View, int, int)} was invoked. 11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return True if this popup is showing above the anchor view, false otherwise. 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isAboveAnchor() { 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAboveAnchor; 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1175e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette * Prepare the popup by embedding it into a new ViewGroup if the background 1176e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette * drawable is not null. If embedding is required, the layout parameters' 1177e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette * height is modified to take into account the background's padding. 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param p the layout parameters of the popup's content view 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void preparePopup(WindowManager.LayoutParams p) { 1182448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy if (mContentView == null || mContext == null || mWindowManager == null) { 1183448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy throw new IllegalStateException("You must specify a valid content view by " 1184448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy + "calling setContentView() before attempting to show the popup."); 1185448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy } 1186448ecf5a94bb8778c677f00dedd33b26ea7683e8Romain Guy 11878fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // The old decor view may be transitioning out. Make sure it finishes 11888fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // and cleans up before we try to create another one. 11898fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (mDecorView != null) { 11908fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mDecorView.cancelTransitions(); 11918fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 11928fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 11935435a30ae552391f14009c4459731ae149675b18Alan Viverette // When a background is available, we embed the content view within 11945435a30ae552391f14009c4459731ae149675b18Alan Viverette // another view that owns the background drawable. 11958fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View backgroundView; 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBackground != null) { 11978fd949e680c15d397084430d4907c16cedfacddaAlan Viverette backgroundView = createBackgroundView(mContentView); 11988fd949e680c15d397084430d4907c16cedfacddaAlan Viverette backgroundView.setBackground(mBackground); 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 12008fd949e680c15d397084430d4907c16cedfacddaAlan Viverette backgroundView = mContentView; 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1202ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette 12038fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mDecorView = createDecorView(backgroundView); 12045435a30ae552391f14009c4459731ae149675b18Alan Viverette 12055435a30ae552391f14009c4459731ae149675b18Alan Viverette // The background owner should be elevated so that it casts a shadow. 12068fd949e680c15d397084430d4907c16cedfacddaAlan Viverette backgroundView.setElevation(mElevation); 12075435a30ae552391f14009c4459731ae149675b18Alan Viverette 12085435a30ae552391f14009c4459731ae149675b18Alan Viverette // We may wrap that in another view, so we'll need to manually specify 12095435a30ae552391f14009c4459731ae149675b18Alan Viverette // the surface insets. 12108fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final int surfaceInset = (int) Math.ceil(backgroundView.getZ() * 2); 12115435a30ae552391f14009c4459731ae149675b18Alan Viverette p.surfaceInsets.set(surfaceInset, surfaceInset, surfaceInset, surfaceInset); 12125435a30ae552391f14009c4459731ae149675b18Alan Viverette p.hasManualSurfaceInsets = true; 12135435a30ae552391f14009c4459731ae149675b18Alan Viverette 1214b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio mPopupViewInitialLayoutDirectionInherited = 12155435a30ae552391f14009c4459731ae149675b18Alan Viverette (mContentView.getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT); 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPopupWidth = p.width; 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPopupHeight = p.height; 12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12215435a30ae552391f14009c4459731ae149675b18Alan Viverette * Wraps a content view in a PopupViewContainer. 12225435a30ae552391f14009c4459731ae149675b18Alan Viverette * 12235435a30ae552391f14009c4459731ae149675b18Alan Viverette * @param contentView the content view to wrap 12245435a30ae552391f14009c4459731ae149675b18Alan Viverette * @return a PopupViewContainer that wraps the content view 12255435a30ae552391f14009c4459731ae149675b18Alan Viverette */ 12265435a30ae552391f14009c4459731ae149675b18Alan Viverette private PopupBackgroundView createBackgroundView(View contentView) { 12275435a30ae552391f14009c4459731ae149675b18Alan Viverette final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams(); 12285435a30ae552391f14009c4459731ae149675b18Alan Viverette final int height; 12295435a30ae552391f14009c4459731ae149675b18Alan Viverette if (layoutParams != null && layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) { 12305435a30ae552391f14009c4459731ae149675b18Alan Viverette height = ViewGroup.LayoutParams.WRAP_CONTENT; 12315435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 12325435a30ae552391f14009c4459731ae149675b18Alan Viverette height = ViewGroup.LayoutParams.MATCH_PARENT; 12335435a30ae552391f14009c4459731ae149675b18Alan Viverette } 12345435a30ae552391f14009c4459731ae149675b18Alan Viverette 12355435a30ae552391f14009c4459731ae149675b18Alan Viverette final PopupBackgroundView backgroundView = new PopupBackgroundView(mContext); 12365435a30ae552391f14009c4459731ae149675b18Alan Viverette final PopupBackgroundView.LayoutParams listParams = new PopupBackgroundView.LayoutParams( 12375435a30ae552391f14009c4459731ae149675b18Alan Viverette ViewGroup.LayoutParams.MATCH_PARENT, height); 12385435a30ae552391f14009c4459731ae149675b18Alan Viverette backgroundView.addView(contentView, listParams); 12395435a30ae552391f14009c4459731ae149675b18Alan Viverette 12405435a30ae552391f14009c4459731ae149675b18Alan Viverette return backgroundView; 12415435a30ae552391f14009c4459731ae149675b18Alan Viverette } 12425435a30ae552391f14009c4459731ae149675b18Alan Viverette 12435435a30ae552391f14009c4459731ae149675b18Alan Viverette /** 12445435a30ae552391f14009c4459731ae149675b18Alan Viverette * Wraps a content view in a FrameLayout. 12455435a30ae552391f14009c4459731ae149675b18Alan Viverette * 12465435a30ae552391f14009c4459731ae149675b18Alan Viverette * @param contentView the content view to wrap 12475435a30ae552391f14009c4459731ae149675b18Alan Viverette * @return a FrameLayout that wraps the content view 12485435a30ae552391f14009c4459731ae149675b18Alan Viverette */ 12495435a30ae552391f14009c4459731ae149675b18Alan Viverette private PopupDecorView createDecorView(View contentView) { 12505435a30ae552391f14009c4459731ae149675b18Alan Viverette final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams(); 12515435a30ae552391f14009c4459731ae149675b18Alan Viverette final int height; 12525435a30ae552391f14009c4459731ae149675b18Alan Viverette if (layoutParams != null && layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) { 12535435a30ae552391f14009c4459731ae149675b18Alan Viverette height = ViewGroup.LayoutParams.WRAP_CONTENT; 12545435a30ae552391f14009c4459731ae149675b18Alan Viverette } else { 12555435a30ae552391f14009c4459731ae149675b18Alan Viverette height = ViewGroup.LayoutParams.MATCH_PARENT; 12565435a30ae552391f14009c4459731ae149675b18Alan Viverette } 12575435a30ae552391f14009c4459731ae149675b18Alan Viverette 12585435a30ae552391f14009c4459731ae149675b18Alan Viverette final PopupDecorView decorView = new PopupDecorView(mContext); 12595435a30ae552391f14009c4459731ae149675b18Alan Viverette decorView.addView(contentView, ViewGroup.LayoutParams.MATCH_PARENT, height); 12605435a30ae552391f14009c4459731ae149675b18Alan Viverette decorView.setClipChildren(false); 12615435a30ae552391f14009c4459731ae149675b18Alan Viverette decorView.setClipToPadding(false); 12625435a30ae552391f14009c4459731ae149675b18Alan Viverette 12635435a30ae552391f14009c4459731ae149675b18Alan Viverette return decorView; 12645435a30ae552391f14009c4459731ae149675b18Alan Viverette } 12655435a30ae552391f14009c4459731ae149675b18Alan Viverette 12665435a30ae552391f14009c4459731ae149675b18Alan Viverette /** 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Invoke the popup window by adding the content view to the window 12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * manager.</p> 12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The content view must be non-null when this method is invoked.</p> 12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param p the layout parameters of the popup's content view 12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void invokePopup(WindowManager.LayoutParams p) { 12750c0b768e1514280812321854db6dfba723c3d169Romain Guy if (mContext != null) { 12760c0b768e1514280812321854db6dfba723c3d169Romain Guy p.packageName = mContext.getPackageName(); 12770c0b768e1514280812321854db6dfba723c3d169Romain Guy } 12785435a30ae552391f14009c4459731ae149675b18Alan Viverette 12798fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final PopupDecorView decorView = mDecorView; 12808fd949e680c15d397084430d4907c16cedfacddaAlan Viverette decorView.setFitsSystemWindows(mLayoutInsetDecor); 12818fd949e680c15d397084430d4907c16cedfacddaAlan Viverette decorView.requestEnterTransition(mEnterTransition); 12825435a30ae552391f14009c4459731ae149675b18Alan Viverette 12838fd949e680c15d397084430d4907c16cedfacddaAlan Viverette setLayoutDirectionFromAnchor(); 12845435a30ae552391f14009c4459731ae149675b18Alan Viverette 12858fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mWindowManager.addView(decorView, p); 12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1288b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio private void setLayoutDirectionFromAnchor() { 1289b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio if (mAnchor != null) { 1290b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio View anchor = mAnchor.get(); 1291b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio if (anchor != null && mPopupViewInitialLayoutDirectionInherited) { 12925435a30ae552391f14009c4459731ae149675b18Alan Viverette mDecorView.setLayoutDirection(anchor.getLayoutDirection()); 1293b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio } 1294b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio } 1295b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio } 1296b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio 12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Generate the layout parameters for the popup window.</p> 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param token the window token used to bind the popup's window 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the layout parameters to pass to the window manager 13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1304e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette private WindowManager.LayoutParams createPopupLayoutParams(IBinder token) { 1305e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final WindowManager.LayoutParams p = new WindowManager.LayoutParams(); 1306e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1307e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // These gravity settings put the view at the top left corner of the 1308e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // screen. The view is then positioned to the appropriate location by 1309e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // setting the x and y offsets to match the anchor's bottom-left 1310e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // corner. 1311aac0d4ed026d1cfbcf3fa81c6e4eb96f4347ca17Fabrice Di Meglio p.gravity = Gravity.START | Gravity.TOP; 1312e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.flags = computeFlags(p.flags); 1313e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.type = mWindowLayoutType; 1314e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.token = token; 1315e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.softInputMode = mSoftInputMode; 1316e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.windowAnimations = computeAnimationResource(); 1317e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBackground != null) { 13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.format = mBackground.getOpacity(); 13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.format = PixelFormat.TRANSLUCENT; 13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1323e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1324e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette if (mHeightMode < 0) { 1325e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.height = mLastHeight = mHeightMode; 1326e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } else { 1327e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.height = mLastHeight = mHeight; 1328e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } 1329e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1330e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette if (mWidthMode < 0) { 1331e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.width = mLastWidth = mWidthMode; 1332e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } else { 1333e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette p.width = mLastWidth = mWidth; 1334e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } 1335e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1336e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette // Used for debugging. 13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.setTitle("PopupWindow:" + Integer.toHexString(hashCode())); 13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return p; 13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int computeFlags(int curFlags) { 13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags &= ~( 13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES | 13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | 13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | 13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | 13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | 1349ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM | 1350ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell WindowManager.LayoutParams.FLAG_SPLIT_TOUCH); 13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(mIgnoreCheekPress) { 13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES; 13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mFocusable) { 13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mInputMethodMode == INPUT_METHOD_NEEDED) { 13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mInputMethodMode == INPUT_METHOD_NOT_NEEDED) { 13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mTouchable) { 13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1365c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project if (mOutsideTouchable) { 13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH; 13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mClippingEnabled) { 13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; 13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 137146e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown if (isSplitTouchEnabled()) { 137201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown curFlags |= WindowManager.LayoutParams.FLAG_SPLIT_TOUCH; 137301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown } 1374ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell if (mLayoutInScreen) { 1375ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; 1376ba0a2c383ffe4be1fe33a5aa57bc3148c4fd0b7cAdam Powell } 13770bd1d0a15294345bf88b20df28466907f982cec7Adam Powell if (mLayoutInsetDecor) { 13780bd1d0a15294345bf88b20df28466907f982cec7Adam Powell curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; 13790bd1d0a15294345bf88b20df28466907f982cec7Adam Powell } 1380e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell if (mNotTouchModal) { 1381e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; 1382e0b6cd14ac116006e26dac6898a332fa90f1f49cAdam Powell } 1383393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale if (mAttachedInDecor) { 1384393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR; 1385393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale } 13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return curFlags; 13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1388393b1c1e88cbdd0f65c8f217c495dbbe8de9125dWale Ogunwale 13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int computeAnimationResource() { 13905435a30ae552391f14009c4459731ae149675b18Alan Viverette if (mAnimationStyle == ANIMATION_STYLE_DEFAULT) { 13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsDropdown) { 13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAboveAnchor 13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ? com.android.internal.R.style.Animation_DropDownUp 13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : com.android.internal.R.style.Animation_DropDownDown; 13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAnimationStyle; 13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1400560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1402560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * Positions the popup window on screen. When the popup window is too tall 1403560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * to fit under the anchor, a parent scroll view is seeked and scrolled up 1404560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * to reclaim space. If scrolling is not possible or not enough, the popup 1405560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * window gets moved on top of the anchor. 1406560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * <p> 1407560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * The height must have been set on the layout parameters prior to calling 1408560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * this method. 14095435a30ae552391f14009c4459731ae149675b18Alan Viverette * 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the view on which the popup window must be anchored 14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param p the layout parameters used to display the drop down 1412560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * @param xoff horizontal offset used to adjust for background padding 1413560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * @param yoff vertical offset used to adjust for background padding 1414560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette * @param gravity horizontal gravity specifying popup alignment 14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup is translated upwards to fit on screen 14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1417560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette private boolean findDropDownPosition(View anchor, WindowManager.LayoutParams p, int xoff, 1418560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette int yoff, int gravity) { 141962e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell final int anchorHeight = anchor.getHeight(); 1420560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int anchorWidth = anchor.getWidth(); 1421560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette if (mOverlapAnchor) { 1422560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette yoff -= anchorHeight; 1423560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette } 1424560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anchor.getLocationInWindow(mDrawingLocation); 14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.x = mDrawingLocation[0] + xoff; 142762e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell p.y = mDrawingLocation[1] + anchorHeight + yoff; 142854c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 1429560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int hgrav = Gravity.getAbsoluteGravity(gravity, anchor.getLayoutDirection()) 1430560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette & Gravity.HORIZONTAL_GRAVITY_MASK; 143154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell if (hgrav == Gravity.RIGHT) { 1432560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // Flip the location to align the right sides of the popup and 1433560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // anchor instead of left. 1434560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette p.x -= mPopupWidth - anchorWidth; 143554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell } 1436560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean onTop = false; 14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 143954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell p.gravity = Gravity.LEFT | Gravity.TOP; 144054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anchor.getLocationOnScreen(mScreenLocation); 14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect displayFrame = new Rect(); 14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anchor.getWindowVisibleDisplayFrame(displayFrame); 144462e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell 1445560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int screenY = mScreenLocation[1] + anchorHeight + yoff; 14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View root = anchor.getRootView(); 1447560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette if (screenY + mPopupHeight > displayFrame.bottom 1448560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette || p.x + mPopupWidth - root.getWidth() > 0) { 1449560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // If the drop down disappears at the bottom of the screen, we try 1450560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // to scroll a parent scrollview or move the drop down back up on 1451560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // top of the edit box. 1452b7c1b20c8a5a4d4378ae91b4a1f12a34100df452Adam Powell if (mAllowScrollingAnchorParent) { 1453560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int scrollX = anchor.getScrollX(); 1454560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int scrollY = anchor.getScrollY(); 1455560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final Rect r = new Rect(scrollX, scrollY, scrollX + mPopupWidth + xoff, 1456560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette scrollY + mPopupHeight + anchorHeight + yoff); 1457b7c1b20c8a5a4d4378ae91b4a1f12a34100df452Adam Powell anchor.requestRectangleOnScreen(r, true); 1458b7c1b20c8a5a4d4378ae91b4a1f12a34100df452Adam Powell } 14593e141685003939a9addce21ba2492ea3a8aebee6Romain Guy 1460560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // Now we re-evaluate the space available, and decide from that 14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // whether the pop-up will go above or below the anchor. 14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anchor.getLocationInWindow(mDrawingLocation); 14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.x = mDrawingLocation[0] + xoff; 1464560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette p.y = mDrawingLocation[1] + anchorHeight + yoff; 146554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 1466560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // Preserve the gravity adjustment. 146754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell if (hgrav == Gravity.RIGHT) { 1468560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette p.x -= mPopupWidth - anchorWidth; 146954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell } 1470560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 1471560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette // Determine whether there is more space above or below the anchor. 14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anchor.getLocationOnScreen(mScreenLocation); 1473560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette onTop = (displayFrame.bottom - mScreenLocation[1] - anchorHeight - yoff) < 14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (mScreenLocation[1] - yoff - displayFrame.top); 14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (onTop) { 147654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell p.gravity = Gravity.LEFT | Gravity.BOTTOM; 14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.y = root.getHeight() - mDrawingLocation[1] + yoff; 14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1479560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette p.y = mDrawingLocation[1] + anchorHeight + yoff; 14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 148356c2d337e02a275397fc9d0460dca90977f199acAdam Powell if (mClipToScreen) { 148456c2d337e02a275397fc9d0460dca90977f199acAdam Powell final int displayFrameWidth = displayFrame.right - displayFrame.left; 1485560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int right = p.x + p.width; 148656c2d337e02a275397fc9d0460dca90977f199acAdam Powell if (right > displayFrameWidth) { 148756c2d337e02a275397fc9d0460dca90977f199acAdam Powell p.x -= right - displayFrameWidth; 148856c2d337e02a275397fc9d0460dca90977f199acAdam Powell } 1489560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 149056c2d337e02a275397fc9d0460dca90977f199acAdam Powell if (p.x < displayFrame.left) { 149156c2d337e02a275397fc9d0460dca90977f199acAdam Powell p.x = displayFrame.left; 149256c2d337e02a275397fc9d0460dca90977f199acAdam Powell p.width = Math.min(p.width, displayFrameWidth); 149356c2d337e02a275397fc9d0460dca90977f199acAdam Powell } 149456c2d337e02a275397fc9d0460dca90977f199acAdam Powell 14955f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell if (onTop) { 1496560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette final int popupTop = mScreenLocation[1] + yoff - mPopupHeight; 14975f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell if (popupTop < 0) { 14985f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell p.y += popupTop; 14995f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell } 15005f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell } else { 15015f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell p.y = Math.max(p.y, displayFrame.top); 15025f83a6017bacb513610df83a36b1f55953e65ad4Adam Powell } 150356c2d337e02a275397fc9d0460dca90977f199acAdam Powell } 150456c2d337e02a275397fc9d0460dca90977f199acAdam Powell 15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.gravity |= Gravity.DISPLAY_CLIP_VERTICAL; 1506560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette 15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return onTop; 15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15095435a30ae552391f14009c4459731ae149675b18Alan Viverette 15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the maximum height that is available for the popup to be 15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * completely shown. It is recommended that this height be the maximum for 15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the popup's height, otherwise it is possible that the popup will be 15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clipped. 15155435a30ae552391f14009c4459731ae149675b18Alan Viverette * 15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor The view on which the popup window must be anchored. 15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The maximum available height for the popup to be completely 15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * shown. 15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getMaxAvailableHeight(View anchor) { 15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return getMaxAvailableHeight(anchor, 0); 15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the maximum height that is available for the popup to be 15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * completely shown. It is recommended that this height be the maximum for 15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the popup's height, otherwise it is possible that the popup will be 15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clipped. 15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor The view on which the popup window must be anchored. 15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param yOffset y offset from the view's bottom edge 15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The maximum available height for the popup to be completely 15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * shown. 15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getMaxAvailableHeight(View anchor, int yOffset) { 153698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau return getMaxAvailableHeight(anchor, yOffset, false); 153798acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau } 15385435a30ae552391f14009c4459731ae149675b18Alan Viverette 153998acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau /** 154098acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * Returns the maximum height that is available for the popup to be 154198acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * completely shown, optionally ignoring any bottom decorations such as 154298acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * the input method. It is recommended that this height be the maximum for 154398acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * the popup's height, otherwise it is possible that the popup will be 154498acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * clipped. 15455435a30ae552391f14009c4459731ae149675b18Alan Viverette * 154698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @param anchor The view on which the popup window must be anchored. 154798acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @param yOffset y offset from the view's bottom edge 154898acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @param ignoreBottomDecorations if true, the height returned will be 154998acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * all the way to the bottom of the display, ignoring any 155098acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * bottom decorations 155198acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @return The maximum available height for the popup to be completely 155298acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * shown. 15535435a30ae552391f14009c4459731ae149675b18Alan Viverette * 155498acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau * @hide Pending API council approval. 155598acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau */ 155698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau public int getMaxAvailableHeight(View anchor, int yOffset, boolean ignoreBottomDecorations) { 15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect displayFrame = new Rect(); 15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anchor.getWindowVisibleDisplayFrame(displayFrame); 15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int[] anchorPos = mDrawingLocation; 15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project anchor.getLocationOnScreen(anchorPos); 15625435a30ae552391f14009c4459731ae149675b18Alan Viverette 156398acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau int bottomEdge = displayFrame.bottom; 156498acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau if (ignoreBottomDecorations) { 1565a7287f4d199b5d86e01d1de9d9a9db7e3221b02dAdam Powell Resources res = anchor.getContext().getResources(); 15663f4a764cf400aa209c1f8f76a1c73143eefc4905Adam Powell bottomEdge = res.getDisplayMetrics().heightPixels; 156798acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau } 156898acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau final int distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset; 15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset; 15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // anchorPos[1] is distance from anchor to top of screen 15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int returnedHeight = Math.max(distanceToBottom, distanceToTop); 15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBackground != null) { 15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBackground.getPadding(mTempRect); 15755435a30ae552391f14009c4459731ae149675b18Alan Viverette returnedHeight -= mTempRect.top + mTempRect.bottom; 15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15775435a30ae552391f14009c4459731ae149675b18Alan Viverette 15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return returnedHeight; 15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15805435a30ae552391f14009c4459731ae149675b18Alan Viverette 15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15827878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette * Disposes of the popup window. This method can be invoked only after 15837878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette * {@link #showAsDropDown(android.view.View)} has been executed. Failing 15847878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette * that, calling this method will have no effect. 15859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15865435a30ae552391f14009c4459731ae149675b18Alan Viverette * @see #showAsDropDown(android.view.View) 15879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dismiss() { 15898fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (!isShowing() || mIsTransitioningToDismiss) { 1590e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette return; 1591e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } 159206f938e8aa56cd89ab0bdb04c8b946392c428dd1Svetoslav Ganov 15938fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final PopupDecorView decorView = mDecorView; 15948fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View contentView = mContentView; 15958fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 15968fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewGroup contentHolder; 15978fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewParent contentParent = contentView.getParent(); 15988fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (contentParent instanceof ViewGroup) { 15998fd949e680c15d397084430d4907c16cedfacddaAlan Viverette contentHolder = ((ViewGroup) contentParent); 16008fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } else { 16018fd949e680c15d397084430d4907c16cedfacddaAlan Viverette contentHolder = null; 16028fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 16038fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 16048fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // Ensure any ongoing or pending transitions are canceled. 16058fd949e680c15d397084430d4907c16cedfacddaAlan Viverette decorView.cancelTransitions(); 16068fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 1607e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette unregisterForScrollChanged(); 16089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1609e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette mIsShowing = false; 16108fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mIsTransitioningToDismiss = true; 1611b82d074038f4c8d86e1bd4f3fa4d3780bd4bcba5Craig Mautner 16128fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (mExitTransition != null && decorView.isLaidOut()) { 16138fd949e680c15d397084430d4907c16cedfacddaAlan Viverette decorView.startExitTransition(mExitTransition, new TransitionListenerAdapter() { 1614e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette @Override 1615e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette public void onTransitionEnd(Transition transition) { 16168fd949e680c15d397084430d4907c16cedfacddaAlan Viverette dismissImmediate(decorView, contentHolder, contentView); 1617e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } 1618e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette }); 1619e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette } else { 16208fd949e680c15d397084430d4907c16cedfacddaAlan Viverette dismissImmediate(decorView, contentHolder, contentView); 16217878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette } 16227878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette 16237878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette if (mOnDismissListener != null) { 16247878edfa1dacf20c6120dbf18327905d6bf117d0Alan Viverette mOnDismissListener.onDismiss(); 16255435a30ae552391f14009c4459731ae149675b18Alan Viverette } 16265435a30ae552391f14009c4459731ae149675b18Alan Viverette } 16275435a30ae552391f14009c4459731ae149675b18Alan Viverette 16285435a30ae552391f14009c4459731ae149675b18Alan Viverette /** 16295435a30ae552391f14009c4459731ae149675b18Alan Viverette * Removes the popup from the window manager and tears down the supporting 16305435a30ae552391f14009c4459731ae149675b18Alan Viverette * view hierarchy, if necessary. 16315435a30ae552391f14009c4459731ae149675b18Alan Viverette */ 16328fd949e680c15d397084430d4907c16cedfacddaAlan Viverette private void dismissImmediate(View decorView, ViewGroup contentHolder, View contentView) { 16338fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // If this method gets called and the decor view doesn't have a parent, 16348fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // then it was either never added or was already removed. That should 16358fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // never happen, but it's worth checking to avoid potential crashes. 16368fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (decorView.getParent() != null) { 16378fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mWindowManager.removeViewImmediate(decorView); 1638df4639a0135ea643b493067b3f7cd1e092346c78Alan Viverette } 1639df4639a0135ea643b493067b3f7cd1e092346c78Alan Viverette 16408fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (contentHolder != null) { 16418fd949e680c15d397084430d4907c16cedfacddaAlan Viverette contentHolder.removeView(contentView); 16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16438fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 16448fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // This needs to stay until after all transitions have ended since we 16458fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // need the reference to cancel transitions in preparePopup(). 16468fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mDecorView = null; 16478fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mIsTransitioningToDismiss = false; 16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 16519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the listener to be called when the window is dismissed. 16525435a30ae552391f14009c4459731ae149675b18Alan Viverette * 16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param onDismissListener The listener. 16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setOnDismissListener(OnDismissListener onDismissListener) { 16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnDismissListener = onDismissListener; 16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16585435a30ae552391f14009c4459731ae149675b18Alan Viverette 16599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 16609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Updates the state of the popup window, if it is currently being displayed, 1661259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * from the currently set state. 1662259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1663259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * This includes: 1664259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <ul> 1665259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setClippingEnabled(boolean)}</li> 1666259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setFocusable(boolean)}</li> 1667259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setIgnoreCheekPress()}</li> 1668259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setInputMethodMode(int)}</li> 1669259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setTouchable(boolean)}</li> 1670259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <li>{@link #setAnimationStyle(int)}</li> 1671259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * </ul> 16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update() { 16749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isShowing() || mContentView == null) { 16759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16775435a30ae552391f14009c4459731ae149675b18Alan Viverette 16785435a30ae552391f14009c4459731ae149675b18Alan Viverette final WindowManager.LayoutParams p = 16795435a30ae552391f14009c4459731ae149675b18Alan Viverette (WindowManager.LayoutParams) mDecorView.getLayoutParams(); 16805435a30ae552391f14009c4459731ae149675b18Alan Viverette 16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean update = false; 16825435a30ae552391f14009c4459731ae149675b18Alan Viverette 16839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newAnim = computeAnimationResource(); 16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newAnim != p.windowAnimations) { 16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.windowAnimations = newAnim; 16869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 16879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newFlags = computeFlags(p.flags); 16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newFlags != p.flags) { 16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.flags = newFlags; 16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1694b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio 16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (update) { 1696b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio setLayoutDirectionFromAnchor(); 16975435a30ae552391f14009c4459731ae149675b18Alan Viverette mWindowManager.updateViewLayout(mDecorView, p); 16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1700d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy 1701d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy /** 1702259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the dimension of the popup window. 1703259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1704259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Calling this function also updates the window with the current popup 1705259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * state as described for {@link #update()}. 1706d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy * 1707259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param width the new width, must be >= 0 or -1 to ignore 1708259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param height the new height, must be >= 0 or -1 to ignore 1709d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy */ 1710d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy public void update(int width, int height) { 17115435a30ae552391f14009c4459731ae149675b18Alan Viverette final WindowManager.LayoutParams p = 17125435a30ae552391f14009c4459731ae149675b18Alan Viverette (WindowManager.LayoutParams) mDecorView.getLayoutParams(); 1713d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy update(p.x, p.y, width, height, false); 1714d6a463a9f23b3901bf729f2f27a6bb8f78b95248Romain Guy } 17155435a30ae552391f14009c4459731ae149675b18Alan Viverette 17169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1717259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 1718259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1719259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Width and height can be set to -1 to update location only. Calling this 1720259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * function also updates the window with the current popup state as 1721259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * described for {@link #update()}. 17229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 17239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x the new x location 17249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y the new y location 1725259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param width the new width, must be >= 0 or -1 to ignore 1726259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param height the new height, must be >= 0 or -1 to ignore 17279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 17289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(int x, int y, int width, int height) { 17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update(x, y, width, height, false); 17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1733259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 1734259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1735259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Width and height can be set to -1 to update location only. Calling this 1736259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * function also updates the window with the current popup state as 1737259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * described for {@link #update()}. 17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 17399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x the new x location 17409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y the new y location 1741259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param width the new width, must be >= 0 or -1 to ignore 1742259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param height the new height, must be >= 0 or -1 to ignore 1743259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param force {@code true} to reposition the window even if the specified 1744259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * position already seems to correspond to the LayoutParams, 1745259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * {@code false} to only reposition if needed 17469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 17479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(int x, int y, int width, int height, boolean force) { 1748259c2840691a79634ffd8f63291ec21c21819542Alan Viverette if (width >= 0) { 17499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastWidth = width; 17509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setWidth(width); 17519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1753259c2840691a79634ffd8f63291ec21c21819542Alan Viverette if (height >= 0) { 17549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastHeight = height; 17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setHeight(height); 17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isShowing() || mContentView == null) { 17599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 17609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17625435a30ae552391f14009c4459731ae149675b18Alan Viverette final WindowManager.LayoutParams p = 17635435a30ae552391f14009c4459731ae149675b18Alan Viverette (WindowManager.LayoutParams) mDecorView.getLayoutParams(); 17649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean update = force; 17669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int finalWidth = mWidthMode < 0 ? mWidthMode : mLastWidth; 17689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (width != -1 && p.width != finalWidth) { 17699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.width = mLastWidth = finalWidth; 17709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 17719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int finalHeight = mHeightMode < 0 ? mHeightMode : mLastHeight; 17749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (height != -1 && p.height != finalHeight) { 17759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.height = mLastHeight = finalHeight; 17769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 17779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p.x != x) { 17809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.x = x; 17819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 17829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p.y != y) { 17859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.y = y; 17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newAnim = computeAnimationResource(); 17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newAnim != p.windowAnimations) { 17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.windowAnimations = newAnim; 17929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 17939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newFlags = computeFlags(p.flags); 17969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newFlags != p.flags) { 17979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.flags = newFlags; 17989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update = true; 17999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 180098acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau 18019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (update) { 1802b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio setLayoutDirectionFromAnchor(); 18035435a30ae552391f14009c4459731ae149675b18Alan Viverette mWindowManager.updateViewLayout(mDecorView, p); 18049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1808259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 1809259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1810259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Calling this function also updates the window with the current popup 1811259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * state as described for {@link #update()}. 18129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 18139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the popup's anchor view 1814259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param width the new width, must be >= 0 or -1 to ignore 1815259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param height the new height, must be >= 0 or -1 to ignore 18169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 18179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(View anchor, int width, int height) { 181875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette update(anchor, false, 0, 0, true, width, height); 18199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1822259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Updates the position and the dimension of the popup window. 1823259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1824259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * Width and height can be set to -1 to update location only. Calling this 1825259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * function also updates the window with the current popup state as 1826259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * described for {@link #update()}. 1827259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * <p> 1828259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * If the view later scrolls to move {@code anchor} to a different 1829259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * location, the popup will be moved correspondingly. 18309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 18319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param anchor the popup's anchor view 18329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param xoff x offset from the view's left edge 18339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param yoff y offset from the view's bottom edge 1834259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param width the new width, must be >= 0 or -1 to ignore 1835259c2840691a79634ffd8f63291ec21c21819542Alan Viverette * @param height the new height, must be >= 0 or -1 to ignore 18369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 18379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void update(View anchor, int xoff, int yoff, int width, int height) { 183875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette update(anchor, true, xoff, yoff, true, width, height); 1839105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 1840105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 1841105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private void update(View anchor, boolean updateLocation, int xoff, int yoff, 184275d837954c3673647e3a899f03cd56c0892066e0Alan Viverette boolean updateDimension, int width, int height) { 1843105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 18449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isShowing() || mContentView == null) { 18459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 18469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 184875d837954c3673647e3a899f03cd56c0892066e0Alan Viverette final WeakReference<View> oldAnchor = mAnchor; 184975d837954c3673647e3a899f03cd56c0892066e0Alan Viverette final boolean needsUpdate = updateLocation && (mAnchorXoff != xoff || mAnchorYoff != yoff); 185081f08086b44a117097960195d2c9072e29644962Gilles Debunne if (oldAnchor == null || oldAnchor.get() != anchor || (needsUpdate && !mIsDropdown)) { 185175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette registerForScrollChanged(anchor, xoff, yoff, mAnchoredGravity); 185281f08086b44a117097960195d2c9072e29644962Gilles Debunne } else if (needsUpdate) { 185381f08086b44a117097960195d2c9072e29644962Gilles Debunne // No need to register again if this is a DropDown, showAsDropDown already did. 185481f08086b44a117097960195d2c9072e29644962Gilles Debunne mAnchorXoff = xoff; 185581f08086b44a117097960195d2c9072e29644962Gilles Debunne mAnchorYoff = yoff; 18569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1858105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (updateDimension) { 1859105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (width == -1) { 1860105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project width = mPopupWidth; 1861105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } else { 1862105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mPopupWidth = width; 1863105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 1864105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (height == -1) { 1865105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project height = mPopupHeight; 1866105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } else { 1867105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mPopupHeight = height; 1868105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 18699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1870105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 187175d837954c3673647e3a899f03cd56c0892066e0Alan Viverette final WindowManager.LayoutParams p = 18725435a30ae552391f14009c4459731ae149675b18Alan Viverette (WindowManager.LayoutParams) mDecorView.getLayoutParams(); 187375d837954c3673647e3a899f03cd56c0892066e0Alan Viverette final int x = p.x; 187475d837954c3673647e3a899f03cd56c0892066e0Alan Viverette final int y = p.y; 1875105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (updateLocation) { 187675d837954c3673647e3a899f03cd56c0892066e0Alan Viverette updateAboveAnchor(findDropDownPosition(anchor, p, xoff, yoff, mAnchoredGravity)); 18779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 187854c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell updateAboveAnchor(findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff, 187954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell mAnchoredGravity)); 18809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1881b003e28c1d65d06fcb5690ff2955d007d8f7a626Fabrice Di Meglio 18823e141685003939a9addce21ba2492ea3a8aebee6Romain Guy update(p.x, p.y, width, height, x != p.x || y != p.y); 18839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 18869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Listener that is called when this popup window is dismissed. 18879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 18889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnDismissListener { 18899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called when this popup window is dismissed. 18919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onDismiss(); 18939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void unregisterForScrollChanged() { 1896e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final WeakReference<View> anchorRef = mAnchor; 1897e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final View anchor = anchorRef == null ? null : anchorRef.get(); 18989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (anchor != null) { 1899e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final ViewTreeObserver vto = anchor.getViewTreeObserver(); 19009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project vto.removeOnScrollChangedListener(mOnScrollChangedListener); 19019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1902e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 19039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnchor = null; 19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 190654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell private void registerForScrollChanged(View anchor, int xoff, int yoff, int gravity) { 19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterForScrollChanged(); 19089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19095435a30ae552391f14009c4459731ae149675b18Alan Viverette mAnchor = new WeakReference<>(anchor); 1910e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette 1911e025ed2f26858dae5f40a94a2e1ac0db808a6950Alan Viverette final ViewTreeObserver vto = anchor.getViewTreeObserver(); 19129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (vto != null) { 19139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project vto.addOnScrollChangedListener(mOnScrollChangedListener); 19149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnchorXoff = xoff; 19179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnchorYoff = yoff; 191854c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell mAnchoredGravity = gravity; 19199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19215435a30ae552391f14009c4459731ae149675b18Alan Viverette private class PopupDecorView extends FrameLayout { 19228fd949e680c15d397084430d4907c16cedfacddaAlan Viverette private TransitionListenerAdapter mPendingExitListener; 19238fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 19245435a30ae552391f14009c4459731ae149675b18Alan Viverette public PopupDecorView(Context context) { 19255435a30ae552391f14009c4459731ae149675b18Alan Viverette super(context); 19265435a30ae552391f14009c4459731ae149675b18Alan Viverette } 19279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 19299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean dispatchKeyEvent(KeyEvent event) { 19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { 19314ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson if (getKeyDispatcherState() == null) { 19324ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson return super.dispatchKeyEvent(event); 19334ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson } 19344ae02b37bb0ee0a9a626108299b6a2e9ac028ca2Per Andersson 19355435a30ae552391f14009c4459731ae149675b18Alan Viverette if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { 19365435a30ae552391f14009c4459731ae149675b18Alan Viverette final KeyEvent.DispatcherState state = getKeyDispatcherState(); 1937b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown if (state != null) { 1938b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown state.startTracking(event, this); 1939b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } 19408d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn return true; 1941b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } else if (event.getAction() == KeyEvent.ACTION_UP) { 19425435a30ae552391f14009c4459731ae149675b18Alan Viverette final KeyEvent.DispatcherState state = getKeyDispatcherState(); 1943b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown if (state != null && state.isTracking(event) && !event.isCanceled()) { 1944b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown dismiss(); 1945b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown return true; 1946b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } 19478d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn } 19488d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn return super.dispatchKeyEvent(event); 19499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 19509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.dispatchKeyEvent(event); 19519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 19559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean dispatchTouchEvent(MotionEvent ev) { 19569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTouchInterceptor != null && mTouchInterceptor.onTouch(this, ev)) { 19579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.dispatchTouchEvent(ev); 19609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 19639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onTouchEvent(MotionEvent event) { 19649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int x = (int) event.getX(); 19659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int y = (int) event.getY(); 19665435a30ae552391f14009c4459731ae149675b18Alan Viverette 19679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((event.getAction() == MotionEvent.ACTION_DOWN) 19689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && ((x < 0) || (x >= getWidth()) || (y < 0) || (y >= getHeight()))) { 19699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dismiss(); 19709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 19719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (event.getAction() == MotionEvent.ACTION_OUTSIDE) { 19729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dismiss(); 19739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 19749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 19759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.onTouchEvent(event); 19769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19788fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 19798fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 19808fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Requests that an enter transition run after the next layout pass. 19818fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 19828fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void requestEnterTransition(Transition transition) { 19838fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewTreeObserver observer = getViewTreeObserver(); 19848fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (observer != null && transition != null) { 19858fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final Transition enterTransition = transition.clone(); 19868fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 19878fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // Postpone the enter transition after the first layout pass. 19888fd949e680c15d397084430d4907c16cedfacddaAlan Viverette observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 19898fd949e680c15d397084430d4907c16cedfacddaAlan Viverette @Override 19908fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void onGlobalLayout() { 19918fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final ViewTreeObserver observer = getViewTreeObserver(); 19928fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (observer != null) { 19938fd949e680c15d397084430d4907c16cedfacddaAlan Viverette observer.removeOnGlobalLayoutListener(this); 19948fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 19958fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 19968fd949e680c15d397084430d4907c16cedfacddaAlan Viverette startEnterTransition(enterTransition); 19978fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 19988fd949e680c15d397084430d4907c16cedfacddaAlan Viverette }); 19998fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20008fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20018fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20028fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 20038fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Starts the pending enter transition, if one is set. 20048fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 20058fd949e680c15d397084430d4907c16cedfacddaAlan Viverette private void startEnterTransition(Transition enterTransition) { 20068fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final int count = getChildCount(); 20078fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 20088fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 20098fd949e680c15d397084430d4907c16cedfacddaAlan Viverette enterTransition.addTarget(child); 20108fd949e680c15d397084430d4907c16cedfacddaAlan Viverette child.setVisibility(View.INVISIBLE); 20118fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20128fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20138fd949e680c15d397084430d4907c16cedfacddaAlan Viverette TransitionManager.beginDelayedTransition(this, enterTransition); 20148fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20158fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 20168fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 20178fd949e680c15d397084430d4907c16cedfacddaAlan Viverette child.setVisibility(View.VISIBLE); 20188fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20198fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20208fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20218fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 20228fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Starts an exit transition immediately. 20238fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * <p> 20248fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * <strong>Note:</strong> The transition listener is guaranteed to have 20258fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * its {@code onTransitionEnd} method called even if the transition 20268fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * never starts; however, it may be called with a {@code null} argument. 20278fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 20288fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void startExitTransition(Transition transition, final TransitionListener listener) { 20298fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (transition == null) { 20308fd949e680c15d397084430d4907c16cedfacddaAlan Viverette return; 20318fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20328fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20338fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // The exit listener MUST be called for cleanup, even if the 20348fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // transition never starts or ends. Stash it for later. 20358fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mPendingExitListener = new TransitionListenerAdapter() { 20368fd949e680c15d397084430d4907c16cedfacddaAlan Viverette @Override 20378fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void onTransitionEnd(Transition transition) { 20388fd949e680c15d397084430d4907c16cedfacddaAlan Viverette listener.onTransitionEnd(transition); 20398fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20408fd949e680c15d397084430d4907c16cedfacddaAlan Viverette // The listener was called. Our job here is done. 20418fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mPendingExitListener = null; 20428fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20438fd949e680c15d397084430d4907c16cedfacddaAlan Viverette }; 20448fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20458fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final Transition exitTransition = transition.clone(); 20468fd949e680c15d397084430d4907c16cedfacddaAlan Viverette exitTransition.addListener(mPendingExitListener); 20478fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20488fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final int count = getChildCount(); 20498fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 20508fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 20518fd949e680c15d397084430d4907c16cedfacddaAlan Viverette exitTransition.addTarget(child); 20528fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20538fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20548fd949e680c15d397084430d4907c16cedfacddaAlan Viverette TransitionManager.beginDelayedTransition(this, exitTransition); 20558fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20568fd949e680c15d397084430d4907c16cedfacddaAlan Viverette for (int i = 0; i < count; i++) { 20578fd949e680c15d397084430d4907c16cedfacddaAlan Viverette final View child = getChildAt(i); 20588fd949e680c15d397084430d4907c16cedfacddaAlan Viverette child.setVisibility(View.INVISIBLE); 20598fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20608fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20618fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20628fd949e680c15d397084430d4907c16cedfacddaAlan Viverette /** 20638fd949e680c15d397084430d4907c16cedfacddaAlan Viverette * Cancels all pending or current transitions. 20648fd949e680c15d397084430d4907c16cedfacddaAlan Viverette */ 20658fd949e680c15d397084430d4907c16cedfacddaAlan Viverette public void cancelTransitions() { 20668fd949e680c15d397084430d4907c16cedfacddaAlan Viverette TransitionManager.endTransitions(this); 20678fd949e680c15d397084430d4907c16cedfacddaAlan Viverette 20688fd949e680c15d397084430d4907c16cedfacddaAlan Viverette if (mPendingExitListener != null) { 20698fd949e680c15d397084430d4907c16cedfacddaAlan Viverette mPendingExitListener.onTransitionEnd(null); 20708fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20718fd949e680c15d397084430d4907c16cedfacddaAlan Viverette } 20725435a30ae552391f14009c4459731ae149675b18Alan Viverette } 20735435a30ae552391f14009c4459731ae149675b18Alan Viverette 20745435a30ae552391f14009c4459731ae149675b18Alan Viverette private class PopupBackgroundView extends FrameLayout { 20755435a30ae552391f14009c4459731ae149675b18Alan Viverette public PopupBackgroundView(Context context) { 20765435a30ae552391f14009c4459731ae149675b18Alan Viverette super(context); 20775435a30ae552391f14009c4459731ae149675b18Alan Viverette } 207875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov 207975986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov @Override 20805435a30ae552391f14009c4459731ae149675b18Alan Viverette protected int[] onCreateDrawableState(int extraSpace) { 20815435a30ae552391f14009c4459731ae149675b18Alan Viverette if (mAboveAnchor) { 20825435a30ae552391f14009c4459731ae149675b18Alan Viverette final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 20835435a30ae552391f14009c4459731ae149675b18Alan Viverette View.mergeDrawableStates(drawableState, ABOVE_ANCHOR_STATE_SET); 20845435a30ae552391f14009c4459731ae149675b18Alan Viverette return drawableState; 208575986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } else { 20865435a30ae552391f14009c4459731ae149675b18Alan Viverette return super.onCreateDrawableState(extraSpace); 208775986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 208875986cf9bc57ef11ad70f36fb77fbbf5d63af6ecsvetoslavganov } 20899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2091