1c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell/* 2c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Copyright (C) 2010 The Android Open Source Project 3c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 4c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Licensed under the Apache License, Version 2.0 (the "License"); 5c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * you may not use this file except in compliance with the License. 6c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * You may obtain a copy of the License at 7c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 8c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * http://www.apache.org/licenses/LICENSE-2.0 9c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 10c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Unless required by applicable law or agreed to in writing, software 11c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * distributed under the License is distributed on an "AS IS" BASIS, 12c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * See the License for the specific language governing permissions and 14c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * limitations under the License. 15c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 16c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 17c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellpackage android.widget; 18c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1902cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viveretteimport com.android.internal.R; 2002cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viveretteimport com.android.internal.view.menu.ShowableListMenu; 2102cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette 2202cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viveretteimport android.annotation.AttrRes; 2302cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viveretteimport android.annotation.NonNull; 2402cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viveretteimport android.annotation.Nullable; 2502cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viveretteimport android.annotation.StyleRes; 26c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.content.Context; 27f023c2530a4591889dda614aaa016d5a9f9617edAlan Viveretteimport android.content.res.TypedArray; 28c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.database.DataSetObserver; 29c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.graphics.Rect; 30c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.graphics.drawable.Drawable; 31c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.os.Handler; 32c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.util.AttributeSet; 33c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.util.Log; 3454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powellimport android.view.Gravity; 35c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.KeyEvent; 36c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.MotionEvent; 37c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.View; 38c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.View.MeasureSpec; 39c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.View.OnTouchListener; 40711734a2f8d7529df0ed1bce36da651fc835c144Gilles Debunneimport android.view.ViewGroup; 41711734a2f8d7529df0ed1bce36da651fc835c144Gilles Debunneimport android.view.ViewParent; 4280ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viveretteimport android.view.WindowManager; 4302cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viveretteimport android.widget.AdapterView.OnItemSelectedListener; 441d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio 45c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell/** 46c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * A ListPopupWindow anchors itself to a host view and displays a 4765d79fbe55c017edd9419ddb71939c8916471390Adam Powell * list of choices. 48c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 49c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>ListPopupWindow contains a number of tricky behaviors surrounding 50c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * positioning, scrolling parents to fit the dropdown, interacting 51c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * sanely with the IME if present, and others. 52c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 53c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see android.widget.AutoCompleteTextView 54c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see android.widget.Spinner 55c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 56f44d90b5c247f0629201d1fa322b83fa55b20608Oren Blasbergpublic class ListPopupWindow implements ShowableListMenu { 57c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private static final String TAG = "ListPopupWindow"; 58c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private static final boolean DEBUG = false; 59c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 60c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 61c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * This value controls the length of time that the user 62c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * must leave a pointer down without scrolling to expand 63c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * the autocomplete dropdown list to cover the IME. 64c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 65c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private static final int EXPAND_LIST_TIMEOUT = 250; 66c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 67c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private Context mContext; 68c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private ListAdapter mAdapter; 69c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private DropDownListView mDropDownList; 70c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 71c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private int mDropDownHeight = ViewGroup.LayoutParams.WRAP_CONTENT; 72c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private int mDropDownWidth = ViewGroup.LayoutParams.WRAP_CONTENT; 73c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private int mDropDownHorizontalOffset; 74c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private int mDropDownVerticalOffset; 7580ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette private int mDropDownWindowLayoutType = WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL; 768132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell private boolean mDropDownVerticalOffsetSet; 7791098574f90277128415e9593cce1e495cc51465Alan Viverette private boolean mIsAnimatedFromAnchor = true; 78c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 7954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell private int mDropDownGravity = Gravity.NO_GRAVITY; 8054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 81c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private boolean mDropDownAlwaysVisible = false; 82c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private boolean mForceIgnoreOutsideTouch = false; 83348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell int mListItemExpandMaximum = Integer.MAX_VALUE; 84c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 85c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private View mPromptView; 86c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private int mPromptPosition = POSITION_PROMPT_ABOVE; 87c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 88c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private DataSetObserver mObserver; 89c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 90c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private View mDropDownAnchorView; 91c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 92c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private Drawable mDropDownListHighlight; 93c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 94c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private AdapterView.OnItemClickListener mItemClickListener; 95c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private AdapterView.OnItemSelectedListener mItemSelectedListener; 96c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 974267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell private final ResizePopupRunnable mResizePopupRunnable = new ResizePopupRunnable(); 98c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private final PopupTouchInterceptor mTouchInterceptor = new PopupTouchInterceptor(); 99c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private final PopupScrollListener mScrollListener = new PopupScrollListener(); 100c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private final ListSelectorHider mHideSelector = new ListSelectorHider(); 101c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private Runnable mShowDropDownRunnable; 102c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1034a50723fe399047e833e61f43928f21d90e2b5faAlan Viverette private final Handler mHandler; 104c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 10591098574f90277128415e9593cce1e495cc51465Alan Viverette private final Rect mTempRect = new Rect(); 10691098574f90277128415e9593cce1e495cc51465Alan Viverette 10791098574f90277128415e9593cce1e495cc51465Alan Viverette /** 10891098574f90277128415e9593cce1e495cc51465Alan Viverette * Optional anchor-relative bounds to be used as the transition epicenter. 10991098574f90277128415e9593cce1e495cc51465Alan Viverette * When {@code null}, the anchor bounds are used as the epicenter. 11091098574f90277128415e9593cce1e495cc51465Alan Viverette */ 11191098574f90277128415e9593cce1e495cc51465Alan Viverette private Rect mEpicenterBounds; 112c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 113c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private boolean mModal; 114c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1158e12f8df076d38853e0fedde7ed79e2e8689d59eOren Blasberg PopupWindow mPopup; 1168e12f8df076d38853e0fedde7ed79e2e8689d59eOren Blasberg 117c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 118c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * The provided prompt view should appear above list content. 119c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 120c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setPromptPosition(int) 121c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #getPromptPosition() 122c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setPromptView(View) 123c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 124c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public static final int POSITION_PROMPT_ABOVE = 0; 125c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 126c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 127c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * The provided prompt view should appear below list content. 128c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 129c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setPromptPosition(int) 130c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #getPromptPosition() 131c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setPromptView(View) 132c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 133c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public static final int POSITION_PROMPT_BELOW = 1; 134c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 135c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 136c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Alias for {@link ViewGroup.LayoutParams#MATCH_PARENT}. 137c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * If used to specify a popup width, the popup will match the width of the anchor view. 138c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * If used to specify a popup height, the popup will fill available space. 139c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 140c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public static final int MATCH_PARENT = ViewGroup.LayoutParams.MATCH_PARENT; 141c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 142c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 143c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Alias for {@link ViewGroup.LayoutParams#WRAP_CONTENT}. 144c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * If used to specify a popup width, the popup will use the width of its content. 145c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 146c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public static final int WRAP_CONTENT = ViewGroup.LayoutParams.WRAP_CONTENT; 147c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 148c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 149c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Mode for {@link #setInputMethodMode(int)}: the requirements for the 150c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * input method should be based on the focusability of the popup. That is 151c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * if it is focusable than it needs to work with the input method, else 152c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * it doesn't. 153c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 154c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public static final int INPUT_METHOD_FROM_FOCUSABLE = PopupWindow.INPUT_METHOD_FROM_FOCUSABLE; 155c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 156c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 157c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Mode for {@link #setInputMethodMode(int)}: this popup always needs to 158c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * work with an input method, regardless of whether it is focusable. This 159c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * means that it will always be displayed so that the user can also operate 160c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * the input method while it is shown. 161c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 162c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public static final int INPUT_METHOD_NEEDED = PopupWindow.INPUT_METHOD_NEEDED; 163c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 164c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 165c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Mode for {@link #setInputMethodMode(int)}: this popup never needs to 166c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * work with an input method, regardless of whether it is focusable. This 167c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * means that it will always be displayed to use as much space on the 168c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * screen as needed, regardless of whether this covers the input method. 169c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 170c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public static final int INPUT_METHOD_NOT_NEEDED = PopupWindow.INPUT_METHOD_NOT_NEEDED; 171c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 172c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 173c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Create a new, empty popup window capable of displaying items from a ListAdapter. 174c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Backgrounds should be set using {@link #setBackgroundDrawable(Drawable)}. 175c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 176c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param context Context used for contained views. 177c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 17802cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette public ListPopupWindow(@NonNull Context context) { 179c2238d006237ebf1296074d80fb4f4a2741ef880Daniel Lehmann this(context, null, com.android.internal.R.attr.listPopupWindowStyle, 0); 180c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 181c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 182c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 183c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Create a new, empty popup window capable of displaying items from a ListAdapter. 184c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Backgrounds should be set using {@link #setBackgroundDrawable(Drawable)}. 185c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 186c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param context Context used for contained views. 187c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param attrs Attributes from inflating parent views used to style the popup. 188c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 18902cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette public ListPopupWindow(@NonNull Context context, @Nullable AttributeSet attrs) { 1900b2d306e7000f4c0c6ad4e00d494bb401d8a9fc2Adam Powell this(context, attrs, com.android.internal.R.attr.listPopupWindowStyle, 0); 191c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 192c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 193c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 194c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Create a new, empty popup window capable of displaying items from a ListAdapter. 195c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Backgrounds should be set using {@link #setBackgroundDrawable(Drawable)}. 196c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 197c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param context Context used for contained views. 198c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param attrs Attributes from inflating parent views used to style the popup. 199c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param defStyleAttr Default style attribute to use for popup content. 200c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 20102cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette public ListPopupWindow(@NonNull Context context, @Nullable AttributeSet attrs, 20202cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette @AttrRes int defStyleAttr) { 203c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell this(context, attrs, defStyleAttr, 0); 204c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 205c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 206c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 207c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Create a new, empty popup window capable of displaying items from a ListAdapter. 208c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Backgrounds should be set using {@link #setBackgroundDrawable(Drawable)}. 209c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 210c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param context Context used for contained views. 211c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param attrs Attributes from inflating parent views used to style the popup. 212c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param defStyleAttr Style attribute to read for default styling of popup content. 213c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param defStyleRes Style resource ID to use for default styling of popup content. 214c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 21502cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette public ListPopupWindow(@NonNull Context context, @Nullable AttributeSet attrs, 21602cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette @AttrRes int defStyleAttr, @StyleRes int defStyleRes) { 217c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mContext = context; 2184a50723fe399047e833e61f43928f21d90e2b5faAlan Viverette mHandler = new Handler(context.getMainLooper()); 219f023c2530a4591889dda614aaa016d5a9f9617edAlan Viverette 220f023c2530a4591889dda614aaa016d5a9f9617edAlan Viverette final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ListPopupWindow, 221f023c2530a4591889dda614aaa016d5a9f9617edAlan Viverette defStyleAttr, defStyleRes); 222f023c2530a4591889dda614aaa016d5a9f9617edAlan Viverette mDropDownHorizontalOffset = a.getDimensionPixelOffset( 223f023c2530a4591889dda614aaa016d5a9f9617edAlan Viverette R.styleable.ListPopupWindow_dropDownHorizontalOffset, 0); 224f023c2530a4591889dda614aaa016d5a9f9617edAlan Viverette mDropDownVerticalOffset = a.getDimensionPixelOffset( 225f023c2530a4591889dda614aaa016d5a9f9617edAlan Viverette R.styleable.ListPopupWindow_dropDownVerticalOffset, 0); 226f023c2530a4591889dda614aaa016d5a9f9617edAlan Viverette if (mDropDownVerticalOffset != 0) { 227f023c2530a4591889dda614aaa016d5a9f9617edAlan Viverette mDropDownVerticalOffsetSet = true; 228f023c2530a4591889dda614aaa016d5a9f9617edAlan Viverette } 229f023c2530a4591889dda614aaa016d5a9f9617edAlan Viverette a.recycle(); 230f023c2530a4591889dda614aaa016d5a9f9617edAlan Viverette 231c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup = new PopupWindow(context, attrs, defStyleAttr, defStyleRes); 2326f5e934b96c400f610b1c5ad228cc60cab5d443fAdam Powell mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); 233c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 234c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 235c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 236c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets the adapter that provides the data and the views to represent the data 237c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * in this popup window. 238c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 239c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param adapter The adapter to use to create this window's content. 240c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 24102cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette public void setAdapter(@Nullable ListAdapter adapter) { 242c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mObserver == null) { 243c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mObserver = new PopupDataSetObserver(); 244c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else if (mAdapter != null) { 24599969da3772d9a0f5079672847ca4f2ad819c1bbAdam Powell mAdapter.unregisterDataSetObserver(mObserver); 246c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 247c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mAdapter = adapter; 248c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mAdapter != null) { 249c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell adapter.registerDataSetObserver(mObserver); 250c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 251c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 252c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownList != null) { 253c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setAdapter(mAdapter); 254c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 255c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 256c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 257c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 258c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Set where the optional prompt view should appear. The default is 259c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * {@link #POSITION_PROMPT_ABOVE}. 260c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 261c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param position A position constant declaring where the prompt should be displayed. 262c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 263c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #POSITION_PROMPT_ABOVE 264c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #POSITION_PROMPT_BELOW 265c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 266c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setPromptPosition(int position) { 267c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPromptPosition = position; 268c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 269c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 270c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 271c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return Where the optional prompt view should appear. 272c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 273c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #POSITION_PROMPT_ABOVE 274c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #POSITION_PROMPT_BELOW 275c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 276c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getPromptPosition() { 277c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mPromptPosition; 278c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 279c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 280c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 281c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Set whether this window should be modal when shown. 282c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 283c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>If a popup window is modal, it will receive all touch and key input. 284c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * If the user touches outside the popup window's content area the popup window 285c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * will be dismissed. 286c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 287c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param modal {@code true} if the popup window should be modal, {@code false} otherwise. 288c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 289c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setModal(boolean modal) { 290e04499ad930ff4f112114683dc9f1e5411d6802bChet Haase mModal = modal; 291c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setFocusable(modal); 292c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 293c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 294c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 295c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Returns whether the popup window will be modal when shown. 296c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 297c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return {@code true} if the popup window will be modal, {@code false} otherwise. 298c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 299c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean isModal() { 300c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mModal; 301c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 302c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 303c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 304c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Forces outside touches to be ignored. Normally if {@link #isDropDownAlwaysVisible()} is 305c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * false, we allow outside touch to dismiss the dropdown. If this is set to true, then we 306c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * ignore outside touch even when the drop down is not set to always visible. 307c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 308c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @hide Used only by AutoCompleteTextView to handle some internal special cases. 309c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 310c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setForceIgnoreOutsideTouch(boolean forceIgnoreOutsideTouch) { 311c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mForceIgnoreOutsideTouch = forceIgnoreOutsideTouch; 312c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 313c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 314c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 315c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets whether the drop-down should remain visible under certain conditions. 316c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 317c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * The drop-down will occupy the entire screen below {@link #getAnchorView} regardless 318c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * of the size or content of the list. {@link #getBackground()} will fill any space 319c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * that is not used by the list. 320c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 321c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param dropDownAlwaysVisible Whether to keep the drop-down visible. 322c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 323c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @hide Only used by AutoCompleteTextView under special conditions. 324c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 325c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setDropDownAlwaysVisible(boolean dropDownAlwaysVisible) { 326c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownAlwaysVisible = dropDownAlwaysVisible; 327c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 328c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 329c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 330c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return Whether the drop-down is visible under special conditions. 331c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 332c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @hide Only used by AutoCompleteTextView under special conditions. 333c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 334c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean isDropDownAlwaysVisible() { 335c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownAlwaysVisible; 336c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 337c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 338c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 339c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets the operating mode for the soft input area. 340c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 341c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param mode The desired mode, see 342c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * {@link android.view.WindowManager.LayoutParams#softInputMode} 343c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * for the full list 344c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 345c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see android.view.WindowManager.LayoutParams#softInputMode 346c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #getSoftInputMode() 347c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 348c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setSoftInputMode(int mode) { 349c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setSoftInputMode(mode); 350c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 351c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 352c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 353c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Returns the current value in {@link #setSoftInputMode(int)}. 354c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 355c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setSoftInputMode(int) 356c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see android.view.WindowManager.LayoutParams#softInputMode 357c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 358c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getSoftInputMode() { 359c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mPopup.getSoftInputMode(); 360c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 361c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 362c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 363c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets a drawable to use as the list item selector. 364c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 365c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param selector List selector drawable to use in the popup. 366c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 367c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setListSelector(Drawable selector) { 368c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownListHighlight = selector; 369c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 370c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 371c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 372c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The background drawable for the popup window. 373c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 37402cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette public @Nullable Drawable getBackground() { 375c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mPopup.getBackground(); 376c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 377c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 378c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 379c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets a drawable to be the background for the popup window. 380c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 381c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param d A drawable to set as the background. 382c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 38302cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette public void setBackgroundDrawable(@Nullable Drawable d) { 384c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setBackgroundDrawable(d); 385c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 386c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 387c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 388c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Set an animation style to use when the popup window is shown or dismissed. 389c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 390c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param animationStyle Animation style to use. 391c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 39202cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette public void setAnimationStyle(@StyleRes int animationStyle) { 393c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setAnimationStyle(animationStyle); 394c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 395c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 396c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 397c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Returns the animation style that will be used when the popup window is 398c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * shown or dismissed. 399c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 400c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return Animation style that will be used. 401c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 40202cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette public @StyleRes int getAnimationStyle() { 403c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mPopup.getAnimationStyle(); 404c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 405c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 406c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 407c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Returns the view that will be used to anchor this popup. 408c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 409c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The popup's anchor view 410c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 41102cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette public @Nullable View getAnchorView() { 412c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownAnchorView; 413c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 414c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 415c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 416c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets the popup's anchor view. This popup will always be positioned relative to 417c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * the anchor view when shown. 418c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 419c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param anchor The view to use as an anchor. 420c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 42102cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette public void setAnchorView(@Nullable View anchor) { 422c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownAnchorView = anchor; 423c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 424c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 425c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 426c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The horizontal offset of the popup from its anchor in pixels. 427c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 428c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getHorizontalOffset() { 429c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownHorizontalOffset; 430c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 431c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 432c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 433c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Set the horizontal offset of this popup from its anchor view in pixels. 434c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 435a984b38df5cfe6db0ba792bf2a6221f6b6072448Adam Powell * @param offset The horizontal offset of the popup from its anchor. 436c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 437c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setHorizontalOffset(int offset) { 438c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownHorizontalOffset = offset; 439c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 440c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 441c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 442c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The vertical offset of the popup from its anchor in pixels. 443c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 444c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getVerticalOffset() { 4458132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell if (!mDropDownVerticalOffsetSet) { 4468132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell return 0; 4478132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell } 448c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownVerticalOffset; 449c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 450c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 451c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 452c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Set the vertical offset of this popup from its anchor view in pixels. 453c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 454a984b38df5cfe6db0ba792bf2a6221f6b6072448Adam Powell * @param offset The vertical offset of the popup from its anchor. 455c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 456c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setVerticalOffset(int offset) { 457c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownVerticalOffset = offset; 4588132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell mDropDownVerticalOffsetSet = true; 459c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 460c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 461c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 46291098574f90277128415e9593cce1e495cc51465Alan Viverette * Specifies the anchor-relative bounds of the popup's transition 46391098574f90277128415e9593cce1e495cc51465Alan Viverette * epicenter. 46491098574f90277128415e9593cce1e495cc51465Alan Viverette * 46591098574f90277128415e9593cce1e495cc51465Alan Viverette * @param bounds anchor-relative bounds 46691098574f90277128415e9593cce1e495cc51465Alan Viverette * @hide 46791098574f90277128415e9593cce1e495cc51465Alan Viverette */ 46891098574f90277128415e9593cce1e495cc51465Alan Viverette public void setEpicenterBounds(Rect bounds) { 46991098574f90277128415e9593cce1e495cc51465Alan Viverette mEpicenterBounds = bounds; 47091098574f90277128415e9593cce1e495cc51465Alan Viverette } 47191098574f90277128415e9593cce1e495cc51465Alan Viverette 47291098574f90277128415e9593cce1e495cc51465Alan Viverette /** 47354c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * Set the gravity of the dropdown list. This is commonly used to 47454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * set gravity to START or END for alignment with the anchor. 47554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * 47654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param gravity Gravity value to use 47754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell */ 47854c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell public void setDropDownGravity(int gravity) { 47954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell mDropDownGravity = gravity; 48054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell } 48154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 48254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell /** 483c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The width of the popup window in pixels. 484c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 485c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getWidth() { 486c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownWidth; 487c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 488c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 489c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 490c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets the width of the popup window in pixels. Can also be {@link #MATCH_PARENT} 491c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * or {@link #WRAP_CONTENT}. 492c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 493c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param width Width of the popup window. 494c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 495c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setWidth(int width) { 496c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownWidth = width; 497c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 498c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 499c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 5004267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell * Sets the width of the popup window by the size of its content. The final width may be 5014267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell * larger to accommodate styled window dressing. 5024267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell * 5034267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell * @param width Desired width of content in pixels. 5044267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell */ 5054267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell public void setContentWidth(int width) { 5064267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell Drawable popupBackground = mPopup.getBackground(); 5074267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell if (popupBackground != null) { 508a39b987bb761899636ae1e3669d1343499d04ebdAdam Powell popupBackground.getPadding(mTempRect); 509a39b987bb761899636ae1e3669d1343499d04ebdAdam Powell mDropDownWidth = mTempRect.left + mTempRect.right + width; 51062e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell } else { 51162e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell setWidth(width); 5124267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell } 5134267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell } 5144267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell 5154267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell /** 516c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The height of the popup window in pixels. 517c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 518c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getHeight() { 519c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownHeight; 520c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 521c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 522c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 523c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets the height of the popup window in pixels. Can also be {@link #MATCH_PARENT}. 524c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 525c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param height Height of the popup window. 526c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 527c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setHeight(int height) { 528c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownHeight = height; 529c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 530c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 531c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 53280ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette * Set the layout type for this popup window. 53380ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette * <p> 53480ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette * See {@link WindowManager.LayoutParams#type} for possible values. 53580ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette * 53680ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette * @param layoutType Layout type for this window. 53780ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette * 53880ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette * @see WindowManager.LayoutParams#type 53980ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette */ 54080ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette public void setWindowLayoutType(int layoutType) { 54180ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette mDropDownWindowLayoutType = layoutType; 54280ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette } 54380ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette 54480ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette /** 545c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets a listener to receive events when a list item is clicked. 546c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 547c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param clickListener Listener to register 548c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 549c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see ListView#setOnItemClickListener(android.widget.AdapterView.OnItemClickListener) 550c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 55102cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette public void setOnItemClickListener(@Nullable AdapterView.OnItemClickListener clickListener) { 552c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mItemClickListener = clickListener; 553c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 554c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 555c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 556c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets a listener to receive events when a list item is selected. 557c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 558c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param selectedListener Listener to register. 559c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 56002cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette * @see ListView#setOnItemSelectedListener(OnItemSelectedListener) 561c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 56202cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette public void setOnItemSelectedListener(@Nullable OnItemSelectedListener selectedListener) { 563c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mItemSelectedListener = selectedListener; 564c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 565c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 566c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 567c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Set a view to act as a user prompt for this popup window. Where the prompt view will appear 568c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * is controlled by {@link #setPromptPosition(int)}. 569c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 570c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param prompt View to use as an informational prompt. 571c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 57202cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette public void setPromptView(@Nullable View prompt) { 573c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell boolean showing = isShowing(); 574c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (showing) { 575c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell removePromptView(); 576c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 577c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPromptView = prompt; 578c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (showing) { 579c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell show(); 580c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 581c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 582c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 583c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 584c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Post a {@link #show()} call to the UI thread. 585c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 586c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void postShow() { 587c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mHandler.post(mShowDropDownRunnable); 588c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 589c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 590c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 591c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Show the popup list. If the list is already showing, this method 592c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * will recalculate the popup's size and position. 593c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 594f44d90b5c247f0629201d1fa322b83fa55b20608Oren Blasberg @Override 595c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void show() { 596c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int height = buildDropDown(); 597c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 59880ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette final boolean noInputMethod = isInputMethodNotNeeded(); 599348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell mPopup.setAllowScrollingAnchorParent(!noInputMethod); 60080ebe0d4ecb36d0e82dce499ccc0810cf3a0ec89Alan Viverette mPopup.setWindowLayoutType(mDropDownWindowLayoutType); 601c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 602c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mPopup.isShowing()) { 603259c2840691a79634ffd8f63291ec21c21819542Alan Viverette final int widthSpec; 604c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT) { 605c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // The call to PopupWindow's update method below can accept -1 for any 606c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // value you do not want to update. 607c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell widthSpec = -1; 608c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) { 609c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell widthSpec = getAnchorView().getWidth(); 610c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 611c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell widthSpec = mDropDownWidth; 612c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 613c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 614259c2840691a79634ffd8f63291ec21c21819542Alan Viverette final int heightSpec; 615c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) { 616c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // The call to PopupWindow's update method below can accept -1 for any 617c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // value you do not want to update. 618c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell heightSpec = noInputMethod ? height : ViewGroup.LayoutParams.MATCH_PARENT; 619c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (noInputMethod) { 620259c2840691a79634ffd8f63291ec21c21819542Alan Viverette mPopup.setWidth(mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT ? 621259c2840691a79634ffd8f63291ec21c21819542Alan Viverette ViewGroup.LayoutParams.MATCH_PARENT : 0); 622259c2840691a79634ffd8f63291ec21c21819542Alan Viverette mPopup.setHeight(0); 623c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 624259c2840691a79634ffd8f63291ec21c21819542Alan Viverette mPopup.setWidth(mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT ? 625259c2840691a79634ffd8f63291ec21c21819542Alan Viverette ViewGroup.LayoutParams.MATCH_PARENT : 0); 626259c2840691a79634ffd8f63291ec21c21819542Alan Viverette mPopup.setHeight(ViewGroup.LayoutParams.MATCH_PARENT); 627c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 628c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) { 629c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell heightSpec = height; 630c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 631c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell heightSpec = mDropDownHeight; 632c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 633c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 634c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch && !mDropDownAlwaysVisible); 635c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 636c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.update(getAnchorView(), mDropDownHorizontalOffset, 6370eaec1f5d1b47739b8d33cb45111bccd18f2d7b1Jun Mukai mDropDownVerticalOffset, (widthSpec < 0)? -1 : widthSpec, 6380eaec1f5d1b47739b8d33cb45111bccd18f2d7b1Jun Mukai (heightSpec < 0)? -1 : heightSpec); 639c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 640259c2840691a79634ffd8f63291ec21c21819542Alan Viverette final int widthSpec; 641c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT) { 642c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell widthSpec = ViewGroup.LayoutParams.MATCH_PARENT; 643c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 644c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) { 645259c2840691a79634ffd8f63291ec21c21819542Alan Viverette widthSpec = getAnchorView().getWidth(); 646c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 647259c2840691a79634ffd8f63291ec21c21819542Alan Viverette widthSpec = mDropDownWidth; 648c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 649c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 650c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 651259c2840691a79634ffd8f63291ec21c21819542Alan Viverette final int heightSpec; 652c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) { 653c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell heightSpec = ViewGroup.LayoutParams.MATCH_PARENT; 654c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 655c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) { 656259c2840691a79634ffd8f63291ec21c21819542Alan Viverette heightSpec = height; 657c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 658259c2840691a79634ffd8f63291ec21c21819542Alan Viverette heightSpec = mDropDownHeight; 659c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 660c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 661c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 662259c2840691a79634ffd8f63291ec21c21819542Alan Viverette mPopup.setWidth(widthSpec); 663259c2840691a79634ffd8f63291ec21c21819542Alan Viverette mPopup.setHeight(heightSpec); 66456c2d337e02a275397fc9d0460dca90977f199acAdam Powell mPopup.setClipToScreenEnabled(true); 665c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 666c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // use outside touchable to dismiss drop down when touching outside of it, so 667c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // only set this if the dropdown is not always visible 668c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch && !mDropDownAlwaysVisible); 669c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setTouchInterceptor(mTouchInterceptor); 67091098574f90277128415e9593cce1e495cc51465Alan Viverette mPopup.setEpicenterBounds(mEpicenterBounds); 671560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette mPopup.showAsDropDown(getAnchorView(), mDropDownHorizontalOffset, 672560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette mDropDownVerticalOffset, mDropDownGravity); 673c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setSelection(ListView.INVALID_POSITION); 674c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 675c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (!mModal || mDropDownList.isInTouchMode()) { 676c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell clearListSelection(); 677c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 678c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (!mModal) { 679c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mHandler.post(mHideSelector); 680c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 681c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 682c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 683c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 684c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 685c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Dismiss the popup window. 686c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 687f44d90b5c247f0629201d1fa322b83fa55b20608Oren Blasberg @Override 688c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void dismiss() { 689c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.dismiss(); 690c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell removePromptView(); 691c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setContentView(null); 692c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList = null; 693ca51e8788a58f2af3525b7214a675f2d0233e5daAdam Powell mHandler.removeCallbacks(mResizePopupRunnable); 694c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 695c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 6966c6f575423d6718c3ff322224c1520901ce881e1Adam Powell /** 6976c6f575423d6718c3ff322224c1520901ce881e1Adam Powell * Set a listener to receive a callback when the popup is dismissed. 6986c6f575423d6718c3ff322224c1520901ce881e1Adam Powell * 6996c6f575423d6718c3ff322224c1520901ce881e1Adam Powell * @param listener Listener that will be notified when the popup is dismissed. 7006c6f575423d6718c3ff322224c1520901ce881e1Adam Powell */ 70102cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette public void setOnDismissListener(@Nullable PopupWindow.OnDismissListener listener) { 7026c6f575423d6718c3ff322224c1520901ce881e1Adam Powell mPopup.setOnDismissListener(listener); 7036c6f575423d6718c3ff322224c1520901ce881e1Adam Powell } 7046c6f575423d6718c3ff322224c1520901ce881e1Adam Powell 705c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private void removePromptView() { 706c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mPromptView != null) { 707c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final ViewParent parent = mPromptView.getParent(); 708c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (parent instanceof ViewGroup) { 709c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final ViewGroup group = (ViewGroup) parent; 710c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell group.removeView(mPromptView); 711c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 712c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 713c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 714c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 715c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 716c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Control how the popup operates with an input method: one of 717c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * {@link #INPUT_METHOD_FROM_FOCUSABLE}, {@link #INPUT_METHOD_NEEDED}, 718c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * or {@link #INPUT_METHOD_NOT_NEEDED}. 719c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 720c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>If the popup is showing, calling this method will take effect only 721c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * the next time the popup is shown or through a manual call to the {@link #show()} 722c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * method.</p> 723c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 724c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #getInputMethodMode() 725c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #show() 726c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 727c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setInputMethodMode(int mode) { 728c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setInputMethodMode(mode); 729c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 730c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 731c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 732c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Return the current value in {@link #setInputMethodMode(int)}. 733c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 734c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setInputMethodMode(int) 735c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 736c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getInputMethodMode() { 737c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mPopup.getInputMethodMode(); 738c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 739c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 740c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 741c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Set the selected position of the list. 742c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Only valid when {@link #isShowing()} == {@code true}. 743c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 744c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param position List position to set as selected. 745c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 746c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setSelection(int position) { 747c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell DropDownListView list = mDropDownList; 748c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (isShowing() && list != null) { 749f44d90b5c247f0629201d1fa322b83fa55b20608Oren Blasberg list.setListSelectionHidden(false); 750c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell list.setSelection(position); 751c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (list.getChoiceMode() != ListView.CHOICE_MODE_NONE) { 752c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell list.setItemChecked(position, true); 753c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 754c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 755c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 756c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 757c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 758c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Clear any current list selection. 759c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Only valid when {@link #isShowing()} == {@code true}. 760c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 761c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void clearListSelection() { 762c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final DropDownListView list = mDropDownList; 763c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (list != null) { 764c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // WARNING: Please read the comment where mListSelectionHidden is declared 765f44d90b5c247f0629201d1fa322b83fa55b20608Oren Blasberg list.setListSelectionHidden(true); 766c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell list.hideSelector(); 767c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell list.requestLayout(); 768c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 769c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 770c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 771c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 772c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return {@code true} if the popup is currently showing, {@code false} otherwise. 773c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 774f44d90b5c247f0629201d1fa322b83fa55b20608Oren Blasberg @Override 775c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean isShowing() { 776c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mPopup.isShowing(); 777c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 778c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 779c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 780c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return {@code true} if this popup is configured to assume the user does not need 781c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * to interact with the IME while it is showing, {@code false} otherwise. 782c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 783c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean isInputMethodNotNeeded() { 784c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mPopup.getInputMethodMode() == INPUT_METHOD_NOT_NEEDED; 785c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 786c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 787c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 788c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Perform an item click operation on the specified list adapter position. 789c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 790c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param position Adapter position for performing the click 791c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return true if the click action could be performed, false if not. 792c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * (e.g. if the popup was not showing, this method would return false.) 793c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 794c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean performItemClick(int position) { 795c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (isShowing()) { 796c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mItemClickListener != null) { 797c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final DropDownListView list = mDropDownList; 798c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final View child = list.getChildAt(position - list.getFirstVisiblePosition()); 799cdee446075811e871fc2af295377bd99c100d16dAdam Powell final ListAdapter adapter = list.getAdapter(); 800cdee446075811e871fc2af295377bd99c100d16dAdam Powell mItemClickListener.onItemClick(list, child, position, adapter.getItemId(position)); 801c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 802c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return true; 803c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 804c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return false; 805c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 806c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 807c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 808c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The currently selected item or null if the popup is not showing. 809c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 81002cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette public @Nullable Object getSelectedItem() { 811c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (!isShowing()) { 812c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return null; 813c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 814c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownList.getSelectedItem(); 815c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 816c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 817c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 818c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The position of the currently selected item or {@link ListView#INVALID_POSITION} 819c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * if {@link #isShowing()} == {@code false}. 820c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 821c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see ListView#getSelectedItemPosition() 822c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 823c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getSelectedItemPosition() { 824c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (!isShowing()) { 825c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return ListView.INVALID_POSITION; 826c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 827c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownList.getSelectedItemPosition(); 828c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 829c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 830c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 831c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The ID of the currently selected item or {@link ListView#INVALID_ROW_ID} 832c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * if {@link #isShowing()} == {@code false}. 833c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 834c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see ListView#getSelectedItemId() 835c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 836c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public long getSelectedItemId() { 837c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (!isShowing()) { 838c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return ListView.INVALID_ROW_ID; 839c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 840c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownList.getSelectedItemId(); 841c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 842c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 843c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 844c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The View for the currently selected item or null if 845c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * {@link #isShowing()} == {@code false}. 846c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 847c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see ListView#getSelectedView() 848c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 84902cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette public @Nullable View getSelectedView() { 850c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (!isShowing()) { 851c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return null; 852c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 853c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownList.getSelectedView(); 854c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 855c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 856c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 857c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The {@link ListView} displayed within the popup window. 858c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Only valid when {@link #isShowing()} == {@code true}. 859c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 860f44d90b5c247f0629201d1fa322b83fa55b20608Oren Blasberg @Override 86102cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette public @Nullable ListView getListView() { 862c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownList; 863c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 864c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 86502cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette @NonNull DropDownListView createDropDownListView(Context context, boolean hijackFocus) { 86631f581c5a64320d9a90ce3fb1a4625f94f4f8021Jun Mukai return new DropDownListView(context, hijackFocus); 86731f581c5a64320d9a90ce3fb1a4625f94f4f8021Jun Mukai } 86831f581c5a64320d9a90ce3fb1a4625f94f4f8021Jun Mukai 869c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 870348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * The maximum number of list items that can be visible and still have 871348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * the list expand when touched. 872348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * 873348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * @param max Max number of items that can be visible and still allow the list to expand. 874348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell */ 875348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell void setListItemExpandMax(int max) { 876348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell mListItemExpandMaximum = max; 877348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell } 878348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell 879348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell /** 8808d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown * Filter key down events. By forwarding key down events to this function, 881c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * views using non-modal ListPopupWindow can have it handle key selection of items. 8823d25a1f5dbe892330fb2677d8b1030bcbcd60447Kirill Grouchnikov * 883c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param keyCode keyCode param passed to the host view's onKeyDown 884c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param event event param passed to the host view's onKeyDown 885c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return true if the event was handled, false if it was ignored. 8863d25a1f5dbe892330fb2677d8b1030bcbcd60447Kirill Grouchnikov * 887c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setModal(boolean) 8883d25a1f5dbe892330fb2677d8b1030bcbcd60447Kirill Grouchnikov * @see #onKeyUp(int, KeyEvent) 889c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 89002cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette public boolean onKeyDown(int keyCode, @NonNull KeyEvent event) { 891c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // when the drop down is shown, we drive it directly 892c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (isShowing()) { 893c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // the key events are forwarded to the list in the drop down view 894c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // note that ListView handles space but we don't want that to happen 895c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // also if selection is not currently in the drop down, then don't 896c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // let center or enter presses go there since that would cause it 897c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // to select one of its items 898c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (keyCode != KeyEvent.KEYCODE_SPACE 899c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell && (mDropDownList.getSelectedItemPosition() >= 0 90024d36f592224d1316165f579bb0937df0bf42f7cMichael Wright || !KeyEvent.isConfirmKey(keyCode))) { 901c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int curIndex = mDropDownList.getSelectedItemPosition(); 902c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell boolean consumed; 903c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 904c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final boolean below = !mPopup.isAboveAnchor(); 905c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 906c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final ListAdapter adapter = mAdapter; 907c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 908c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell boolean allEnabled; 909c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int firstItem = Integer.MAX_VALUE; 910c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int lastItem = Integer.MIN_VALUE; 911c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 912c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (adapter != null) { 913c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell allEnabled = adapter.areAllItemsEnabled(); 914c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell firstItem = allEnabled ? 0 : 915c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.lookForSelectablePosition(0, true); 916c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell lastItem = allEnabled ? adapter.getCount() - 1 : 917c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.lookForSelectablePosition(adapter.getCount() - 1, false); 918c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 919c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 920c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if ((below && keyCode == KeyEvent.KEYCODE_DPAD_UP && curIndex <= firstItem) || 921c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell (!below && keyCode == KeyEvent.KEYCODE_DPAD_DOWN && curIndex >= lastItem)) { 922c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // When the selection is at the top, we block the key 923c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // event to prevent focus from moving. 924c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell clearListSelection(); 925c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); 926c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell show(); 927c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return true; 928c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 929c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // WARNING: Please read the comment where mListSelectionHidden 930c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // is declared 931f44d90b5c247f0629201d1fa322b83fa55b20608Oren Blasberg mDropDownList.setListSelectionHidden(false); 932c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 933c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 934c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell consumed = mDropDownList.onKeyDown(keyCode, event); 935c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (DEBUG) Log.v(TAG, "Key down: code=" + keyCode + " list consumed=" + consumed); 936c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 937c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (consumed) { 938c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // If it handled the key event, then the user is 939c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // navigating in the list, so we should put it in front. 940c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); 941c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // Here's a little trick we need to do to make sure that 942c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // the list view is actually showing its focus indicator, 943c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // by ensuring it has focus and getting its window out 944c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // of touch mode. 945c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.requestFocusFromTouch(); 946c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell show(); 947c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 948c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell switch (keyCode) { 949c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // avoid passing the focus from the text view to the 950c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // next component 951c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell case KeyEvent.KEYCODE_ENTER: 952c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell case KeyEvent.KEYCODE_DPAD_CENTER: 953c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell case KeyEvent.KEYCODE_DPAD_DOWN: 954c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell case KeyEvent.KEYCODE_DPAD_UP: 955c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return true; 956c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 957c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 958c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (below && keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { 959c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // when the selection is at the bottom, we block the 960c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // event to avoid going to the next focusable widget 961c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (curIndex == lastItem) { 962c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return true; 963c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 964c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else if (!below && keyCode == KeyEvent.KEYCODE_DPAD_UP && 965c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell curIndex == firstItem) { 966c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return true; 967c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 968c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 969c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 970c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 971c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 972c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return false; 973c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 974c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 975c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 9763d25a1f5dbe892330fb2677d8b1030bcbcd60447Kirill Grouchnikov * Filter key up events. By forwarding key up events to this function, 977c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * views using non-modal ListPopupWindow can have it handle key selection of items. 9783d25a1f5dbe892330fb2677d8b1030bcbcd60447Kirill Grouchnikov * 979c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param keyCode keyCode param passed to the host view's onKeyUp 980c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param event event param passed to the host view's onKeyUp 981c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return true if the event was handled, false if it was ignored. 9823d25a1f5dbe892330fb2677d8b1030bcbcd60447Kirill Grouchnikov * 983c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setModal(boolean) 9843d25a1f5dbe892330fb2677d8b1030bcbcd60447Kirill Grouchnikov * @see #onKeyDown(int, KeyEvent) 985c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 98602cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette public boolean onKeyUp(int keyCode, @NonNull KeyEvent event) { 987c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (isShowing() && mDropDownList.getSelectedItemPosition() >= 0) { 988c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell boolean consumed = mDropDownList.onKeyUp(keyCode, event); 98924d36f592224d1316165f579bb0937df0bf42f7cMichael Wright if (consumed && KeyEvent.isConfirmKey(keyCode)) { 99024d36f592224d1316165f579bb0937df0bf42f7cMichael Wright // if the list accepts the key events and the key event was a click, the text view 99124d36f592224d1316165f579bb0937df0bf42f7cMichael Wright // gets the selected item from the drop down as its content 99224d36f592224d1316165f579bb0937df0bf42f7cMichael Wright dismiss(); 993c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 994c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return consumed; 995c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 996c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return false; 997c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 998c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 999c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 1000c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Filter pre-IME key events. By forwarding {@link View#onKeyPreIme(int, KeyEvent)} 1001c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * events to this function, views using ListPopupWindow can have it dismiss the popup 1002c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * when the back key is pressed. 10033d25a1f5dbe892330fb2677d8b1030bcbcd60447Kirill Grouchnikov * 1004c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param keyCode keyCode param passed to the host view's onKeyPreIme 1005c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param event event param passed to the host view's onKeyPreIme 1006c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return true if the event was handled, false if it was ignored. 10073d25a1f5dbe892330fb2677d8b1030bcbcd60447Kirill Grouchnikov * 1008c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setModal(boolean) 1009c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 101002cd0f91059f04136bb3817b41305c2909f4f1d5Alan Viverette public boolean onKeyPreIme(int keyCode, @NonNull KeyEvent event) { 1011c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (keyCode == KeyEvent.KEYCODE_BACK && isShowing()) { 1012c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // special case for the back key, we do not even try to send it 1013c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // to the drop down list but instead, consume it immediately 1014c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final View anchorView = mDropDownAnchorView; 1015c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { 1016b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown KeyEvent.DispatcherState state = anchorView.getKeyDispatcherState(); 1017b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown if (state != null) { 1018b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown state.startTracking(event, this); 1019b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } 1020c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return true; 1021c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else if (event.getAction() == KeyEvent.ACTION_UP) { 1022b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown KeyEvent.DispatcherState state = anchorView.getKeyDispatcherState(); 1023b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown if (state != null) { 1024b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown state.handleUpEvent(event); 1025b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } 1026c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (event.isTracking() && !event.isCanceled()) { 1027c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell dismiss(); 1028c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return true; 1029c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1030c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1031c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1032c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return false; 1033c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1034c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1035c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 10361955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * Returns an {@link OnTouchListener} that can be added to the source view 10371955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * to implement drag-to-open behavior. Generally, the source view should be 10381955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * the same view that was passed to {@link #setAnchorView}. 10391955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * <p> 10401955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * When the listener is set on a view, touching that view and dragging 10411955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * outside of its bounds will open the popup window. Lifting will select the 10421955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * currently touched list item. 10431955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * <p> 10441955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * Example usage: 10453f9832d3c7b30bf4dc8ed9e5123b02daca96c878Alan Viverette * <pre> 10463f9832d3c7b30bf4dc8ed9e5123b02daca96c878Alan Viverette * ListPopupWindow myPopup = new ListPopupWindow(context); 10471955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * myPopup.setAnchor(myAnchor); 10481955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * OnTouchListener dragListener = myPopup.createDragToOpenListener(myAnchor); 10493f9832d3c7b30bf4dc8ed9e5123b02daca96c878Alan Viverette * myAnchor.setOnTouchListener(dragListener); 10503f9832d3c7b30bf4dc8ed9e5123b02daca96c878Alan Viverette * </pre> 10511955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * 10521955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * @param src the view on which the resulting listener will be set 10531955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * @return a touch listener that controls drag-to-open behavior 10541955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette */ 10551955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette public OnTouchListener createDragToOpenListener(View src) { 10561955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette return new ForwardingListener(src) { 10571955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette @Override 1058f44d90b5c247f0629201d1fa322b83fa55b20608Oren Blasberg public ShowableListMenu getPopup() { 10591955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette return ListPopupWindow.this; 10601955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette } 10611955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette }; 10621955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette } 10631955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette 10641955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette /** 1065c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>Builds the popup window's content and returns the height the popup 1066c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * should have. Returns -1 when the content already exists.</p> 1067c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 1068c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return the content's height or -1 if content already exists 1069c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 1070c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private int buildDropDown() { 1071c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell ViewGroup dropDownView; 1072c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int otherHeights = 0; 1073c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1074c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownList == null) { 1075c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell Context context = mContext; 1076c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1077c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 1078c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * This Runnable exists for the sole purpose of checking if the view layout has got 1079c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * completed and if so call showDropDown to display the drop down. This is used to show 1080c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * the drop down as soon as possible after user opens up the search dialog, without 1081c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * waiting for the normal UI pipeline to do it's job which is slower than this method. 1082c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 1083c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mShowDropDownRunnable = new Runnable() { 1084c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void run() { 1085c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // View layout should be all done before displaying the drop down. 1086c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell View view = getAnchorView(); 1087c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (view != null && view.getWindowToken() != null) { 1088c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell show(); 1089c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1090c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1091c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell }; 1092c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 109331f581c5a64320d9a90ce3fb1a4625f94f4f8021Jun Mukai mDropDownList = createDropDownListView(context, !mModal); 1094c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownListHighlight != null) { 1095c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setSelector(mDropDownListHighlight); 1096c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1097c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setAdapter(mAdapter); 1098c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setOnItemClickListener(mItemClickListener); 1099c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setFocusable(true); 1100c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setFocusableInTouchMode(true); 1101c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 1102c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void onItemSelected(AdapterView<?> parent, View view, 1103c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int position, long id) { 1104c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1105c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (position != -1) { 1106c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell DropDownListView dropDownList = mDropDownList; 1107c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1108c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (dropDownList != null) { 1109f44d90b5c247f0629201d1fa322b83fa55b20608Oren Blasberg dropDownList.setListSelectionHidden(false); 1110c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1111c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1112c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1113c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1114c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void onNothingSelected(AdapterView<?> parent) { 1115c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1116c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell }); 1117c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setOnScrollListener(mScrollListener); 1118c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1119c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mItemSelectedListener != null) { 1120c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setOnItemSelectedListener(mItemSelectedListener); 1121c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1122c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1123c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell dropDownView = mDropDownList; 1124c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1125c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell View hintView = mPromptView; 1126c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (hintView != null) { 1127f76a50ce8fdc6aea22cabc77b2977a1a15a79630Ken Wakasa // if a hint has been specified, we accomodate more space for it and 1128c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // add a text view in the drop down menu, at the bottom of the list 1129c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell LinearLayout hintContainer = new LinearLayout(context); 1130c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell hintContainer.setOrientation(LinearLayout.VERTICAL); 1131c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1132c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell LinearLayout.LayoutParams hintParams = new LinearLayout.LayoutParams( 1133c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell ViewGroup.LayoutParams.MATCH_PARENT, 0, 1.0f 1134c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell ); 1135c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1136c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell switch (mPromptPosition) { 1137c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell case POSITION_PROMPT_BELOW: 1138c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell hintContainer.addView(dropDownView, hintParams); 1139c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell hintContainer.addView(hintView); 1140c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell break; 1141c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1142c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell case POSITION_PROMPT_ABOVE: 1143c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell hintContainer.addView(hintView); 1144c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell hintContainer.addView(dropDownView, hintParams); 1145c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell break; 1146c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1147c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell default: 1148c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell Log.e(TAG, "Invalid hint position " + mPromptPosition); 1149c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell break; 1150c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1151c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1152ba4332d9cf09b7e342783e39efd41646792a5b06Alan Viverette // Measure the hint's height to find how much more vertical 1153ba4332d9cf09b7e342783e39efd41646792a5b06Alan Viverette // space we need to add to the drop down's height. 1154ba4332d9cf09b7e342783e39efd41646792a5b06Alan Viverette final int widthSize; 1155ba4332d9cf09b7e342783e39efd41646792a5b06Alan Viverette final int widthMode; 1156ba4332d9cf09b7e342783e39efd41646792a5b06Alan Viverette if (mDropDownWidth >= 0) { 1157ba4332d9cf09b7e342783e39efd41646792a5b06Alan Viverette widthMode = MeasureSpec.AT_MOST; 1158ba4332d9cf09b7e342783e39efd41646792a5b06Alan Viverette widthSize = mDropDownWidth; 1159ba4332d9cf09b7e342783e39efd41646792a5b06Alan Viverette } else { 1160ba4332d9cf09b7e342783e39efd41646792a5b06Alan Viverette widthMode = MeasureSpec.UNSPECIFIED; 1161ba4332d9cf09b7e342783e39efd41646792a5b06Alan Viverette widthSize = 0; 1162ba4332d9cf09b7e342783e39efd41646792a5b06Alan Viverette } 1163ba4332d9cf09b7e342783e39efd41646792a5b06Alan Viverette final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, widthMode); 1164ba4332d9cf09b7e342783e39efd41646792a5b06Alan Viverette final int heightSpec = MeasureSpec.UNSPECIFIED; 1165c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell hintView.measure(widthSpec, heightSpec); 1166c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1167c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell hintParams = (LinearLayout.LayoutParams) hintView.getLayoutParams(); 1168c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell otherHeights = hintView.getMeasuredHeight() + hintParams.topMargin 1169c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell + hintParams.bottomMargin; 1170c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1171c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell dropDownView = hintContainer; 1172c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1173c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1174c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setContentView(dropDownView); 1175c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 1176c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final View view = mPromptView; 1177c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (view != null) { 1178c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell LinearLayout.LayoutParams hintParams = 1179c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell (LinearLayout.LayoutParams) view.getLayoutParams(); 1180c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell otherHeights = view.getMeasuredHeight() + hintParams.topMargin 1181c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell + hintParams.bottomMargin; 1182c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1183c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1184c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 11858132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell // getMaxAvailableHeight() subtracts the padding, so we put it back 11861e2c2d45090db36b73df105ec37b7b896e5bab3cAlan Viverette // to get the available height for the whole window. 11871e2c2d45090db36b73df105ec37b7b896e5bab3cAlan Viverette final int padding; 11881e2c2d45090db36b73df105ec37b7b896e5bab3cAlan Viverette final Drawable background = mPopup.getBackground(); 1189c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (background != null) { 1190c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell background.getPadding(mTempRect); 1191c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell padding = mTempRect.top + mTempRect.bottom; 11928132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell 11931e2c2d45090db36b73df105ec37b7b896e5bab3cAlan Viverette // If we don't have an explicit vertical offset, determine one from 11941e2c2d45090db36b73df105ec37b7b896e5bab3cAlan Viverette // the window background so that content will line up. 11958132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell if (!mDropDownVerticalOffsetSet) { 11968132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell mDropDownVerticalOffset = -mTempRect.top; 11978132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell } 11987507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell } else { 11997507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell mTempRect.setEmpty(); 12001e2c2d45090db36b73df105ec37b7b896e5bab3cAlan Viverette padding = 0; 1201c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1202c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 12038132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell // Max height available on the screen for a popup. 12041e2c2d45090db36b73df105ec37b7b896e5bab3cAlan Viverette final boolean ignoreBottomDecorations = 12058132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED; 12068132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell final int maxHeight = mPopup.getMaxAvailableHeight( 12078132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell getAnchorView(), mDropDownVerticalOffset, ignoreBottomDecorations); 1208c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownAlwaysVisible || mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) { 1209c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return maxHeight + padding; 1210c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1211c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 12127507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell final int childWidthSpec; 12137507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell switch (mDropDownWidth) { 12147507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell case ViewGroup.LayoutParams.WRAP_CONTENT: 12157507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell childWidthSpec = MeasureSpec.makeMeasureSpec( 12161e2c2d45090db36b73df105ec37b7b896e5bab3cAlan Viverette mContext.getResources().getDisplayMetrics().widthPixels 12171e2c2d45090db36b73df105ec37b7b896e5bab3cAlan Viverette - (mTempRect.left + mTempRect.right), 12187507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell MeasureSpec.AT_MOST); 12197507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell break; 12207507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell case ViewGroup.LayoutParams.MATCH_PARENT: 12217507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell childWidthSpec = MeasureSpec.makeMeasureSpec( 12221e2c2d45090db36b73df105ec37b7b896e5bab3cAlan Viverette mContext.getResources().getDisplayMetrics().widthPixels 12231e2c2d45090db36b73df105ec37b7b896e5bab3cAlan Viverette - (mTempRect.left + mTempRect.right), 12247507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell MeasureSpec.EXACTLY); 12257507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell break; 12267507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell default: 12277507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell childWidthSpec = MeasureSpec.makeMeasureSpec(mDropDownWidth, MeasureSpec.EXACTLY); 12287507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell break; 12297507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell } 12301e2c2d45090db36b73df105ec37b7b896e5bab3cAlan Viverette 12311e2c2d45090db36b73df105ec37b7b896e5bab3cAlan Viverette // Add padding only if the list has items in it, that way we don't show 12321e2c2d45090db36b73df105ec37b7b896e5bab3cAlan Viverette // the popup if it is not needed. 12337507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell final int listContent = mDropDownList.measureHeightOfChildren(childWidthSpec, 12341e2c2d45090db36b73df105ec37b7b896e5bab3cAlan Viverette 0, DropDownListView.NO_POSITION, maxHeight - otherHeights, -1); 12351e2c2d45090db36b73df105ec37b7b896e5bab3cAlan Viverette if (listContent > 0) { 12361e2c2d45090db36b73df105ec37b7b896e5bab3cAlan Viverette final int listPadding = mDropDownList.getPaddingTop() 12371e2c2d45090db36b73df105ec37b7b896e5bab3cAlan Viverette + mDropDownList.getPaddingBottom(); 12381e2c2d45090db36b73df105ec37b7b896e5bab3cAlan Viverette otherHeights += padding + listPadding; 12391e2c2d45090db36b73df105ec37b7b896e5bab3cAlan Viverette } 1240c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1241c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return listContent + otherHeights; 1242c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1243c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1244c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private class PopupDataSetObserver extends DataSetObserver { 1245c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell @Override 1246c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void onChanged() { 1247c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (isShowing()) { 1248c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // Resize the popup to fit new content 1249c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell show(); 1250c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1251c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1252c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1253c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell @Override 1254c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void onInvalidated() { 1255c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell dismiss(); 1256c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1257c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1258c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1259c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private class ListSelectorHider implements Runnable { 1260c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void run() { 1261c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell clearListSelection(); 1262c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1263c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1264c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1265c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private class ResizePopupRunnable implements Runnable { 1266c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void run() { 1267c8bfc68cddc15787943e7db1ba1cfeb26d4f74d3Alan Viverette if (mDropDownList != null && mDropDownList.isAttachedToWindow() 1268c8bfc68cddc15787943e7db1ba1cfeb26d4f74d3Alan Viverette && mDropDownList.getCount() > mDropDownList.getChildCount() 1269c8bfc68cddc15787943e7db1ba1cfeb26d4f74d3Alan Viverette && mDropDownList.getChildCount() <= mListItemExpandMaximum) { 1270348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); 1271348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell show(); 1272348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell } 1273c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1274c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1275c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1276c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private class PopupTouchInterceptor implements OnTouchListener { 1277c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean onTouch(View v, MotionEvent event) { 1278c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final int action = event.getAction(); 1279c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final int x = (int) event.getX(); 1280c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final int y = (int) event.getY(); 1281c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1282c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (action == MotionEvent.ACTION_DOWN && 1283c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup != null && mPopup.isShowing() && 1284711734a2f8d7529df0ed1bce36da651fc835c144Gilles Debunne (x >= 0 && x < mPopup.getWidth() && y >= 0 && y < mPopup.getHeight())) { 1285c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mHandler.postDelayed(mResizePopupRunnable, EXPAND_LIST_TIMEOUT); 1286c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else if (action == MotionEvent.ACTION_UP) { 1287c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mHandler.removeCallbacks(mResizePopupRunnable); 1288c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1289c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return false; 1290c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1291c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1292c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1293c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private class PopupScrollListener implements ListView.OnScrollListener { 1294c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, 1295c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int totalItemCount) { 1296c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1297c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1298c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1299c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void onScrollStateChanged(AbsListView view, int scrollState) { 1300c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (scrollState == SCROLL_STATE_TOUCH_SCROLL && 1301c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell !isInputMethodNotNeeded() && mPopup.getContentView() != null) { 1302c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mHandler.removeCallbacks(mResizePopupRunnable); 1303c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mResizePopupRunnable.run(); 1304c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1305c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1306c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1307c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell} 1308