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 19c05027214f1f4dda67296a072dfc9af9176dc590Alan Viveretteimport android.animation.Animator; 20c05027214f1f4dda67296a072dfc9af9176dc590Alan Viveretteimport android.animation.AnimatorListenerAdapter; 21c05027214f1f4dda67296a072dfc9af9176dc590Alan Viveretteimport android.animation.ObjectAnimator; 22c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.content.Context; 23c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.database.DataSetObserver; 24c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.graphics.Rect; 25c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.graphics.drawable.Drawable; 26c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.os.Handler; 27d3d9f3f1004dfee2649a26cfe8dba948cd364904Fabrice Di Meglioimport android.text.TextUtils; 28c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.util.AttributeSet; 29c05027214f1f4dda67296a072dfc9af9176dc590Alan Viveretteimport android.util.IntProperty; 30c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.util.Log; 3154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powellimport android.view.Gravity; 32c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.KeyEvent; 33c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.MotionEvent; 34c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.View; 35c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.View.MeasureSpec; 3669960142efa8d228adbfcbabdcf618426e31e1f5Alan Viveretteimport android.view.View.OnAttachStateChangeListener; 37c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.View.OnTouchListener; 38ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viveretteimport android.view.ViewConfiguration; 39711734a2f8d7529df0ed1bce36da651fc835c144Gilles Debunneimport android.view.ViewGroup; 40711734a2f8d7529df0ed1bce36da651fc835c144Gilles Debunneimport android.view.ViewParent; 41c05027214f1f4dda67296a072dfc9af9176dc590Alan Viveretteimport android.view.animation.AccelerateDecelerateInterpolator; 42c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 435e66021c8a24c27c470cc6b9fe49e5653f3fa05dAlan Viveretteimport com.android.internal.widget.AutoScrollHelper.AbsListViewAutoScroller; 445e66021c8a24c27c470cc6b9fe49e5653f3fa05dAlan Viverette 451d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglioimport java.util.Locale; 461d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio 47c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell/** 48c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * A ListPopupWindow anchors itself to a host view and displays a 4965d79fbe55c017edd9419ddb71939c8916471390Adam Powell * list of choices. 50c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 51c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>ListPopupWindow contains a number of tricky behaviors surrounding 52c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * positioning, scrolling parents to fit the dropdown, interacting 53c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * sanely with the IME if present, and others. 54c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 55c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see android.widget.AutoCompleteTextView 56c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see android.widget.Spinner 57c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 58c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellpublic class ListPopupWindow { 59c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private static final String TAG = "ListPopupWindow"; 60c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private static final boolean DEBUG = false; 61c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 62c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 63c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * This value controls the length of time that the user 64c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * must leave a pointer down without scrolling to expand 65c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * the autocomplete dropdown list to cover the IME. 66c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 67c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private static final int EXPAND_LIST_TIMEOUT = 250; 68c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 69c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private Context mContext; 70c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private PopupWindow mPopup; 71c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private ListAdapter mAdapter; 72c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private DropDownListView mDropDownList; 73c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 74c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private int mDropDownHeight = ViewGroup.LayoutParams.WRAP_CONTENT; 75c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private int mDropDownWidth = ViewGroup.LayoutParams.WRAP_CONTENT; 76c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private int mDropDownHorizontalOffset; 77c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private int mDropDownVerticalOffset; 788132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell private boolean mDropDownVerticalOffsetSet; 79c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 8054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell private int mDropDownGravity = Gravity.NO_GRAVITY; 8154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 82c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private boolean mDropDownAlwaysVisible = false; 83c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private boolean mForceIgnoreOutsideTouch = false; 84348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell int mListItemExpandMaximum = Integer.MAX_VALUE; 85c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 86c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private View mPromptView; 87c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private int mPromptPosition = POSITION_PROMPT_ABOVE; 88c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 89c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private DataSetObserver mObserver; 90c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 91c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private View mDropDownAnchorView; 92c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 93c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private Drawable mDropDownListHighlight; 94c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 95c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private AdapterView.OnItemClickListener mItemClickListener; 96c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private AdapterView.OnItemSelectedListener mItemSelectedListener; 97c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 984267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell private final ResizePopupRunnable mResizePopupRunnable = new ResizePopupRunnable(); 99c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private final PopupTouchInterceptor mTouchInterceptor = new PopupTouchInterceptor(); 100c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private final PopupScrollListener mScrollListener = new PopupScrollListener(); 101c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private final ListSelectorHider mHideSelector = new ListSelectorHider(); 102c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private Runnable mShowDropDownRunnable; 103c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 104c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private Handler mHandler = new Handler(); 105c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 106c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private Rect mTempRect = new Rect(); 107c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 108c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private boolean mModal; 109c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1101d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio private int mLayoutDirection; 1111d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio 112c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 113c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * The provided prompt view should appear above list content. 114c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 115c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setPromptPosition(int) 116c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #getPromptPosition() 117c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setPromptView(View) 118c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 119c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public static final int POSITION_PROMPT_ABOVE = 0; 120c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 121c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 122c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * The provided prompt view should appear below list content. 123c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 124c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setPromptPosition(int) 125c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #getPromptPosition() 126c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setPromptView(View) 127c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 128c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public static final int POSITION_PROMPT_BELOW = 1; 129c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 130c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 131c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Alias for {@link ViewGroup.LayoutParams#MATCH_PARENT}. 132c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * If used to specify a popup width, the popup will match the width of the anchor view. 133c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * If used to specify a popup height, the popup will fill available space. 134c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 135c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public static final int MATCH_PARENT = ViewGroup.LayoutParams.MATCH_PARENT; 136c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 137c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 138c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Alias for {@link ViewGroup.LayoutParams#WRAP_CONTENT}. 139c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * If used to specify a popup width, the popup will use the width of its content. 140c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 141c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public static final int WRAP_CONTENT = ViewGroup.LayoutParams.WRAP_CONTENT; 142c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 143c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 144c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Mode for {@link #setInputMethodMode(int)}: the requirements for the 145c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * input method should be based on the focusability of the popup. That is 146c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * if it is focusable than it needs to work with the input method, else 147c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * it doesn't. 148c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 149c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public static final int INPUT_METHOD_FROM_FOCUSABLE = PopupWindow.INPUT_METHOD_FROM_FOCUSABLE; 150c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 151c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 152c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Mode for {@link #setInputMethodMode(int)}: this popup always needs to 153c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * work with an input method, regardless of whether it is focusable. This 154c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * means that it will always be displayed so that the user can also operate 155c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * the input method while it is shown. 156c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 157c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public static final int INPUT_METHOD_NEEDED = PopupWindow.INPUT_METHOD_NEEDED; 158c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 159c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 160c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Mode for {@link #setInputMethodMode(int)}: this popup never needs to 161c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * work with an input method, regardless of whether it is focusable. This 162c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * means that it will always be displayed to use as much space on the 163c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * screen as needed, regardless of whether this covers the input method. 164c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 165c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public static final int INPUT_METHOD_NOT_NEEDED = PopupWindow.INPUT_METHOD_NOT_NEEDED; 166c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 167c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 168c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Create a new, empty popup window capable of displaying items from a ListAdapter. 169c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Backgrounds should be set using {@link #setBackgroundDrawable(Drawable)}. 170c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 171c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param context Context used for contained views. 172c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 173c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public ListPopupWindow(Context context) { 174c2238d006237ebf1296074d80fb4f4a2741ef880Daniel Lehmann this(context, null, com.android.internal.R.attr.listPopupWindowStyle, 0); 175c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 176c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 177c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 178c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Create a new, empty popup window capable of displaying items from a ListAdapter. 179c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Backgrounds should be set using {@link #setBackgroundDrawable(Drawable)}. 180c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 181c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param context Context used for contained views. 182c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param attrs Attributes from inflating parent views used to style the popup. 183c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 184c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public ListPopupWindow(Context context, AttributeSet attrs) { 1850b2d306e7000f4c0c6ad4e00d494bb401d8a9fc2Adam Powell this(context, attrs, com.android.internal.R.attr.listPopupWindowStyle, 0); 186c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 187c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 188c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 189c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Create a new, empty popup window capable of displaying items from a ListAdapter. 190c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Backgrounds should be set using {@link #setBackgroundDrawable(Drawable)}. 191c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 192c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param context Context used for contained views. 193c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param attrs Attributes from inflating parent views used to style the popup. 194c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param defStyleAttr Default style attribute to use for popup content. 195c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 196c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public ListPopupWindow(Context context, AttributeSet attrs, int defStyleAttr) { 197c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell this(context, attrs, defStyleAttr, 0); 198c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 199c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 200c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 201c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Create a new, empty popup window capable of displaying items from a ListAdapter. 202c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Backgrounds should be set using {@link #setBackgroundDrawable(Drawable)}. 203c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 204c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param context Context used for contained views. 205c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param attrs Attributes from inflating parent views used to style the popup. 206c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param defStyleAttr Style attribute to read for default styling of popup content. 207c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param defStyleRes Style resource ID to use for default styling of popup content. 208c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 209c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public ListPopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 210c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mContext = context; 211c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup = new PopupWindow(context, attrs, defStyleAttr, defStyleRes); 2126f5e934b96c400f610b1c5ad228cc60cab5d443fAdam Powell mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); 2131d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio // Set the default layout direction to match the default locale one 2141d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio final Locale locale = mContext.getResources().getConfiguration().locale; 215d3d9f3f1004dfee2649a26cfe8dba948cd364904Fabrice Di Meglio mLayoutDirection = TextUtils.getLayoutDirectionFromLocale(locale); 216c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 217c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 218c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 219c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets the adapter that provides the data and the views to represent the data 220c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * in this popup window. 221c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 222c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param adapter The adapter to use to create this window's content. 223c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 224c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setAdapter(ListAdapter adapter) { 225c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mObserver == null) { 226c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mObserver = new PopupDataSetObserver(); 227c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else if (mAdapter != null) { 22899969da3772d9a0f5079672847ca4f2ad819c1bbAdam Powell mAdapter.unregisterDataSetObserver(mObserver); 229c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 230c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mAdapter = adapter; 231c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mAdapter != null) { 232c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell adapter.registerDataSetObserver(mObserver); 233c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 234c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 235c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownList != null) { 236c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setAdapter(mAdapter); 237c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 238c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 239c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 240c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 241c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Set where the optional prompt view should appear. The default is 242c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * {@link #POSITION_PROMPT_ABOVE}. 243c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 244c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param position A position constant declaring where the prompt should be displayed. 245c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 246c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #POSITION_PROMPT_ABOVE 247c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #POSITION_PROMPT_BELOW 248c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 249c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setPromptPosition(int position) { 250c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPromptPosition = position; 251c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 252c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 253c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 254c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return Where the optional prompt view should appear. 255c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 256c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #POSITION_PROMPT_ABOVE 257c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #POSITION_PROMPT_BELOW 258c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 259c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getPromptPosition() { 260c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mPromptPosition; 261c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 262c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 263c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 264c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Set whether this window should be modal when shown. 265c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 266c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>If a popup window is modal, it will receive all touch and key input. 267c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * If the user touches outside the popup window's content area the popup window 268c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * will be dismissed. 269c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 270c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param modal {@code true} if the popup window should be modal, {@code false} otherwise. 271c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 272c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setModal(boolean modal) { 273c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mModal = true; 274c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setFocusable(modal); 275c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 276c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 277c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 278c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Returns whether the popup window will be modal when shown. 279c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 280c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return {@code true} if the popup window will be modal, {@code false} otherwise. 281c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 282c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean isModal() { 283c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mModal; 284c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 285c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 286c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 287c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Forces outside touches to be ignored. Normally if {@link #isDropDownAlwaysVisible()} is 288c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * false, we allow outside touch to dismiss the dropdown. If this is set to true, then we 289c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * ignore outside touch even when the drop down is not set to always visible. 290c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 291c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @hide Used only by AutoCompleteTextView to handle some internal special cases. 292c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 293c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setForceIgnoreOutsideTouch(boolean forceIgnoreOutsideTouch) { 294c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mForceIgnoreOutsideTouch = forceIgnoreOutsideTouch; 295c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 296c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 297c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 298c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets whether the drop-down should remain visible under certain conditions. 299c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 300c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * The drop-down will occupy the entire screen below {@link #getAnchorView} regardless 301c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * of the size or content of the list. {@link #getBackground()} will fill any space 302c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * that is not used by the list. 303c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 304c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param dropDownAlwaysVisible Whether to keep the drop-down visible. 305c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 306c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @hide Only used by AutoCompleteTextView under special conditions. 307c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 308c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setDropDownAlwaysVisible(boolean dropDownAlwaysVisible) { 309c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownAlwaysVisible = dropDownAlwaysVisible; 310c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 311c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 312c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 313c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return Whether the drop-down is visible under special conditions. 314c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 315c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @hide Only used by AutoCompleteTextView under special conditions. 316c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 317c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean isDropDownAlwaysVisible() { 318c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownAlwaysVisible; 319c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 320c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 321c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 322c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets the operating mode for the soft input area. 323c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 324c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param mode The desired mode, see 325c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * {@link android.view.WindowManager.LayoutParams#softInputMode} 326c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * for the full list 327c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 328c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see android.view.WindowManager.LayoutParams#softInputMode 329c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #getSoftInputMode() 330c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 331c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setSoftInputMode(int mode) { 332c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setSoftInputMode(mode); 333c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 334c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 335c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 336c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Returns the current value in {@link #setSoftInputMode(int)}. 337c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 338c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setSoftInputMode(int) 339c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see android.view.WindowManager.LayoutParams#softInputMode 340c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 341c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getSoftInputMode() { 342c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mPopup.getSoftInputMode(); 343c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 344c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 345c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 346c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets a drawable to use as the list item selector. 347c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 348c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param selector List selector drawable to use in the popup. 349c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 350c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setListSelector(Drawable selector) { 351c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownListHighlight = selector; 352c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 353c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 354c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 355c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The background drawable for the popup window. 356c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 357c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public Drawable getBackground() { 358c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mPopup.getBackground(); 359c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 360c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 361c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 362c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets a drawable to be the background for the popup window. 363c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 364c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param d A drawable to set as the background. 365c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 366c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setBackgroundDrawable(Drawable d) { 367c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setBackgroundDrawable(d); 368c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 369c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 370c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 371c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Set an animation style to use when the popup window is shown or dismissed. 372c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 373c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param animationStyle Animation style to use. 374c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 375c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setAnimationStyle(int animationStyle) { 376c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setAnimationStyle(animationStyle); 377c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 378c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 379c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 380c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Returns the animation style that will be used when the popup window is 381c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * shown or dismissed. 382c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 383c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return Animation style that will be used. 384c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 385c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getAnimationStyle() { 386c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mPopup.getAnimationStyle(); 387c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 388c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 389c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 390c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Returns the view that will be used to anchor this popup. 391c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 392c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The popup's anchor view 393c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 394c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public View getAnchorView() { 395c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownAnchorView; 396c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 397c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 398c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 399c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets the popup's anchor view. This popup will always be positioned relative to 400c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * the anchor view when shown. 401c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 402c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param anchor The view to use as an anchor. 403c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 404c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setAnchorView(View anchor) { 405c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownAnchorView = anchor; 406c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 407c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 408c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 409c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The horizontal offset of the popup from its anchor in pixels. 410c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 411c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getHorizontalOffset() { 412c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownHorizontalOffset; 413c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 414c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 415c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 416c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Set the horizontal offset of this popup from its anchor view in pixels. 417c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 418a984b38df5cfe6db0ba792bf2a6221f6b6072448Adam Powell * @param offset The horizontal offset of the popup from its anchor. 419c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 420c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setHorizontalOffset(int offset) { 421c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownHorizontalOffset = offset; 422c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 423c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 424c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 425c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The vertical offset of the popup from its anchor in pixels. 426c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 427c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getVerticalOffset() { 4288132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell if (!mDropDownVerticalOffsetSet) { 4298132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell return 0; 4308132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell } 431c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownVerticalOffset; 432c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 433c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 434c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 435c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Set the vertical offset of this popup from its anchor view in pixels. 436c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 437a984b38df5cfe6db0ba792bf2a6221f6b6072448Adam Powell * @param offset The vertical offset of the popup from its anchor. 438c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 439c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setVerticalOffset(int offset) { 440c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownVerticalOffset = offset; 4418132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell mDropDownVerticalOffsetSet = true; 442c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 443c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 444c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 44554c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * Set the gravity of the dropdown list. This is commonly used to 44654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * set gravity to START or END for alignment with the anchor. 44754c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * 44854c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell * @param gravity Gravity value to use 44954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell */ 45054c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell public void setDropDownGravity(int gravity) { 45154c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell mDropDownGravity = gravity; 45254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell } 45354c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell 45454c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell /** 455c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The width of the popup window in pixels. 456c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 457c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getWidth() { 458c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownWidth; 459c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 460c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 461c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 462c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets the width of the popup window in pixels. Can also be {@link #MATCH_PARENT} 463c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * or {@link #WRAP_CONTENT}. 464c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 465c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param width Width of the popup window. 466c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 467c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setWidth(int width) { 468c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownWidth = width; 469c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 470c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 471c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 4724267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell * Sets the width of the popup window by the size of its content. The final width may be 4734267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell * larger to accommodate styled window dressing. 4744267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell * 4754267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell * @param width Desired width of content in pixels. 4764267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell */ 4774267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell public void setContentWidth(int width) { 4784267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell Drawable popupBackground = mPopup.getBackground(); 4794267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell if (popupBackground != null) { 480a39b987bb761899636ae1e3669d1343499d04ebdAdam Powell popupBackground.getPadding(mTempRect); 481a39b987bb761899636ae1e3669d1343499d04ebdAdam Powell mDropDownWidth = mTempRect.left + mTempRect.right + width; 48262e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell } else { 48362e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell setWidth(width); 4844267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell } 4854267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell } 4864267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell 4874267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell /** 488c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The height of the popup window in pixels. 489c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 490c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getHeight() { 491c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownHeight; 492c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 493c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 494c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 495c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets the height of the popup window in pixels. Can also be {@link #MATCH_PARENT}. 496c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 497c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param height Height of the popup window. 498c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 499c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setHeight(int height) { 500c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownHeight = height; 501c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 502c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 503c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 504c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets a listener to receive events when a list item is clicked. 505c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 506c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param clickListener Listener to register 507c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 508c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see ListView#setOnItemClickListener(android.widget.AdapterView.OnItemClickListener) 509c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 510c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setOnItemClickListener(AdapterView.OnItemClickListener clickListener) { 511c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mItemClickListener = clickListener; 512c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 513c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 514c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 515c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets a listener to receive events when a list item is selected. 516c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 517c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param selectedListener Listener to register. 518c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 519c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see ListView#setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener) 520c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 521c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener selectedListener) { 522c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mItemSelectedListener = selectedListener; 523c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 524c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 525c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 526c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Set a view to act as a user prompt for this popup window. Where the prompt view will appear 527c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * is controlled by {@link #setPromptPosition(int)}. 528c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 529c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param prompt View to use as an informational prompt. 530c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 531c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setPromptView(View prompt) { 532c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell boolean showing = isShowing(); 533c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (showing) { 534c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell removePromptView(); 535c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 536c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPromptView = prompt; 537c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (showing) { 538c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell show(); 539c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 540c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 541c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 542c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 543c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Post a {@link #show()} call to the UI thread. 544c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 545c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void postShow() { 546c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mHandler.post(mShowDropDownRunnable); 547c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 548c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 549c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 550c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Show the popup list. If the list is already showing, this method 551c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * will recalculate the popup's size and position. 552c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 553c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void show() { 554c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int height = buildDropDown(); 555c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 556c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int widthSpec = 0; 557c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int heightSpec = 0; 558c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 559c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell boolean noInputMethod = isInputMethodNotNeeded(); 560348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell mPopup.setAllowScrollingAnchorParent(!noInputMethod); 561c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 562c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mPopup.isShowing()) { 563c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT) { 564c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // The call to PopupWindow's update method below can accept -1 for any 565c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // value you do not want to update. 566c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell widthSpec = -1; 567c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) { 568c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell widthSpec = getAnchorView().getWidth(); 569c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 570c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell widthSpec = mDropDownWidth; 571c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 572c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 573c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) { 574c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // The call to PopupWindow's update method below can accept -1 for any 575c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // value you do not want to update. 576c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell heightSpec = noInputMethod ? height : ViewGroup.LayoutParams.MATCH_PARENT; 577c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (noInputMethod) { 578c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setWindowLayoutMode( 579c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT ? 580c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell ViewGroup.LayoutParams.MATCH_PARENT : 0, 0); 581c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 582c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setWindowLayoutMode( 583c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT ? 584c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell ViewGroup.LayoutParams.MATCH_PARENT : 0, 585c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell ViewGroup.LayoutParams.MATCH_PARENT); 586c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 587c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) { 588c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell heightSpec = height; 589c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 590c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell heightSpec = mDropDownHeight; 591c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 592c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 593c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch && !mDropDownAlwaysVisible); 594c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 595c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.update(getAnchorView(), mDropDownHorizontalOffset, 596c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownVerticalOffset, widthSpec, heightSpec); 597c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 598c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT) { 599c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell widthSpec = ViewGroup.LayoutParams.MATCH_PARENT; 600c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 601c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) { 602c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setWidth(getAnchorView().getWidth()); 603c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 604c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setWidth(mDropDownWidth); 605c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 606c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 607c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 608c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) { 609c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell heightSpec = ViewGroup.LayoutParams.MATCH_PARENT; 610c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 611c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) { 612c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setHeight(height); 613c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 614c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setHeight(mDropDownHeight); 615c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 616c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 617c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 618c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setWindowLayoutMode(widthSpec, heightSpec); 61956c2d337e02a275397fc9d0460dca90977f199acAdam Powell mPopup.setClipToScreenEnabled(true); 620c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 621c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // use outside touchable to dismiss drop down when touching outside of it, so 622c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // only set this if the dropdown is not always visible 623c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch && !mDropDownAlwaysVisible); 624c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setTouchInterceptor(mTouchInterceptor); 625c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.showAsDropDown(getAnchorView(), 62654c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell mDropDownHorizontalOffset, mDropDownVerticalOffset, mDropDownGravity); 627c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setSelection(ListView.INVALID_POSITION); 628c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 629c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (!mModal || mDropDownList.isInTouchMode()) { 630c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell clearListSelection(); 631c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 632c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (!mModal) { 633c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mHandler.post(mHideSelector); 634c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 635c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 636c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 637c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 638c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 639c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Dismiss the popup window. 640c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 641c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void dismiss() { 642c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.dismiss(); 643c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell removePromptView(); 644c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setContentView(null); 645c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList = null; 646ca51e8788a58f2af3525b7214a675f2d0233e5daAdam Powell mHandler.removeCallbacks(mResizePopupRunnable); 647c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 648c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 6496c6f575423d6718c3ff322224c1520901ce881e1Adam Powell /** 6506c6f575423d6718c3ff322224c1520901ce881e1Adam Powell * Set a listener to receive a callback when the popup is dismissed. 6516c6f575423d6718c3ff322224c1520901ce881e1Adam Powell * 6526c6f575423d6718c3ff322224c1520901ce881e1Adam Powell * @param listener Listener that will be notified when the popup is dismissed. 6536c6f575423d6718c3ff322224c1520901ce881e1Adam Powell */ 6546c6f575423d6718c3ff322224c1520901ce881e1Adam Powell public void setOnDismissListener(PopupWindow.OnDismissListener listener) { 6556c6f575423d6718c3ff322224c1520901ce881e1Adam Powell mPopup.setOnDismissListener(listener); 6566c6f575423d6718c3ff322224c1520901ce881e1Adam Powell } 6576c6f575423d6718c3ff322224c1520901ce881e1Adam Powell 658c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private void removePromptView() { 659c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mPromptView != null) { 660c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final ViewParent parent = mPromptView.getParent(); 661c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (parent instanceof ViewGroup) { 662c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final ViewGroup group = (ViewGroup) parent; 663c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell group.removeView(mPromptView); 664c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 665c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 666c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 667c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 668c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 669c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Control how the popup operates with an input method: one of 670c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * {@link #INPUT_METHOD_FROM_FOCUSABLE}, {@link #INPUT_METHOD_NEEDED}, 671c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * or {@link #INPUT_METHOD_NOT_NEEDED}. 672c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 673c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>If the popup is showing, calling this method will take effect only 674c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * the next time the popup is shown or through a manual call to the {@link #show()} 675c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * method.</p> 676c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 677c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #getInputMethodMode() 678c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #show() 679c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 680c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setInputMethodMode(int mode) { 681c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setInputMethodMode(mode); 682c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 683c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 684c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 685c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Return the current value in {@link #setInputMethodMode(int)}. 686c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 687c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setInputMethodMode(int) 688c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 689c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getInputMethodMode() { 690c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mPopup.getInputMethodMode(); 691c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 692c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 693c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 694c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Set the selected position of the list. 695c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Only valid when {@link #isShowing()} == {@code true}. 696c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 697c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param position List position to set as selected. 698c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 699c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setSelection(int position) { 700c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell DropDownListView list = mDropDownList; 701c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (isShowing() && list != null) { 702c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell list.mListSelectionHidden = false; 703c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell list.setSelection(position); 704c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (list.getChoiceMode() != ListView.CHOICE_MODE_NONE) { 705c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell list.setItemChecked(position, true); 706c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 707c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 708c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 709c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 710c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 711c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Clear any current list selection. 712c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Only valid when {@link #isShowing()} == {@code true}. 713c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 714c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void clearListSelection() { 715c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final DropDownListView list = mDropDownList; 716c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (list != null) { 717c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // WARNING: Please read the comment where mListSelectionHidden is declared 718c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell list.mListSelectionHidden = true; 719c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell list.hideSelector(); 720c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell list.requestLayout(); 721c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 722c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 723c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 724c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 725c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return {@code true} if the popup is currently showing, {@code false} otherwise. 726c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 727c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean isShowing() { 728c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mPopup.isShowing(); 729c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 730c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 731c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 732c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return {@code true} if this popup is configured to assume the user does not need 733c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * to interact with the IME while it is showing, {@code false} otherwise. 734c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 735c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean isInputMethodNotNeeded() { 736c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mPopup.getInputMethodMode() == INPUT_METHOD_NOT_NEEDED; 737c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 738c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 739c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 740c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Perform an item click operation on the specified list adapter position. 741c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 742c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param position Adapter position for performing the click 743c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return true if the click action could be performed, false if not. 744c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * (e.g. if the popup was not showing, this method would return false.) 745c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 746c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean performItemClick(int position) { 747c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (isShowing()) { 748c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mItemClickListener != null) { 749c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final DropDownListView list = mDropDownList; 750c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final View child = list.getChildAt(position - list.getFirstVisiblePosition()); 751cdee446075811e871fc2af295377bd99c100d16dAdam Powell final ListAdapter adapter = list.getAdapter(); 752cdee446075811e871fc2af295377bd99c100d16dAdam Powell mItemClickListener.onItemClick(list, child, position, adapter.getItemId(position)); 753c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 754c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return true; 755c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 756c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return false; 757c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 758c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 759c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 760c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The currently selected item or null if the popup is not showing. 761c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 762c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public Object getSelectedItem() { 763c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (!isShowing()) { 764c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return null; 765c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 766c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownList.getSelectedItem(); 767c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 768c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 769c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 770c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The position of the currently selected item or {@link ListView#INVALID_POSITION} 771c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * if {@link #isShowing()} == {@code false}. 772c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 773c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see ListView#getSelectedItemPosition() 774c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 775c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getSelectedItemPosition() { 776c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (!isShowing()) { 777c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return ListView.INVALID_POSITION; 778c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 779c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownList.getSelectedItemPosition(); 780c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 781c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 782c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 783c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The ID of the currently selected item or {@link ListView#INVALID_ROW_ID} 784c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * if {@link #isShowing()} == {@code false}. 785c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 786c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see ListView#getSelectedItemId() 787c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 788c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public long getSelectedItemId() { 789c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (!isShowing()) { 790c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return ListView.INVALID_ROW_ID; 791c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 792c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownList.getSelectedItemId(); 793c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 794c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 795c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 796c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The View for the currently selected item or null if 797c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * {@link #isShowing()} == {@code false}. 798c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 799c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see ListView#getSelectedView() 800c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 801c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public View getSelectedView() { 802c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (!isShowing()) { 803c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return null; 804c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 805c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownList.getSelectedView(); 806c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 807c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 808c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 809c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The {@link ListView} displayed within the popup window. 810c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Only valid when {@link #isShowing()} == {@code true}. 811c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 812c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public ListView getListView() { 813c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownList; 814c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 815c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 816c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 817348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * The maximum number of list items that can be visible and still have 818348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * the list expand when touched. 819348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * 820348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * @param max Max number of items that can be visible and still allow the list to expand. 821348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell */ 822348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell void setListItemExpandMax(int max) { 823348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell mListItemExpandMaximum = max; 824348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell } 825348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell 826348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell /** 8278d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown * Filter key down events. By forwarding key down events to this function, 828c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * views using non-modal ListPopupWindow can have it handle key selection of items. 829c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 830c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param keyCode keyCode param passed to the host view's onKeyDown 831c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param event event param passed to the host view's onKeyDown 832c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return true if the event was handled, false if it was ignored. 833c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 834c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setModal(boolean) 835c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 836c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean onKeyDown(int keyCode, KeyEvent event) { 837c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // when the drop down is shown, we drive it directly 838c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (isShowing()) { 839c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // the key events are forwarded to the list in the drop down view 840c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // note that ListView handles space but we don't want that to happen 841c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // also if selection is not currently in the drop down, then don't 842c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // let center or enter presses go there since that would cause it 843c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // to select one of its items 844c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (keyCode != KeyEvent.KEYCODE_SPACE 845c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell && (mDropDownList.getSelectedItemPosition() >= 0 84624d36f592224d1316165f579bb0937df0bf42f7cMichael Wright || !KeyEvent.isConfirmKey(keyCode))) { 847c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int curIndex = mDropDownList.getSelectedItemPosition(); 848c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell boolean consumed; 849c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 850c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final boolean below = !mPopup.isAboveAnchor(); 851c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 852c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final ListAdapter adapter = mAdapter; 853c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 854c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell boolean allEnabled; 855c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int firstItem = Integer.MAX_VALUE; 856c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int lastItem = Integer.MIN_VALUE; 857c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 858c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (adapter != null) { 859c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell allEnabled = adapter.areAllItemsEnabled(); 860c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell firstItem = allEnabled ? 0 : 861c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.lookForSelectablePosition(0, true); 862c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell lastItem = allEnabled ? adapter.getCount() - 1 : 863c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.lookForSelectablePosition(adapter.getCount() - 1, false); 864c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 865c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 866c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if ((below && keyCode == KeyEvent.KEYCODE_DPAD_UP && curIndex <= firstItem) || 867c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell (!below && keyCode == KeyEvent.KEYCODE_DPAD_DOWN && curIndex >= lastItem)) { 868c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // When the selection is at the top, we block the key 869c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // event to prevent focus from moving. 870c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell clearListSelection(); 871c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); 872c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell show(); 873c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return true; 874c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 875c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // WARNING: Please read the comment where mListSelectionHidden 876c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // is declared 877c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.mListSelectionHidden = false; 878c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 879c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 880c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell consumed = mDropDownList.onKeyDown(keyCode, event); 881c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (DEBUG) Log.v(TAG, "Key down: code=" + keyCode + " list consumed=" + consumed); 882c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 883c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (consumed) { 884c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // If it handled the key event, then the user is 885c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // navigating in the list, so we should put it in front. 886c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); 887c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // Here's a little trick we need to do to make sure that 888c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // the list view is actually showing its focus indicator, 889c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // by ensuring it has focus and getting its window out 890c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // of touch mode. 891c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.requestFocusFromTouch(); 892c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell show(); 893c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 894c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell switch (keyCode) { 895c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // avoid passing the focus from the text view to the 896c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // next component 897c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell case KeyEvent.KEYCODE_ENTER: 898c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell case KeyEvent.KEYCODE_DPAD_CENTER: 899c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell case KeyEvent.KEYCODE_DPAD_DOWN: 900c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell case KeyEvent.KEYCODE_DPAD_UP: 901c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return true; 902c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 903c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 904c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (below && keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { 905c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // when the selection is at the bottom, we block the 906c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // event to avoid going to the next focusable widget 907c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (curIndex == lastItem) { 908c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return true; 909c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 910c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else if (!below && keyCode == KeyEvent.KEYCODE_DPAD_UP && 911c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell curIndex == firstItem) { 912c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return true; 913c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 914c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 915c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 916c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 917c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 918c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return false; 919c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 920c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 921c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 922c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Filter key down events. By forwarding key up events to this function, 923c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * views using non-modal ListPopupWindow can have it handle key selection of items. 924c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 925c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param keyCode keyCode param passed to the host view's onKeyUp 926c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param event event param passed to the host view's onKeyUp 927c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return true if the event was handled, false if it was ignored. 928c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 929c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setModal(boolean) 930c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 931c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean onKeyUp(int keyCode, KeyEvent event) { 932c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (isShowing() && mDropDownList.getSelectedItemPosition() >= 0) { 933c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell boolean consumed = mDropDownList.onKeyUp(keyCode, event); 93424d36f592224d1316165f579bb0937df0bf42f7cMichael Wright if (consumed && KeyEvent.isConfirmKey(keyCode)) { 93524d36f592224d1316165f579bb0937df0bf42f7cMichael Wright // if the list accepts the key events and the key event was a click, the text view 93624d36f592224d1316165f579bb0937df0bf42f7cMichael Wright // gets the selected item from the drop down as its content 93724d36f592224d1316165f579bb0937df0bf42f7cMichael Wright dismiss(); 938c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 939c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return consumed; 940c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 941c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return false; 942c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 943c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 944c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 945c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Filter pre-IME key events. By forwarding {@link View#onKeyPreIme(int, KeyEvent)} 946c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * events to this function, views using ListPopupWindow can have it dismiss the popup 947c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * when the back key is pressed. 948c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 949c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param keyCode keyCode param passed to the host view's onKeyPreIme 950c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param event event param passed to the host view's onKeyPreIme 951c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return true if the event was handled, false if it was ignored. 952c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 953c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setModal(boolean) 954c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 955c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean onKeyPreIme(int keyCode, KeyEvent event) { 956c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (keyCode == KeyEvent.KEYCODE_BACK && isShowing()) { 957c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // special case for the back key, we do not even try to send it 958c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // to the drop down list but instead, consume it immediately 959c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final View anchorView = mDropDownAnchorView; 960c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { 961b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown KeyEvent.DispatcherState state = anchorView.getKeyDispatcherState(); 962b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown if (state != null) { 963b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown state.startTracking(event, this); 964b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } 965c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return true; 966c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else if (event.getAction() == KeyEvent.ACTION_UP) { 967b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown KeyEvent.DispatcherState state = anchorView.getKeyDispatcherState(); 968b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown if (state != null) { 969b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown state.handleUpEvent(event); 970b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } 971c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (event.isTracking() && !event.isCanceled()) { 972c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell dismiss(); 973c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return true; 974c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 975c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 976c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 977c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return false; 978c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 979c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 980c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 9811955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * Returns an {@link OnTouchListener} that can be added to the source view 9821955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * to implement drag-to-open behavior. Generally, the source view should be 9831955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * the same view that was passed to {@link #setAnchorView}. 9841955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * <p> 9851955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * When the listener is set on a view, touching that view and dragging 9861955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * outside of its bounds will open the popup window. Lifting will select the 9871955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * currently touched list item. 9881955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * <p> 9891955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * Example usage: 9903f9832d3c7b30bf4dc8ed9e5123b02daca96c878Alan Viverette * <pre> 9913f9832d3c7b30bf4dc8ed9e5123b02daca96c878Alan Viverette * ListPopupWindow myPopup = new ListPopupWindow(context); 9921955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * myPopup.setAnchor(myAnchor); 9931955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * OnTouchListener dragListener = myPopup.createDragToOpenListener(myAnchor); 9943f9832d3c7b30bf4dc8ed9e5123b02daca96c878Alan Viverette * myAnchor.setOnTouchListener(dragListener); 9953f9832d3c7b30bf4dc8ed9e5123b02daca96c878Alan Viverette * </pre> 9961955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * 9971955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * @param src the view on which the resulting listener will be set 9981955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette * @return a touch listener that controls drag-to-open behavior 9991955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette */ 10001955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette public OnTouchListener createDragToOpenListener(View src) { 10011955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette return new ForwardingListener(src) { 10021955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette @Override 10031955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette public ListPopupWindow getPopup() { 10041955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette return ListPopupWindow.this; 10051955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette } 10061955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette }; 10071955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette } 10081955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette 10091955a5b531f03dec90f285b590ef62e3d632783cAlan Viverette /** 1010c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>Builds the popup window's content and returns the height the popup 1011c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * should have. Returns -1 when the content already exists.</p> 1012c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 1013c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return the content's height or -1 if content already exists 1014c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 1015c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private int buildDropDown() { 1016c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell ViewGroup dropDownView; 1017c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int otherHeights = 0; 1018c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1019c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownList == null) { 1020c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell Context context = mContext; 1021c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1022c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 1023c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * This Runnable exists for the sole purpose of checking if the view layout has got 1024c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * completed and if so call showDropDown to display the drop down. This is used to show 1025c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * the drop down as soon as possible after user opens up the search dialog, without 1026c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * waiting for the normal UI pipeline to do it's job which is slower than this method. 1027c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 1028c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mShowDropDownRunnable = new Runnable() { 1029c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void run() { 1030c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // View layout should be all done before displaying the drop down. 1031c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell View view = getAnchorView(); 1032c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (view != null && view.getWindowToken() != null) { 1033c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell show(); 1034c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1035c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1036c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell }; 1037c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1038c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList = new DropDownListView(context, !mModal); 1039c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownListHighlight != null) { 1040c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setSelector(mDropDownListHighlight); 1041c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1042c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setAdapter(mAdapter); 1043c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setOnItemClickListener(mItemClickListener); 1044c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setFocusable(true); 1045c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setFocusableInTouchMode(true); 1046c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 1047c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void onItemSelected(AdapterView<?> parent, View view, 1048c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int position, long id) { 1049c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1050c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (position != -1) { 1051c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell DropDownListView dropDownList = mDropDownList; 1052c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1053c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (dropDownList != null) { 1054c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell dropDownList.mListSelectionHidden = false; 1055c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1056c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1057c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1058c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1059c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void onNothingSelected(AdapterView<?> parent) { 1060c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1061c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell }); 1062c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setOnScrollListener(mScrollListener); 1063c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1064c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mItemSelectedListener != null) { 1065c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setOnItemSelectedListener(mItemSelectedListener); 1066c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1067c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1068c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell dropDownView = mDropDownList; 1069c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1070c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell View hintView = mPromptView; 1071c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (hintView != null) { 1072f76a50ce8fdc6aea22cabc77b2977a1a15a79630Ken Wakasa // if a hint has been specified, we accomodate more space for it and 1073c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // add a text view in the drop down menu, at the bottom of the list 1074c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell LinearLayout hintContainer = new LinearLayout(context); 1075c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell hintContainer.setOrientation(LinearLayout.VERTICAL); 1076c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1077c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell LinearLayout.LayoutParams hintParams = new LinearLayout.LayoutParams( 1078c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell ViewGroup.LayoutParams.MATCH_PARENT, 0, 1.0f 1079c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell ); 1080c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1081c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell switch (mPromptPosition) { 1082c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell case POSITION_PROMPT_BELOW: 1083c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell hintContainer.addView(dropDownView, hintParams); 1084c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell hintContainer.addView(hintView); 1085c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell break; 1086c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1087c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell case POSITION_PROMPT_ABOVE: 1088c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell hintContainer.addView(hintView); 1089c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell hintContainer.addView(dropDownView, hintParams); 1090c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell break; 1091c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1092c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell default: 1093c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell Log.e(TAG, "Invalid hint position " + mPromptPosition); 1094c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell break; 1095c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1096c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1097c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // measure the hint's height to find how much more vertical space 1098c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // we need to add to the drop down's height 1099c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int widthSpec = MeasureSpec.makeMeasureSpec(mDropDownWidth, MeasureSpec.AT_MOST); 1100c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int heightSpec = MeasureSpec.UNSPECIFIED; 1101c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell hintView.measure(widthSpec, heightSpec); 1102c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1103c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell hintParams = (LinearLayout.LayoutParams) hintView.getLayoutParams(); 1104c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell otherHeights = hintView.getMeasuredHeight() + hintParams.topMargin 1105c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell + hintParams.bottomMargin; 1106c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1107c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell dropDownView = hintContainer; 1108c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1109c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1110c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setContentView(dropDownView); 1111c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 1112c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell dropDownView = (ViewGroup) mPopup.getContentView(); 1113c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final View view = mPromptView; 1114c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (view != null) { 1115c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell LinearLayout.LayoutParams hintParams = 1116c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell (LinearLayout.LayoutParams) view.getLayoutParams(); 1117c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell otherHeights = view.getMeasuredHeight() + hintParams.topMargin 1118c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell + hintParams.bottomMargin; 1119c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1120c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1121c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 11228132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell // getMaxAvailableHeight() subtracts the padding, so we put it back 1123c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // to get the available height for the whole window 1124c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int padding = 0; 1125c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell Drawable background = mPopup.getBackground(); 1126c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (background != null) { 1127c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell background.getPadding(mTempRect); 1128c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell padding = mTempRect.top + mTempRect.bottom; 11298132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell 11308132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell // If we don't have an explicit vertical offset, determine one from the window 11318132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell // background so that content will line up. 11328132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell if (!mDropDownVerticalOffsetSet) { 11338132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell mDropDownVerticalOffset = -mTempRect.top; 11348132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell } 11357507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell } else { 11367507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell mTempRect.setEmpty(); 1137c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1138c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 11398132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell // Max height available on the screen for a popup. 11408132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell boolean ignoreBottomDecorations = 11418132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED; 11428132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell final int maxHeight = mPopup.getMaxAvailableHeight( 11438132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell getAnchorView(), mDropDownVerticalOffset, ignoreBottomDecorations); 11448132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell 1145c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownAlwaysVisible || mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) { 1146c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return maxHeight + padding; 1147c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1148c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 11497507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell final int childWidthSpec; 11507507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell switch (mDropDownWidth) { 11517507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell case ViewGroup.LayoutParams.WRAP_CONTENT: 11527507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell childWidthSpec = MeasureSpec.makeMeasureSpec( 11537507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell mContext.getResources().getDisplayMetrics().widthPixels - 11547507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell (mTempRect.left + mTempRect.right), 11557507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell MeasureSpec.AT_MOST); 11567507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell break; 11577507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell case ViewGroup.LayoutParams.MATCH_PARENT: 11587507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell childWidthSpec = MeasureSpec.makeMeasureSpec( 11597507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell mContext.getResources().getDisplayMetrics().widthPixels - 11607507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell (mTempRect.left + mTempRect.right), 11617507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell MeasureSpec.EXACTLY); 11627507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell break; 11637507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell default: 11647507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell childWidthSpec = MeasureSpec.makeMeasureSpec(mDropDownWidth, MeasureSpec.EXACTLY); 11657507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell break; 11667507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell } 11677507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell final int listContent = mDropDownList.measureHeightOfChildren(childWidthSpec, 1168a7845ed44a3722e7d96ca9b677be213da7e8c8feAdam Powell 0, ListView.NO_POSITION, maxHeight - otherHeights, -1); 1169c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // add padding only if the list has items in it, that way we don't show 1170c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // the popup if it is not needed 1171c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (listContent > 0) otherHeights += padding; 1172c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1173c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return listContent + otherHeights; 1174c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1175c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 11761d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio /** 1177ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * Abstract class that forwards touch events to a {@link ListPopupWindow}. 1178ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * 1179ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * @hide 1180ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette */ 118169960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette public static abstract class ForwardingListener 118269960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette implements View.OnTouchListener, View.OnAttachStateChangeListener { 1183ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette /** Scaled touch slop, used for detecting movement outside bounds. */ 1184ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette private final float mScaledTouchSlop; 1185ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette 118669960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette /** Timeout before disallowing intercept on the source's parent. */ 118769960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette private final int mTapTimeout; 118869960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette 118969960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette /** Source view from which events are forwarded. */ 119069960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette private final View mSrc; 119169960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette 119269960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette /** Runnable used to prevent conflicts with scrolling parents. */ 119369960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette private Runnable mDisallowIntercept; 119469960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette 1195ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette /** Whether this listener is currently forwarding touch events. */ 1196ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette private boolean mForwarding; 1197ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette 1198ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette /** The id of the first pointer down in the current event stream. */ 1199ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette private int mActivePointerId; 1200ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette 120169960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette public ForwardingListener(View src) { 120269960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette mSrc = src; 120369960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette mScaledTouchSlop = ViewConfiguration.get(src.getContext()).getScaledTouchSlop(); 120469960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette mTapTimeout = ViewConfiguration.getTapTimeout(); 120569960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette 120669960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette src.addOnAttachStateChangeListener(this); 1207ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette } 1208ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette 1209ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette /** 1210ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * Returns the popup to which this listener is forwarding events. 1211ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * <p> 1212ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * Override this to return the correct popup. If the popup is displayed 1213ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * asynchronously, you may also need to override 1214ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * {@link #onForwardingStopped} to prevent premature cancelation of 1215ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * forwarding. 1216ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * 1217ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * @return the popup to which this listener is forwarding events 1218ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette */ 1219ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette public abstract ListPopupWindow getPopup(); 1220ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette 1221ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette @Override 1222ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette public boolean onTouch(View v, MotionEvent event) { 1223ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette final boolean wasForwarding = mForwarding; 1224ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette final boolean forwarding; 1225ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette if (wasForwarding) { 122669960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette forwarding = onTouchForwarded(event) || !onForwardingStopped(); 1227ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette } else { 122869960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette forwarding = onTouchObserved(event) && onForwardingStarted(); 1229ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette } 1230ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette 1231ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette mForwarding = forwarding; 1232ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette return forwarding || wasForwarding; 1233ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette } 1234ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette 123569960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette @Override 123669960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette public void onViewAttachedToWindow(View v) { 123769960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette } 123869960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette 123969960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette @Override 124069960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette public void onViewDetachedFromWindow(View v) { 124169960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette mForwarding = false; 124269960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette mActivePointerId = MotionEvent.INVALID_POINTER_ID; 124369960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette 124469960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette if (mDisallowIntercept != null) { 124569960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette mSrc.removeCallbacks(mDisallowIntercept); 124669960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette } 124769960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette } 124869960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette 1249ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette /** 1250ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * Called when forwarding would like to start. 1251ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * <p> 1252ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * By default, this will show the popup returned by {@link #getPopup()}. 1253ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * It may be overridden to perform another action, like clicking the 1254ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * source view or preparing the popup before showing it. 1255ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * 1256ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * @return true to start forwarding, false otherwise 1257ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette */ 125869960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette protected boolean onForwardingStarted() { 1259ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette final ListPopupWindow popup = getPopup(); 1260ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette if (popup != null && !popup.isShowing()) { 1261ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette popup.show(); 1262ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette } 1263ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette return true; 1264ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette } 1265ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette 1266ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette /** 1267ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * Called when forwarding would like to stop. 1268ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * <p> 1269ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * By default, this will dismiss the popup returned by 1270ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * {@link #getPopup()}. It may be overridden to perform some other 1271ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * action. 1272ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * 1273ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * @return true to stop forwarding, false otherwise 1274ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette */ 127569960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette protected boolean onForwardingStopped() { 1276ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette final ListPopupWindow popup = getPopup(); 1277ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette if (popup != null && popup.isShowing()) { 1278ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette popup.dismiss(); 1279ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette } 1280ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette return true; 1281ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette } 1282ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette 1283ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette /** 1284ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * Observes motion events and determines when to start forwarding. 1285ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * 1286ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * @param srcEvent motion event in source view coordinates 1287ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * @return true to start forwarding motion events, false otherwise 1288ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette */ 128969960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette private boolean onTouchObserved(MotionEvent srcEvent) { 129069960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette final View src = mSrc; 1291ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette if (!src.isEnabled()) { 1292ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette return false; 1293ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette } 1294ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette 1295ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette final int actionMasked = srcEvent.getActionMasked(); 129669960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette switch (actionMasked) { 129769960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette case MotionEvent.ACTION_DOWN: 129869960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette mActivePointerId = srcEvent.getPointerId(0); 129969960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette if (mDisallowIntercept == null) { 130069960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette mDisallowIntercept = new DisallowIntercept(); 130169960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette } 130269960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette src.postDelayed(mDisallowIntercept, mTapTimeout); 130369960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette break; 130469960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette case MotionEvent.ACTION_MOVE: 130569960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette final int activePointerIndex = srcEvent.findPointerIndex(mActivePointerId); 130669960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette if (activePointerIndex >= 0) { 130769960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette final float x = srcEvent.getX(activePointerIndex); 130869960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette final float y = srcEvent.getY(activePointerIndex); 130969960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette if (!src.pointInView(x, y, mScaledTouchSlop)) { 131069960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette // The pointer has moved outside of the view. 131169960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette if (mDisallowIntercept != null) { 131269960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette src.removeCallbacks(mDisallowIntercept); 131369960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette } 131469960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette src.getParent().requestDisallowInterceptTouchEvent(true); 131569960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette return true; 131669960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette } 131769960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette } 131869960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette break; 131969960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette case MotionEvent.ACTION_CANCEL: 132069960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette case MotionEvent.ACTION_UP: 132169960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette if (mDisallowIntercept != null) { 132269960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette src.removeCallbacks(mDisallowIntercept); 132369960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette } 132469960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette break; 1325ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette } 1326ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette 1327ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette return false; 1328ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette } 1329ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette 1330ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette /** 1331ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * Handled forwarded motion events and determines when to stop 1332ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * forwarding. 1333ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * 1334ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * @param srcEvent motion event in source view coordinates 1335ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette * @return true to continue forwarding motion events, false to cancel 1336ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette */ 133769960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette private boolean onTouchForwarded(MotionEvent srcEvent) { 133869960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette final View src = mSrc; 1339ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette final ListPopupWindow popup = getPopup(); 1340ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette if (popup == null || !popup.isShowing()) { 1341ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette return false; 1342ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette } 1343ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette 1344ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette final DropDownListView dst = popup.mDropDownList; 1345ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette if (dst == null || !dst.isShown()) { 1346ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette return false; 1347ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette } 1348ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette 1349ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette // Convert event to destination-local coordinates. 1350ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette final MotionEvent dstEvent = MotionEvent.obtainNoHistory(srcEvent); 1351ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette src.toGlobalMotionEvent(dstEvent); 1352ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette dst.toLocalMotionEvent(dstEvent); 1353ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette 1354ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette // Forward converted event to destination view, then recycle it. 1355ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette final boolean handled = dst.onForwardedEvent(dstEvent, mActivePointerId); 1356ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette dstEvent.recycle(); 1357ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette return handled; 1358ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette } 135969960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette 136069960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette private class DisallowIntercept implements Runnable { 136169960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette @Override 136269960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette public void run() { 136369960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette final ViewParent parent = mSrc.getParent(); 136469960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette parent.requestDisallowInterceptTouchEvent(true); 136569960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette } 136669960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette } 1367ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette } 1368ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette 1369ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette /** 1370c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>Wrapper class for a ListView. This wrapper can hijack the focus to 1371c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * make sure the list uses the appropriate drawables and states when 1372c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * displayed on screen within a drop down. The focus is never actually 1373c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * passed to the drop down in this mode; the list only looks focused.</p> 1374c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 1375c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private static class DropDownListView extends ListView { 1376c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette /** Duration in milliseconds of the drag-to-open click animation. */ 1377c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette private static final long CLICK_ANIM_DURATION = 150; 1378c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette 1379c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette /** Target alpha value for drag-to-open click animation. */ 1380c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette private static final int CLICK_ANIM_ALPHA = 0x80; 1381c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette 1382c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette /** Wrapper around Drawable's <code>alpha</code> property. */ 1383c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette private static final IntProperty<Drawable> DRAWABLE_ALPHA = 1384c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette new IntProperty<Drawable>("alpha") { 1385c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette @Override 1386c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette public void setValue(Drawable object, int value) { 1387c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette object.setAlpha(value); 1388c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette } 1389c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette 1390c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette @Override 1391c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette public Integer get(Drawable object) { 1392c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette return object.getAlpha(); 1393c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette } 1394c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette }; 1395c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette 1396c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /* 1397c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * WARNING: This is a workaround for a touch mode issue. 1398c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 1399c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Touch mode is propagated lazily to windows. This causes problems in 1400c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * the following scenario: 1401c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * - Type something in the AutoCompleteTextView and get some results 1402c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * - Move down with the d-pad to select an item in the list 1403c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * - Move up with the d-pad until the selection disappears 1404c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * - Type more text in the AutoCompleteTextView *using the soft keyboard* 1405c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * and get new results; you are now in touch mode 1406c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * - The selection comes back on the first item in the list, even though 1407c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * the list is supposed to be in touch mode 1408c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 1409c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Using the soft keyboard triggers the touch mode change but that change 1410c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * is propagated to our window only after the first list layout, therefore 1411c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * after the list attempts to resurrect the selection. 1412c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 1413c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * The trick to work around this issue is to pretend the list is in touch 1414c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * mode when we know that the selection should not appear, that is when 1415c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * we know the user moved the selection away from the list. 1416c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 1417c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * This boolean is set to true whenever we explicitly hide the list's 1418c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * selection and reset to false whenever we know the user moved the 1419c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * selection back to the list. 1420c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 1421c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * When this boolean is true, isInTouchMode() returns true, otherwise it 1422c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * returns super.isInTouchMode(). 1423c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 1424c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private boolean mListSelectionHidden; 1425c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1426c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 1427c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * True if this wrapper should fake focus. 1428c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 1429c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private boolean mHijackFocus; 1430c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1431c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette /** Whether to force drawing of the pressed state selector. */ 1432c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette private boolean mDrawsInPressedState; 1433c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette 1434c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette /** Current drag-to-open click animation, if any. */ 1435c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette private Animator mClickAnimation; 1436c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette 14375e66021c8a24c27c470cc6b9fe49e5653f3fa05dAlan Viverette /** Helper for drag-to-open auto scrolling. */ 14385e66021c8a24c27c470cc6b9fe49e5653f3fa05dAlan Viverette private AbsListViewAutoScroller mScrollHelper; 14395e66021c8a24c27c470cc6b9fe49e5653f3fa05dAlan Viverette 1440c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 1441c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>Creates a new list view wrapper.</p> 1442c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 1443c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param context this view's context 1444c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 1445c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public DropDownListView(Context context, boolean hijackFocus) { 1446c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell super(context, null, com.android.internal.R.attr.dropDownListViewStyle); 1447c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mHijackFocus = hijackFocus; 1448b1818e83f4a81bc4e4e30b99bb48830415be731bAmith Yamasani // TODO: Add an API to control this 1449b1818e83f4a81bc4e4e30b99bb48830415be731bAmith Yamasani setCacheColorHint(0); // Transparent, since the background drawable could be anything. 1450c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1451c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1452c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 1453c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette * Handles forwarded events. 1454c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette * 1455c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette * @param activePointerId id of the pointer that activated forwarding 1456c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette * @return whether the event was handled 1457c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette */ 1458c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette public boolean onForwardedEvent(MotionEvent event, int activePointerId) { 1459c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette boolean handledEvent = true; 1460c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette boolean clearPressedItem = false; 1461c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette 1462c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette final int actionMasked = event.getActionMasked(); 1463c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette switch (actionMasked) { 1464c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette case MotionEvent.ACTION_CANCEL: 1465c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette handledEvent = false; 1466c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette break; 1467c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette case MotionEvent.ACTION_UP: 1468c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette handledEvent = false; 1469c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette // $FALL-THROUGH$ 1470c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette case MotionEvent.ACTION_MOVE: 1471c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette final int activeIndex = event.findPointerIndex(activePointerId); 1472c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette if (activeIndex < 0) { 1473c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette handledEvent = false; 1474c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette break; 1475c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette } 1476c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette 1477c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette final int x = (int) event.getX(activeIndex); 1478c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette final int y = (int) event.getY(activeIndex); 1479c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette final int position = pointToPosition(x, y); 1480c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette if (position == INVALID_POSITION) { 1481c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette clearPressedItem = true; 1482c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette break; 1483c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette } 1484c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette 1485c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette final View child = getChildAt(position - getFirstVisiblePosition()); 1486c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette setPressedItem(child, position); 1487c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette handledEvent = true; 1488c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette 1489c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette if (actionMasked == MotionEvent.ACTION_UP) { 1490c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette clickPressedItem(child, position); 1491c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette } 1492c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette break; 1493c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette } 1494c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette 1495c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette // Failure to handle the event cancels forwarding. 1496c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette if (!handledEvent || clearPressedItem) { 1497c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette clearPressedItem(); 1498c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette } 1499c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette 15005e66021c8a24c27c470cc6b9fe49e5653f3fa05dAlan Viverette // Manage automatic scrolling. 15015e66021c8a24c27c470cc6b9fe49e5653f3fa05dAlan Viverette if (handledEvent) { 15025e66021c8a24c27c470cc6b9fe49e5653f3fa05dAlan Viverette if (mScrollHelper == null) { 15035e66021c8a24c27c470cc6b9fe49e5653f3fa05dAlan Viverette mScrollHelper = new AbsListViewAutoScroller(this); 15045e66021c8a24c27c470cc6b9fe49e5653f3fa05dAlan Viverette } 15055e66021c8a24c27c470cc6b9fe49e5653f3fa05dAlan Viverette mScrollHelper.setEnabled(true); 15065e66021c8a24c27c470cc6b9fe49e5653f3fa05dAlan Viverette mScrollHelper.onTouch(this, event); 15075e66021c8a24c27c470cc6b9fe49e5653f3fa05dAlan Viverette } else if (mScrollHelper != null) { 15085e66021c8a24c27c470cc6b9fe49e5653f3fa05dAlan Viverette mScrollHelper.setEnabled(false); 15095e66021c8a24c27c470cc6b9fe49e5653f3fa05dAlan Viverette } 15105e66021c8a24c27c470cc6b9fe49e5653f3fa05dAlan Viverette 1511c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette return handledEvent; 1512c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette } 1513c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette 1514c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette /** 1515c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette * Starts an alpha animation on the selector. When the animation ends, 1516c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette * the list performs a click on the item. 1517c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette */ 1518c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette private void clickPressedItem(final View child, final int position) { 1519c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette final long id = getItemIdAtPosition(position); 1520c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette final Animator anim = ObjectAnimator.ofInt( 1521c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette mSelector, DRAWABLE_ALPHA, 0xFF, CLICK_ANIM_ALPHA, 0xFF); 1522c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette anim.setDuration(CLICK_ANIM_DURATION); 1523c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette anim.setInterpolator(new AccelerateDecelerateInterpolator()); 1524c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette anim.addListener(new AnimatorListenerAdapter() { 1525c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette @Override 1526c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette public void onAnimationEnd(Animator animation) { 1527c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette performItemClick(child, position, id); 1528c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette } 1529c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette }); 1530c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette anim.start(); 1531c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette 1532c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette if (mClickAnimation != null) { 1533c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette mClickAnimation.cancel(); 1534c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette } 1535c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette mClickAnimation = anim; 1536c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette } 1537c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette 1538c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette private void clearPressedItem() { 1539c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette mDrawsInPressedState = false; 1540c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette setPressed(false); 1541c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette updateSelectorState(); 1542c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette 1543c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette if (mClickAnimation != null) { 1544c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette mClickAnimation.cancel(); 1545c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette mClickAnimation = null; 1546c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette } 1547c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette } 1548c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette 1549c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette private void setPressedItem(View child, int position) { 1550c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette mDrawsInPressedState = true; 1551c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette 1552c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette // Ordering is essential. First update the pressed state and layout 1553c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette // the children. This will ensure the selector actually gets drawn. 1554c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette setPressed(true); 1555c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette layoutChildren(); 1556c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette 1557c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette // Ensure that keyboard focus starts from the last touched position. 1558c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette setSelectedPositionInt(position); 1559c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette positionSelector(position, child); 1560c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette 1561c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette // Refresh the drawable state to reflect the new pressed state, 1562c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette // which will also update the selector state. 1563c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette refreshDrawableState(); 1564c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette 1565c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette if (mClickAnimation != null) { 1566c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette mClickAnimation.cancel(); 1567c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette mClickAnimation = null; 1568c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette } 1569c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette } 1570c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette 1571c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette @Override 1572c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette boolean touchModeDrawsInPressedState() { 1573c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette return mDrawsInPressedState || super.touchModeDrawsInPressedState(); 1574c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette } 1575c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette 1576c05027214f1f4dda67296a072dfc9af9176dc590Alan Viverette /** 1577c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>Avoids jarring scrolling effect by ensuring that list elements 1578c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * made of a text view fit on a single line.</p> 1579c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 1580c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param position the item index in the list to get a view for 1581c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return the view for the specified item 1582c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 1583c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell @Override 1584c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell View obtainView(int position, boolean[] isScrap) { 1585c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell View view = super.obtainView(position, isScrap); 1586c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1587c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (view instanceof TextView) { 1588c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell ((TextView) view).setHorizontallyScrolling(true); 1589c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1590c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1591c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return view; 1592c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1593c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1594c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell @Override 1595c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean isInTouchMode() { 1596c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // WARNING: Please read the comment where mListSelectionHidden is declared 1597c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return (mHijackFocus && mListSelectionHidden) || super.isInTouchMode(); 1598c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1599c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1600c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 1601c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>Returns the focus state in the drop down.</p> 1602c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 1603c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return true always if hijacking focus 1604c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 1605c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell @Override 1606c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean hasWindowFocus() { 1607c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mHijackFocus || super.hasWindowFocus(); 1608c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1609c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1610c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 1611c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>Returns the focus state in the drop down.</p> 1612c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 1613c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return true always if hijacking focus 1614c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 1615c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell @Override 1616c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean isFocused() { 1617c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mHijackFocus || super.isFocused(); 1618c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1619c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1620c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 1621c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>Returns the focus state in the drop down.</p> 1622c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 1623c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return true always if hijacking focus 1624c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 1625c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell @Override 1626c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean hasFocus() { 1627c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mHijackFocus || super.hasFocus(); 1628c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1629c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1630c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1631c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private class PopupDataSetObserver extends DataSetObserver { 1632c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell @Override 1633c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void onChanged() { 1634c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (isShowing()) { 1635c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // Resize the popup to fit new content 1636c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell show(); 1637c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1638c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1639c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1640c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell @Override 1641c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void onInvalidated() { 1642c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell dismiss(); 1643c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1644c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1645c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1646c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private class ListSelectorHider implements Runnable { 1647c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void run() { 1648c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell clearListSelection(); 1649c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1650c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1651c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1652c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private class ResizePopupRunnable implements Runnable { 1653c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void run() { 1654348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell if (mDropDownList != null && mDropDownList.getCount() > mDropDownList.getChildCount() && 1655348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell mDropDownList.getChildCount() <= mListItemExpandMaximum) { 1656348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); 1657348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell show(); 1658348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell } 1659c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1660c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1661c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1662c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private class PopupTouchInterceptor implements OnTouchListener { 1663c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean onTouch(View v, MotionEvent event) { 1664c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final int action = event.getAction(); 1665c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final int x = (int) event.getX(); 1666c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final int y = (int) event.getY(); 1667c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1668c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (action == MotionEvent.ACTION_DOWN && 1669c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup != null && mPopup.isShowing() && 1670711734a2f8d7529df0ed1bce36da651fc835c144Gilles Debunne (x >= 0 && x < mPopup.getWidth() && y >= 0 && y < mPopup.getHeight())) { 1671c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mHandler.postDelayed(mResizePopupRunnable, EXPAND_LIST_TIMEOUT); 1672c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else if (action == MotionEvent.ACTION_UP) { 1673c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mHandler.removeCallbacks(mResizePopupRunnable); 1674c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1675c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return false; 1676c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1677c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1678c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1679c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private class PopupScrollListener implements ListView.OnScrollListener { 1680c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, 1681c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int totalItemCount) { 1682c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1683c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1684c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1685c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void onScrollStateChanged(AbsListView view, int scrollState) { 1686c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (scrollState == SCROLL_STATE_TOUCH_SCROLL && 1687c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell !isInputMethodNotNeeded() && mPopup.getContentView() != null) { 1688c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mHandler.removeCallbacks(mResizePopupRunnable); 1689c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mResizePopupRunnable.run(); 1690c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1691c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1692c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1693c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell} 1694