ListPopupWindow.java revision d3d9f3f1004dfee2649a26cfe8dba948cd364904
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 19c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.content.Context; 20c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.database.DataSetObserver; 21c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.graphics.Rect; 22c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.graphics.drawable.Drawable; 23c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.os.Handler; 24d3d9f3f1004dfee2649a26cfe8dba948cd364904Fabrice Di Meglioimport android.text.TextUtils; 25c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.util.AttributeSet; 26c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.util.Log; 27c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.KeyEvent; 28c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.MotionEvent; 29c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.View; 30c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.View.MeasureSpec; 31c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.View.OnTouchListener; 32711734a2f8d7529df0ed1bce36da651fc835c144Gilles Debunneimport android.view.ViewGroup; 33711734a2f8d7529df0ed1bce36da651fc835c144Gilles Debunneimport android.view.ViewParent; 34c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 351d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglioimport java.util.Locale; 361d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio 37c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell/** 38c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * A ListPopupWindow anchors itself to a host view and displays a 3965d79fbe55c017edd9419ddb71939c8916471390Adam Powell * list of choices. 40c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 41c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>ListPopupWindow contains a number of tricky behaviors surrounding 42c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * positioning, scrolling parents to fit the dropdown, interacting 43c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * sanely with the IME if present, and others. 44c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 45c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see android.widget.AutoCompleteTextView 46c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see android.widget.Spinner 47c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 48c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellpublic class ListPopupWindow { 49c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private static final String TAG = "ListPopupWindow"; 50c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private static final boolean DEBUG = false; 51c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 52c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 53c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * This value controls the length of time that the user 54c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * must leave a pointer down without scrolling to expand 55c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * the autocomplete dropdown list to cover the IME. 56c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 57c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private static final int EXPAND_LIST_TIMEOUT = 250; 58c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 59c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private Context mContext; 60c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private PopupWindow mPopup; 61c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private ListAdapter mAdapter; 62c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private DropDownListView mDropDownList; 63c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 64c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private int mDropDownHeight = ViewGroup.LayoutParams.WRAP_CONTENT; 65c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private int mDropDownWidth = ViewGroup.LayoutParams.WRAP_CONTENT; 66c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private int mDropDownHorizontalOffset; 67c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private int mDropDownVerticalOffset; 688132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell private boolean mDropDownVerticalOffsetSet; 69c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 70c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private boolean mDropDownAlwaysVisible = false; 71c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private boolean mForceIgnoreOutsideTouch = false; 72348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell int mListItemExpandMaximum = Integer.MAX_VALUE; 73c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 74c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private View mPromptView; 75c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private int mPromptPosition = POSITION_PROMPT_ABOVE; 76c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 77c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private DataSetObserver mObserver; 78c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 79c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private View mDropDownAnchorView; 80c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 81c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private Drawable mDropDownListHighlight; 82c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 83c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private AdapterView.OnItemClickListener mItemClickListener; 84c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private AdapterView.OnItemSelectedListener mItemSelectedListener; 85c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 864267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell private final ResizePopupRunnable mResizePopupRunnable = new ResizePopupRunnable(); 87c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private final PopupTouchInterceptor mTouchInterceptor = new PopupTouchInterceptor(); 88c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private final PopupScrollListener mScrollListener = new PopupScrollListener(); 89c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private final ListSelectorHider mHideSelector = new ListSelectorHider(); 90c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private Runnable mShowDropDownRunnable; 91c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 92c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private Handler mHandler = new Handler(); 93c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 94c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private Rect mTempRect = new Rect(); 95c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 96c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private boolean mModal; 97c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 981d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio private int mLayoutDirection; 991d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio 100c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 101c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * The provided prompt view should appear above list content. 102c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 103c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setPromptPosition(int) 104c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #getPromptPosition() 105c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setPromptView(View) 106c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 107c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public static final int POSITION_PROMPT_ABOVE = 0; 108c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 109c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 110c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * The provided prompt view should appear below list content. 111c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 112c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setPromptPosition(int) 113c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #getPromptPosition() 114c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setPromptView(View) 115c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 116c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public static final int POSITION_PROMPT_BELOW = 1; 117c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 118c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 119c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Alias for {@link ViewGroup.LayoutParams#MATCH_PARENT}. 120c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * If used to specify a popup width, the popup will match the width of the anchor view. 121c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * If used to specify a popup height, the popup will fill available space. 122c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 123c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public static final int MATCH_PARENT = ViewGroup.LayoutParams.MATCH_PARENT; 124c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 125c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 126c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Alias for {@link ViewGroup.LayoutParams#WRAP_CONTENT}. 127c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * If used to specify a popup width, the popup will use the width of its content. 128c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 129c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public static final int WRAP_CONTENT = ViewGroup.LayoutParams.WRAP_CONTENT; 130c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 131c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 132c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Mode for {@link #setInputMethodMode(int)}: the requirements for the 133c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * input method should be based on the focusability of the popup. That is 134c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * if it is focusable than it needs to work with the input method, else 135c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * it doesn't. 136c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 137c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public static final int INPUT_METHOD_FROM_FOCUSABLE = PopupWindow.INPUT_METHOD_FROM_FOCUSABLE; 138c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 139c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 140c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Mode for {@link #setInputMethodMode(int)}: this popup always needs to 141c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * work with an input method, regardless of whether it is focusable. This 142c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * means that it will always be displayed so that the user can also operate 143c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * the input method while it is shown. 144c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 145c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public static final int INPUT_METHOD_NEEDED = PopupWindow.INPUT_METHOD_NEEDED; 146c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 147c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 148c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Mode for {@link #setInputMethodMode(int)}: this popup never needs to 149c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * work with an input method, regardless of whether it is focusable. This 150c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * means that it will always be displayed to use as much space on the 151c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * screen as needed, regardless of whether this covers the input method. 152c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 153c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public static final int INPUT_METHOD_NOT_NEEDED = PopupWindow.INPUT_METHOD_NOT_NEEDED; 154c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 155c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 156c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Create a new, empty popup window capable of displaying items from a ListAdapter. 157c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Backgrounds should be set using {@link #setBackgroundDrawable(Drawable)}. 158c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 159c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param context Context used for contained views. 160c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 161c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public ListPopupWindow(Context context) { 162c2238d006237ebf1296074d80fb4f4a2741ef880Daniel Lehmann this(context, null, com.android.internal.R.attr.listPopupWindowStyle, 0); 163c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 164c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 165c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 166c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Create a new, empty popup window capable of displaying items from a ListAdapter. 167c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Backgrounds should be set using {@link #setBackgroundDrawable(Drawable)}. 168c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 169c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param context Context used for contained views. 170c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param attrs Attributes from inflating parent views used to style the popup. 171c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 172c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public ListPopupWindow(Context context, AttributeSet attrs) { 1730b2d306e7000f4c0c6ad4e00d494bb401d8a9fc2Adam Powell this(context, attrs, com.android.internal.R.attr.listPopupWindowStyle, 0); 174c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 175c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 176c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 177c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Create a new, empty popup window capable of displaying items from a ListAdapter. 178c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Backgrounds should be set using {@link #setBackgroundDrawable(Drawable)}. 179c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 180c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param context Context used for contained views. 181c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param attrs Attributes from inflating parent views used to style the popup. 182c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param defStyleAttr Default style attribute to use for popup content. 183c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 184c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public ListPopupWindow(Context context, AttributeSet attrs, int defStyleAttr) { 185c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell this(context, attrs, defStyleAttr, 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 Style attribute to read for default styling of popup content. 195c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param defStyleRes Style resource ID to use for default styling of popup content. 196c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 197c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public ListPopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 198c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mContext = context; 199c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup = new PopupWindow(context, attrs, defStyleAttr, defStyleRes); 2006f5e934b96c400f610b1c5ad228cc60cab5d443fAdam Powell mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); 2011d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio // Set the default layout direction to match the default locale one 2021d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio final Locale locale = mContext.getResources().getConfiguration().locale; 203d3d9f3f1004dfee2649a26cfe8dba948cd364904Fabrice Di Meglio mLayoutDirection = TextUtils.getLayoutDirectionFromLocale(locale); 204c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 205c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 206c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 207c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets the adapter that provides the data and the views to represent the data 208c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * in this popup window. 209c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 210c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param adapter The adapter to use to create this window's content. 211c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 212c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setAdapter(ListAdapter adapter) { 213c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mObserver == null) { 214c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mObserver = new PopupDataSetObserver(); 215c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else if (mAdapter != null) { 21699969da3772d9a0f5079672847ca4f2ad819c1bbAdam Powell mAdapter.unregisterDataSetObserver(mObserver); 217c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 218c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mAdapter = adapter; 219c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mAdapter != null) { 220c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell adapter.registerDataSetObserver(mObserver); 221c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 222c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 223c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownList != null) { 224c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setAdapter(mAdapter); 225c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 226c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 227c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 228c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 229c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Set where the optional prompt view should appear. The default is 230c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * {@link #POSITION_PROMPT_ABOVE}. 231c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 232c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param position A position constant declaring where the prompt should be displayed. 233c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 234c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #POSITION_PROMPT_ABOVE 235c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #POSITION_PROMPT_BELOW 236c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 237c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setPromptPosition(int position) { 238c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPromptPosition = position; 239c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 240c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 241c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 242c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return Where the optional prompt view should appear. 243c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 244c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #POSITION_PROMPT_ABOVE 245c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #POSITION_PROMPT_BELOW 246c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 247c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getPromptPosition() { 248c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mPromptPosition; 249c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 250c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 251c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 252c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Set whether this window should be modal when shown. 253c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 254c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>If a popup window is modal, it will receive all touch and key input. 255c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * If the user touches outside the popup window's content area the popup window 256c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * will be dismissed. 257c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 258c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param modal {@code true} if the popup window should be modal, {@code false} otherwise. 259c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 260c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setModal(boolean modal) { 261c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mModal = true; 262c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setFocusable(modal); 263c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 264c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 265c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 266c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Returns whether the popup window will be modal when shown. 267c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 268c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return {@code true} if the popup window will be modal, {@code false} otherwise. 269c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 270c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean isModal() { 271c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mModal; 272c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 273c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 274c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 275c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Forces outside touches to be ignored. Normally if {@link #isDropDownAlwaysVisible()} is 276c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * false, we allow outside touch to dismiss the dropdown. If this is set to true, then we 277c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * ignore outside touch even when the drop down is not set to always visible. 278c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 279c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @hide Used only by AutoCompleteTextView to handle some internal special cases. 280c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 281c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setForceIgnoreOutsideTouch(boolean forceIgnoreOutsideTouch) { 282c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mForceIgnoreOutsideTouch = forceIgnoreOutsideTouch; 283c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 284c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 285c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 286c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets whether the drop-down should remain visible under certain conditions. 287c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 288c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * The drop-down will occupy the entire screen below {@link #getAnchorView} regardless 289c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * of the size or content of the list. {@link #getBackground()} will fill any space 290c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * that is not used by the list. 291c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 292c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param dropDownAlwaysVisible Whether to keep the drop-down visible. 293c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 294c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @hide Only used by AutoCompleteTextView under special conditions. 295c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 296c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setDropDownAlwaysVisible(boolean dropDownAlwaysVisible) { 297c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownAlwaysVisible = dropDownAlwaysVisible; 298c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 299c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 300c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 301c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return Whether the drop-down is visible under special conditions. 302c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 303c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @hide Only used by AutoCompleteTextView under special conditions. 304c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 305c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean isDropDownAlwaysVisible() { 306c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownAlwaysVisible; 307c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 308c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 309c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 310c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets the operating mode for the soft input area. 311c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 312c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param mode The desired mode, see 313c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * {@link android.view.WindowManager.LayoutParams#softInputMode} 314c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * for the full list 315c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 316c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see android.view.WindowManager.LayoutParams#softInputMode 317c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #getSoftInputMode() 318c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 319c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setSoftInputMode(int mode) { 320c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setSoftInputMode(mode); 321c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 322c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 323c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 324c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Returns the current value in {@link #setSoftInputMode(int)}. 325c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 326c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setSoftInputMode(int) 327c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see android.view.WindowManager.LayoutParams#softInputMode 328c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 329c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getSoftInputMode() { 330c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mPopup.getSoftInputMode(); 331c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 332c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 333c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 334c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets a drawable to use as the list item selector. 335c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 336c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param selector List selector drawable to use in the popup. 337c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 338c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setListSelector(Drawable selector) { 339c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownListHighlight = selector; 340c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 341c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 342c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 343c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The background drawable for the popup window. 344c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 345c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public Drawable getBackground() { 346c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mPopup.getBackground(); 347c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 348c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 349c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 350c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets a drawable to be the background for the popup window. 351c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 352c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param d A drawable to set as the background. 353c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 354c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setBackgroundDrawable(Drawable d) { 355c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setBackgroundDrawable(d); 356c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 357c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 358c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 359c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Set an animation style to use when the popup window is shown or dismissed. 360c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 361c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param animationStyle Animation style to use. 362c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 363c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setAnimationStyle(int animationStyle) { 364c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setAnimationStyle(animationStyle); 365c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 366c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 367c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 368c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Returns the animation style that will be used when the popup window is 369c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * shown or dismissed. 370c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 371c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return Animation style that will be used. 372c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 373c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getAnimationStyle() { 374c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mPopup.getAnimationStyle(); 375c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 376c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 377c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 378c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Returns the view that will be used to anchor this popup. 379c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 380c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The popup's anchor view 381c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 382c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public View getAnchorView() { 383c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownAnchorView; 384c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 385c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 386c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 387c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets the popup's anchor view. This popup will always be positioned relative to 388c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * the anchor view when shown. 389c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 390c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param anchor The view to use as an anchor. 391c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 392c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setAnchorView(View anchor) { 393c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownAnchorView = anchor; 394c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 395c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 396c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 397c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The horizontal offset of the popup from its anchor in pixels. 398c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 399c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getHorizontalOffset() { 400c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownHorizontalOffset; 401c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 402c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 403c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 404c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Set the horizontal offset of this popup from its anchor view in pixels. 405c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 406a984b38df5cfe6db0ba792bf2a6221f6b6072448Adam Powell * @param offset The horizontal offset of the popup from its anchor. 407c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 408c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setHorizontalOffset(int offset) { 409c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownHorizontalOffset = offset; 410c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 411c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 412c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 413c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The vertical offset of the popup from its anchor in pixels. 414c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 415c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getVerticalOffset() { 4168132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell if (!mDropDownVerticalOffsetSet) { 4178132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell return 0; 4188132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell } 419c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownVerticalOffset; 420c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 421c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 422c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 423c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Set the vertical offset of this popup from its anchor view in pixels. 424c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 425a984b38df5cfe6db0ba792bf2a6221f6b6072448Adam Powell * @param offset The vertical offset of the popup from its anchor. 426c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 427c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setVerticalOffset(int offset) { 428c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownVerticalOffset = offset; 4298132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell mDropDownVerticalOffsetSet = true; 430c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 431c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 432c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 433c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The width of the popup window in pixels. 434c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 435c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getWidth() { 436c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownWidth; 437c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 438c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 439c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 440c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets the width of the popup window in pixels. Can also be {@link #MATCH_PARENT} 441c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * or {@link #WRAP_CONTENT}. 442c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 443c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param width Width of the popup window. 444c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 445c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setWidth(int width) { 446c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownWidth = width; 447c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 448c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 449c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 4504267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell * Sets the width of the popup window by the size of its content. The final width may be 4514267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell * larger to accommodate styled window dressing. 4524267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell * 4534267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell * @param width Desired width of content in pixels. 4544267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell */ 4554267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell public void setContentWidth(int width) { 4564267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell Drawable popupBackground = mPopup.getBackground(); 4574267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell if (popupBackground != null) { 458a39b987bb761899636ae1e3669d1343499d04ebdAdam Powell popupBackground.getPadding(mTempRect); 459a39b987bb761899636ae1e3669d1343499d04ebdAdam Powell mDropDownWidth = mTempRect.left + mTempRect.right + width; 46062e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell } else { 46162e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell setWidth(width); 4624267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell } 4634267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell } 4644267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell 4654267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell /** 466c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The height of the popup window in pixels. 467c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 468c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getHeight() { 469c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownHeight; 470c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 471c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 472c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 473c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets the height of the popup window in pixels. Can also be {@link #MATCH_PARENT}. 474c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 475c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param height Height of the popup window. 476c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 477c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setHeight(int height) { 478c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownHeight = height; 479c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 480c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 481c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 482c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets a listener to receive events when a list item is clicked. 483c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 484c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param clickListener Listener to register 485c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 486c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see ListView#setOnItemClickListener(android.widget.AdapterView.OnItemClickListener) 487c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 488c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setOnItemClickListener(AdapterView.OnItemClickListener clickListener) { 489c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mItemClickListener = clickListener; 490c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 491c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 492c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 493c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Sets a listener to receive events when a list item is selected. 494c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 495c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param selectedListener Listener to register. 496c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 497c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see ListView#setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener) 498c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 499c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener selectedListener) { 500c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mItemSelectedListener = selectedListener; 501c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 502c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 503c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 504c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Set a view to act as a user prompt for this popup window. Where the prompt view will appear 505c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * is controlled by {@link #setPromptPosition(int)}. 506c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 507c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param prompt View to use as an informational prompt. 508c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 509c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setPromptView(View prompt) { 510c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell boolean showing = isShowing(); 511c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (showing) { 512c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell removePromptView(); 513c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 514c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPromptView = prompt; 515c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (showing) { 516c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell show(); 517c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 518c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 519c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 520c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 521c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Post a {@link #show()} call to the UI thread. 522c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 523c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void postShow() { 524c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mHandler.post(mShowDropDownRunnable); 525c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 526c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 527c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 528c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Show the popup list. If the list is already showing, this method 529c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * will recalculate the popup's size and position. 530c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 531c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void show() { 532c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int height = buildDropDown(); 533c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 534c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int widthSpec = 0; 535c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int heightSpec = 0; 536c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 537c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell boolean noInputMethod = isInputMethodNotNeeded(); 538348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell mPopup.setAllowScrollingAnchorParent(!noInputMethod); 539c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 540c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mPopup.isShowing()) { 541c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT) { 542c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // The call to PopupWindow's update method below can accept -1 for any 543c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // value you do not want to update. 544c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell widthSpec = -1; 545c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) { 546c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell widthSpec = getAnchorView().getWidth(); 547c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 548c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell widthSpec = mDropDownWidth; 549c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 550c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 551c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) { 552c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // The call to PopupWindow's update method below can accept -1 for any 553c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // value you do not want to update. 554c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell heightSpec = noInputMethod ? height : ViewGroup.LayoutParams.MATCH_PARENT; 555c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (noInputMethod) { 556c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setWindowLayoutMode( 557c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT ? 558c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell ViewGroup.LayoutParams.MATCH_PARENT : 0, 0); 559c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 560c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setWindowLayoutMode( 561c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT ? 562c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell ViewGroup.LayoutParams.MATCH_PARENT : 0, 563c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell ViewGroup.LayoutParams.MATCH_PARENT); 564c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 565c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) { 566c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell heightSpec = height; 567c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 568c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell heightSpec = mDropDownHeight; 569c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 570c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 571c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch && !mDropDownAlwaysVisible); 572c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 573c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.update(getAnchorView(), mDropDownHorizontalOffset, 574c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownVerticalOffset, widthSpec, heightSpec); 575c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 576c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT) { 577c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell widthSpec = ViewGroup.LayoutParams.MATCH_PARENT; 578c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 579c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) { 580c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setWidth(getAnchorView().getWidth()); 581c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 582c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setWidth(mDropDownWidth); 583c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 584c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 585c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 586c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) { 587c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell heightSpec = ViewGroup.LayoutParams.MATCH_PARENT; 588c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 589c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) { 590c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setHeight(height); 591c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 592c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setHeight(mDropDownHeight); 593c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 594c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 595c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 596c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setWindowLayoutMode(widthSpec, heightSpec); 59756c2d337e02a275397fc9d0460dca90977f199acAdam Powell mPopup.setClipToScreenEnabled(true); 598c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 599c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // use outside touchable to dismiss drop down when touching outside of it, so 600c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // only set this if the dropdown is not always visible 601c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch && !mDropDownAlwaysVisible); 602c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setTouchInterceptor(mTouchInterceptor); 603c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.showAsDropDown(getAnchorView(), 604c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownHorizontalOffset, mDropDownVerticalOffset); 605c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setSelection(ListView.INVALID_POSITION); 606c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 607c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (!mModal || mDropDownList.isInTouchMode()) { 608c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell clearListSelection(); 609c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 610c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (!mModal) { 611c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mHandler.post(mHideSelector); 612c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 613c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 614c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 615c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 616c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 617c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Dismiss the popup window. 618c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 619c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void dismiss() { 620c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.dismiss(); 621c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell removePromptView(); 622c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setContentView(null); 623c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList = null; 624ca51e8788a58f2af3525b7214a675f2d0233e5daAdam Powell mHandler.removeCallbacks(mResizePopupRunnable); 625c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 626c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 6276c6f575423d6718c3ff322224c1520901ce881e1Adam Powell /** 6286c6f575423d6718c3ff322224c1520901ce881e1Adam Powell * Set a listener to receive a callback when the popup is dismissed. 6296c6f575423d6718c3ff322224c1520901ce881e1Adam Powell * 6306c6f575423d6718c3ff322224c1520901ce881e1Adam Powell * @param listener Listener that will be notified when the popup is dismissed. 6316c6f575423d6718c3ff322224c1520901ce881e1Adam Powell */ 6326c6f575423d6718c3ff322224c1520901ce881e1Adam Powell public void setOnDismissListener(PopupWindow.OnDismissListener listener) { 6336c6f575423d6718c3ff322224c1520901ce881e1Adam Powell mPopup.setOnDismissListener(listener); 6346c6f575423d6718c3ff322224c1520901ce881e1Adam Powell } 6356c6f575423d6718c3ff322224c1520901ce881e1Adam Powell 636c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private void removePromptView() { 637c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mPromptView != null) { 638c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final ViewParent parent = mPromptView.getParent(); 639c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (parent instanceof ViewGroup) { 640c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final ViewGroup group = (ViewGroup) parent; 641c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell group.removeView(mPromptView); 642c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 643c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 644c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 645c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 646c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 647c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Control how the popup operates with an input method: one of 648c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * {@link #INPUT_METHOD_FROM_FOCUSABLE}, {@link #INPUT_METHOD_NEEDED}, 649c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * or {@link #INPUT_METHOD_NOT_NEEDED}. 650c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 651c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>If the popup is showing, calling this method will take effect only 652c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * the next time the popup is shown or through a manual call to the {@link #show()} 653c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * method.</p> 654c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 655c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #getInputMethodMode() 656c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #show() 657c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 658c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setInputMethodMode(int mode) { 659c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setInputMethodMode(mode); 660c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 661c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 662c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 663c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Return the current value in {@link #setInputMethodMode(int)}. 664c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 665c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setInputMethodMode(int) 666c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 667c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getInputMethodMode() { 668c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mPopup.getInputMethodMode(); 669c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 670c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 671c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 672c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Set the selected position of the list. 673c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Only valid when {@link #isShowing()} == {@code true}. 674c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 675c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param position List position to set as selected. 676c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 677c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void setSelection(int position) { 678c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell DropDownListView list = mDropDownList; 679c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (isShowing() && list != null) { 680c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell list.mListSelectionHidden = false; 681c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell list.setSelection(position); 682c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (list.getChoiceMode() != ListView.CHOICE_MODE_NONE) { 683c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell list.setItemChecked(position, true); 684c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 685c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 686c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 687c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 688c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 689c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Clear any current list selection. 690c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Only valid when {@link #isShowing()} == {@code true}. 691c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 692c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void clearListSelection() { 693c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final DropDownListView list = mDropDownList; 694c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (list != null) { 695c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // WARNING: Please read the comment where mListSelectionHidden is declared 696c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell list.mListSelectionHidden = true; 697c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell list.hideSelector(); 698c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell list.requestLayout(); 699c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 700c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 701c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 702c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 703c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return {@code true} if the popup is currently showing, {@code false} otherwise. 704c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 705c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean isShowing() { 706c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mPopup.isShowing(); 707c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 708c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 709c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 710c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return {@code true} if this popup is configured to assume the user does not need 711c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * to interact with the IME while it is showing, {@code false} otherwise. 712c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 713c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean isInputMethodNotNeeded() { 714c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mPopup.getInputMethodMode() == INPUT_METHOD_NOT_NEEDED; 715c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 716c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 717c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 718c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Perform an item click operation on the specified list adapter position. 719c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 720c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param position Adapter position for performing the click 721c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return true if the click action could be performed, false if not. 722c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * (e.g. if the popup was not showing, this method would return false.) 723c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 724c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean performItemClick(int position) { 725c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (isShowing()) { 726c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mItemClickListener != null) { 727c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final DropDownListView list = mDropDownList; 728c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final View child = list.getChildAt(position - list.getFirstVisiblePosition()); 729cdee446075811e871fc2af295377bd99c100d16dAdam Powell final ListAdapter adapter = list.getAdapter(); 730cdee446075811e871fc2af295377bd99c100d16dAdam Powell mItemClickListener.onItemClick(list, child, position, adapter.getItemId(position)); 731c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 732c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return true; 733c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 734c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return false; 735c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 736c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 737c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 738c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The currently selected item or null if the popup is not showing. 739c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 740c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public Object getSelectedItem() { 741c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (!isShowing()) { 742c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return null; 743c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 744c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownList.getSelectedItem(); 745c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 746c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 747c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 748c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The position of the currently selected item or {@link ListView#INVALID_POSITION} 749c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * if {@link #isShowing()} == {@code false}. 750c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 751c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see ListView#getSelectedItemPosition() 752c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 753c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public int getSelectedItemPosition() { 754c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (!isShowing()) { 755c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return ListView.INVALID_POSITION; 756c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 757c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownList.getSelectedItemPosition(); 758c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 759c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 760c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 761c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The ID of the currently selected item or {@link ListView#INVALID_ROW_ID} 762c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * if {@link #isShowing()} == {@code false}. 763c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 764c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see ListView#getSelectedItemId() 765c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 766c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public long getSelectedItemId() { 767c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (!isShowing()) { 768c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return ListView.INVALID_ROW_ID; 769c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 770c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownList.getSelectedItemId(); 771c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 772c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 773c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 774c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The View for the currently selected item or null if 775c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * {@link #isShowing()} == {@code false}. 776c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 777c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see ListView#getSelectedView() 778c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 779c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public View getSelectedView() { 780c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (!isShowing()) { 781c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return null; 782c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 783c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownList.getSelectedView(); 784c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 785c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 786c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 787c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return The {@link ListView} displayed within the popup window. 788c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Only valid when {@link #isShowing()} == {@code true}. 789c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 790c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public ListView getListView() { 791c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mDropDownList; 792c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 793c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 794c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 795348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * The maximum number of list items that can be visible and still have 796348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * the list expand when touched. 797348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * 798348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell * @param max Max number of items that can be visible and still allow the list to expand. 799348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell */ 800348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell void setListItemExpandMax(int max) { 801348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell mListItemExpandMaximum = max; 802348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell } 803348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell 804348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell /** 8058d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown * Filter key down events. By forwarding key down events to this function, 806c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * views using non-modal ListPopupWindow can have it handle key selection of items. 807c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 808c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param keyCode keyCode param passed to the host view's onKeyDown 809c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param event event param passed to the host view's onKeyDown 810c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return true if the event was handled, false if it was ignored. 811c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 812c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setModal(boolean) 813c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 814c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean onKeyDown(int keyCode, KeyEvent event) { 815c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // when the drop down is shown, we drive it directly 816c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (isShowing()) { 817c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // the key events are forwarded to the list in the drop down view 818c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // note that ListView handles space but we don't want that to happen 819c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // also if selection is not currently in the drop down, then don't 820c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // let center or enter presses go there since that would cause it 821c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // to select one of its items 822c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (keyCode != KeyEvent.KEYCODE_SPACE 823c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell && (mDropDownList.getSelectedItemPosition() >= 0 824c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell || (keyCode != KeyEvent.KEYCODE_ENTER 825c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell && keyCode != KeyEvent.KEYCODE_DPAD_CENTER))) { 826c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int curIndex = mDropDownList.getSelectedItemPosition(); 827c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell boolean consumed; 828c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 829c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final boolean below = !mPopup.isAboveAnchor(); 830c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 831c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final ListAdapter adapter = mAdapter; 832c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 833c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell boolean allEnabled; 834c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int firstItem = Integer.MAX_VALUE; 835c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int lastItem = Integer.MIN_VALUE; 836c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 837c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (adapter != null) { 838c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell allEnabled = adapter.areAllItemsEnabled(); 839c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell firstItem = allEnabled ? 0 : 840c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.lookForSelectablePosition(0, true); 841c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell lastItem = allEnabled ? adapter.getCount() - 1 : 842c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.lookForSelectablePosition(adapter.getCount() - 1, false); 843c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 844c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 845c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if ((below && keyCode == KeyEvent.KEYCODE_DPAD_UP && curIndex <= firstItem) || 846c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell (!below && keyCode == KeyEvent.KEYCODE_DPAD_DOWN && curIndex >= lastItem)) { 847c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // When the selection is at the top, we block the key 848c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // event to prevent focus from moving. 849c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell clearListSelection(); 850c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); 851c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell show(); 852c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return true; 853c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 854c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // WARNING: Please read the comment where mListSelectionHidden 855c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // is declared 856c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.mListSelectionHidden = false; 857c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 858c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 859c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell consumed = mDropDownList.onKeyDown(keyCode, event); 860c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (DEBUG) Log.v(TAG, "Key down: code=" + keyCode + " list consumed=" + consumed); 861c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 862c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (consumed) { 863c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // If it handled the key event, then the user is 864c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // navigating in the list, so we should put it in front. 865c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); 866c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // Here's a little trick we need to do to make sure that 867c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // the list view is actually showing its focus indicator, 868c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // by ensuring it has focus and getting its window out 869c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // of touch mode. 870c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.requestFocusFromTouch(); 871c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell show(); 872c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 873c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell switch (keyCode) { 874c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // avoid passing the focus from the text view to the 875c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // next component 876c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell case KeyEvent.KEYCODE_ENTER: 877c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell case KeyEvent.KEYCODE_DPAD_CENTER: 878c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell case KeyEvent.KEYCODE_DPAD_DOWN: 879c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell case KeyEvent.KEYCODE_DPAD_UP: 880c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return true; 881c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 882c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 883c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (below && keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { 884c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // when the selection is at the bottom, we block the 885c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // event to avoid going to the next focusable widget 886c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (curIndex == lastItem) { 887c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return true; 888c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 889c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else if (!below && keyCode == KeyEvent.KEYCODE_DPAD_UP && 890c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell curIndex == firstItem) { 891c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return true; 892c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 893c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 894c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 895c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 896c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 897c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return false; 898c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 899c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 900c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 901c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Filter key down events. By forwarding key up events to this function, 902c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * views using non-modal ListPopupWindow can have it handle key selection of items. 903c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 904c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param keyCode keyCode param passed to the host view's onKeyUp 905c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param event event param passed to the host view's onKeyUp 906c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return true if the event was handled, false if it was ignored. 907c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 908c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setModal(boolean) 909c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 910c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean onKeyUp(int keyCode, KeyEvent event) { 911c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (isShowing() && mDropDownList.getSelectedItemPosition() >= 0) { 912c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell boolean consumed = mDropDownList.onKeyUp(keyCode, event); 913c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (consumed) { 914c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell switch (keyCode) { 915c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // if the list accepts the key events and the key event 916c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // was a click, the text view gets the selected item 917c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // from the drop down as its content 918c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell case KeyEvent.KEYCODE_ENTER: 919c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell case KeyEvent.KEYCODE_DPAD_CENTER: 920c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell dismiss(); 921c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell break; 922c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 923c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 924c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return consumed; 925c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 926c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return false; 927c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 928c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 929c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 930c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Filter pre-IME key events. By forwarding {@link View#onKeyPreIme(int, KeyEvent)} 931c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * events to this function, views using ListPopupWindow can have it dismiss the popup 932c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * when the back key is pressed. 933c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 934c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param keyCode keyCode param passed to the host view's onKeyPreIme 935c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param event event param passed to the host view's onKeyPreIme 936c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return true if the event was handled, false if it was ignored. 937c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 938c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see #setModal(boolean) 939c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 940c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean onKeyPreIme(int keyCode, KeyEvent event) { 941c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (keyCode == KeyEvent.KEYCODE_BACK && isShowing()) { 942c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // special case for the back key, we do not even try to send it 943c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // to the drop down list but instead, consume it immediately 944c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final View anchorView = mDropDownAnchorView; 945c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { 946b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown KeyEvent.DispatcherState state = anchorView.getKeyDispatcherState(); 947b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown if (state != null) { 948b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown state.startTracking(event, this); 949b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } 950c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return true; 951c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else if (event.getAction() == KeyEvent.ACTION_UP) { 952b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown KeyEvent.DispatcherState state = anchorView.getKeyDispatcherState(); 953b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown if (state != null) { 954b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown state.handleUpEvent(event); 955b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown } 956c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (event.isTracking() && !event.isCanceled()) { 957c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell dismiss(); 958c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return true; 959c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 960c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 961c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 962c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return false; 963c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 964c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 965c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 966c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>Builds the popup window's content and returns the height the popup 967c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * should have. Returns -1 when the content already exists.</p> 968c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 969c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return the content's height or -1 if content already exists 970c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 971c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private int buildDropDown() { 972c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell ViewGroup dropDownView; 973c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int otherHeights = 0; 974c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 975c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownList == null) { 976c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell Context context = mContext; 977c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 978c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 979c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * This Runnable exists for the sole purpose of checking if the view layout has got 980c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * completed and if so call showDropDown to display the drop down. This is used to show 981c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * the drop down as soon as possible after user opens up the search dialog, without 982c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * waiting for the normal UI pipeline to do it's job which is slower than this method. 983c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 984c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mShowDropDownRunnable = new Runnable() { 985c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void run() { 986c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // View layout should be all done before displaying the drop down. 987c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell View view = getAnchorView(); 988c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (view != null && view.getWindowToken() != null) { 989c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell show(); 990c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 991c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 992c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell }; 993c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 994c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList = new DropDownListView(context, !mModal); 995c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownListHighlight != null) { 996c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setSelector(mDropDownListHighlight); 997c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 998c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setAdapter(mAdapter); 999c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setOnItemClickListener(mItemClickListener); 1000c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setFocusable(true); 1001c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setFocusableInTouchMode(true); 1002c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 1003c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void onItemSelected(AdapterView<?> parent, View view, 1004c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int position, long id) { 1005c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1006c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (position != -1) { 1007c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell DropDownListView dropDownList = mDropDownList; 1008c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1009c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (dropDownList != null) { 1010c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell dropDownList.mListSelectionHidden = false; 1011c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1012c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1013c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1014c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1015c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void onNothingSelected(AdapterView<?> parent) { 1016c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1017c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell }); 1018c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setOnScrollListener(mScrollListener); 1019c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1020c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mItemSelectedListener != null) { 1021c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mDropDownList.setOnItemSelectedListener(mItemSelectedListener); 1022c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1023c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 10241d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio mDropDownList.setLayoutDirection(mLayoutDirection); 10251d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio 1026c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell dropDownView = mDropDownList; 1027c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1028c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell View hintView = mPromptView; 1029c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (hintView != null) { 1030f76a50ce8fdc6aea22cabc77b2977a1a15a79630Ken Wakasa // if a hint has been specified, we accomodate more space for it and 1031c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // add a text view in the drop down menu, at the bottom of the list 1032c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell LinearLayout hintContainer = new LinearLayout(context); 1033c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell hintContainer.setOrientation(LinearLayout.VERTICAL); 1034c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1035c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell LinearLayout.LayoutParams hintParams = new LinearLayout.LayoutParams( 1036c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell ViewGroup.LayoutParams.MATCH_PARENT, 0, 1.0f 1037c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell ); 1038c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1039c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell switch (mPromptPosition) { 1040c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell case POSITION_PROMPT_BELOW: 1041c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell hintContainer.addView(dropDownView, hintParams); 1042c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell hintContainer.addView(hintView); 1043c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell break; 1044c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1045c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell case POSITION_PROMPT_ABOVE: 1046c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell hintContainer.addView(hintView); 1047c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell hintContainer.addView(dropDownView, hintParams); 1048c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell break; 1049c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1050c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell default: 1051c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell Log.e(TAG, "Invalid hint position " + mPromptPosition); 1052c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell break; 1053c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1054c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1055c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // measure the hint's height to find how much more vertical space 1056c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // we need to add to the drop down's height 1057c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int widthSpec = MeasureSpec.makeMeasureSpec(mDropDownWidth, MeasureSpec.AT_MOST); 1058c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int heightSpec = MeasureSpec.UNSPECIFIED; 1059c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell hintView.measure(widthSpec, heightSpec); 1060c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1061c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell hintParams = (LinearLayout.LayoutParams) hintView.getLayoutParams(); 1062c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell otherHeights = hintView.getMeasuredHeight() + hintParams.topMargin 1063c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell + hintParams.bottomMargin; 1064c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1065c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell dropDownView = hintContainer; 1066c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1067c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1068c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup.setContentView(dropDownView); 1069c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else { 1070c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell dropDownView = (ViewGroup) mPopup.getContentView(); 1071c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final View view = mPromptView; 1072c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (view != null) { 1073c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell LinearLayout.LayoutParams hintParams = 1074c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell (LinearLayout.LayoutParams) view.getLayoutParams(); 1075c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell otherHeights = view.getMeasuredHeight() + hintParams.topMargin 1076c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell + hintParams.bottomMargin; 1077c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1078c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1079c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 10808132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell // getMaxAvailableHeight() subtracts the padding, so we put it back 1081c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // to get the available height for the whole window 1082c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int padding = 0; 1083c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell Drawable background = mPopup.getBackground(); 1084c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (background != null) { 1085c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell background.getPadding(mTempRect); 1086c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell padding = mTempRect.top + mTempRect.bottom; 10878132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell 10888132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell // If we don't have an explicit vertical offset, determine one from the window 10898132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell // background so that content will line up. 10908132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell if (!mDropDownVerticalOffsetSet) { 10918132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell mDropDownVerticalOffset = -mTempRect.top; 10928132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell } 10937507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell } else { 10947507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell mTempRect.setEmpty(); 1095c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1096c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 10978132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell // Max height available on the screen for a popup. 10988132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell boolean ignoreBottomDecorations = 10998132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED; 11008132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell final int maxHeight = mPopup.getMaxAvailableHeight( 11018132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell getAnchorView(), mDropDownVerticalOffset, ignoreBottomDecorations); 11028132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell 1103c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (mDropDownAlwaysVisible || mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) { 1104c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return maxHeight + padding; 1105c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1106c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 11077507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell final int childWidthSpec; 11087507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell switch (mDropDownWidth) { 11097507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell case ViewGroup.LayoutParams.WRAP_CONTENT: 11107507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell childWidthSpec = MeasureSpec.makeMeasureSpec( 11117507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell mContext.getResources().getDisplayMetrics().widthPixels - 11127507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell (mTempRect.left + mTempRect.right), 11137507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell MeasureSpec.AT_MOST); 11147507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell break; 11157507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell case ViewGroup.LayoutParams.MATCH_PARENT: 11167507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell childWidthSpec = MeasureSpec.makeMeasureSpec( 11177507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell mContext.getResources().getDisplayMetrics().widthPixels - 11187507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell (mTempRect.left + mTempRect.right), 11197507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell MeasureSpec.EXACTLY); 11207507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell break; 11217507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell default: 11227507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell childWidthSpec = MeasureSpec.makeMeasureSpec(mDropDownWidth, MeasureSpec.EXACTLY); 11237507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell break; 11247507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell } 11257507d3d31cb3d0ca190efc9d6b7ead5d6336f8d6Adam Powell final int listContent = mDropDownList.measureHeightOfChildren(childWidthSpec, 1126a7845ed44a3722e7d96ca9b677be213da7e8c8feAdam Powell 0, ListView.NO_POSITION, maxHeight - otherHeights, -1); 1127c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // add padding only if the list has items in it, that way we don't show 1128c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // the popup if it is not needed 1129c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (listContent > 0) otherHeights += padding; 1130c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1131c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return listContent + otherHeights; 1132c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1133c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 11341d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio /** 11351d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio * Set the layout direction for this popup. Should be a resolved direction as the 11361d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio * popup as no capacity to do the resolution on his own. 11371d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio * 11381d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio * @param layoutDirection One of {@link View#LAYOUT_DIRECTION_LTR}, 11391d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio * {@link View#LAYOUT_DIRECTION_RTL}, 11401d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio * 11411d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio */ 11421d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio public void setLayoutDirection(int layoutDirection) { 11431d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio mLayoutDirection = layoutDirection; 11443a69bea30257f32a21bb6c32aafa52982d16a401Fabrice Di Meglio if (mDropDownList != null) { 11451d3d7da331a3e9dc783819ab6fe29ea21c873f1eFabrice Di Meglio mDropDownList.setLayoutDirection(mLayoutDirection); 11463a69bea30257f32a21bb6c32aafa52982d16a401Fabrice Di Meglio } 11473a69bea30257f32a21bb6c32aafa52982d16a401Fabrice Di Meglio } 11483a69bea30257f32a21bb6c32aafa52982d16a401Fabrice Di Meglio 1149c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 1150c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>Wrapper class for a ListView. This wrapper can hijack the focus to 1151c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * make sure the list uses the appropriate drawables and states when 1152c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * displayed on screen within a drop down. The focus is never actually 1153c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * passed to the drop down in this mode; the list only looks focused.</p> 1154c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 1155c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private static class DropDownListView extends ListView { 1156c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private static final String TAG = ListPopupWindow.TAG + ".DropDownListView"; 1157c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /* 1158c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * WARNING: This is a workaround for a touch mode issue. 1159c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 1160c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Touch mode is propagated lazily to windows. This causes problems in 1161c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * the following scenario: 1162c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * - Type something in the AutoCompleteTextView and get some results 1163c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * - Move down with the d-pad to select an item in the list 1164c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * - Move up with the d-pad until the selection disappears 1165c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * - Type more text in the AutoCompleteTextView *using the soft keyboard* 1166c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * and get new results; you are now in touch mode 1167c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * - The selection comes back on the first item in the list, even though 1168c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * the list is supposed to be in touch mode 1169c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 1170c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Using the soft keyboard triggers the touch mode change but that change 1171c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * is propagated to our window only after the first list layout, therefore 1172c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * after the list attempts to resurrect the selection. 1173c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 1174c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * The trick to work around this issue is to pretend the list is in touch 1175c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * mode when we know that the selection should not appear, that is when 1176c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * we know the user moved the selection away from the list. 1177c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 1178c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * This boolean is set to true whenever we explicitly hide the list's 1179c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * selection and reset to false whenever we know the user moved the 1180c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * selection back to the list. 1181c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 1182c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * When this boolean is true, isInTouchMode() returns true, otherwise it 1183c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * returns super.isInTouchMode(). 1184c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 1185c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private boolean mListSelectionHidden; 1186c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1187c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 1188c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * True if this wrapper should fake focus. 1189c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 1190c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private boolean mHijackFocus; 1191c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1192c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 1193c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>Creates a new list view wrapper.</p> 1194c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 1195c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param context this view's context 1196c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 1197c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public DropDownListView(Context context, boolean hijackFocus) { 1198c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell super(context, null, com.android.internal.R.attr.dropDownListViewStyle); 1199c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mHijackFocus = hijackFocus; 1200b1818e83f4a81bc4e4e30b99bb48830415be731bAmith Yamasani // TODO: Add an API to control this 1201b1818e83f4a81bc4e4e30b99bb48830415be731bAmith Yamasani setCacheColorHint(0); // Transparent, since the background drawable could be anything. 1202c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1203c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1204c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 1205c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>Avoids jarring scrolling effect by ensuring that list elements 1206c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * made of a text view fit on a single line.</p> 1207c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 1208c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @param position the item index in the list to get a view for 1209c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return the view for the specified item 1210c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 1211c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell @Override 1212c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell View obtainView(int position, boolean[] isScrap) { 1213c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell View view = super.obtainView(position, isScrap); 1214c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1215c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (view instanceof TextView) { 1216c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell ((TextView) view).setHorizontallyScrolling(true); 1217c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1218c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1219c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return view; 1220c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1221c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1222c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell @Override 1223c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean isInTouchMode() { 1224c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // WARNING: Please read the comment where mListSelectionHidden is declared 1225c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return (mHijackFocus && mListSelectionHidden) || super.isInTouchMode(); 1226c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1227c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1228c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 1229c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>Returns the focus state in the drop down.</p> 1230c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 1231c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return true always if hijacking focus 1232c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 1233c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell @Override 1234c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean hasWindowFocus() { 1235c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mHijackFocus || super.hasWindowFocus(); 1236c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1237c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1238c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 1239c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>Returns the focus state in the drop down.</p> 1240c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 1241c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return true always if hijacking focus 1242c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 1243c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell @Override 1244c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean isFocused() { 1245c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mHijackFocus || super.isFocused(); 1246c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1247c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1248c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell /** 1249c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>Returns the focus state in the drop down.</p> 1250c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * 1251c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @return true always if hijacking focus 1252c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */ 1253c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell @Override 1254c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean hasFocus() { 1255c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return mHijackFocus || super.hasFocus(); 1256c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1257c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1258c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1259c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private class PopupDataSetObserver extends DataSetObserver { 1260c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell @Override 1261c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void onChanged() { 1262c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (isShowing()) { 1263c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell // Resize the popup to fit new content 1264c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell show(); 1265c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1266c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1267c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1268c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell @Override 1269c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void onInvalidated() { 1270c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell dismiss(); 1271c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1272c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1273c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1274c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private class ListSelectorHider implements Runnable { 1275c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void run() { 1276c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell clearListSelection(); 1277c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1278c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1279c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1280c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private class ResizePopupRunnable implements Runnable { 1281c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void run() { 1282348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell if (mDropDownList != null && mDropDownList.getCount() > mDropDownList.getChildCount() && 1283348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell mDropDownList.getChildCount() <= mListItemExpandMaximum) { 1284348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); 1285348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell show(); 1286348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell } 1287c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1288c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1289c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1290c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private class PopupTouchInterceptor implements OnTouchListener { 1291c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public boolean onTouch(View v, MotionEvent event) { 1292c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final int action = event.getAction(); 1293c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final int x = (int) event.getX(); 1294c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell final int y = (int) event.getY(); 1295c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1296c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (action == MotionEvent.ACTION_DOWN && 1297c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mPopup != null && mPopup.isShowing() && 1298711734a2f8d7529df0ed1bce36da651fc835c144Gilles Debunne (x >= 0 && x < mPopup.getWidth() && y >= 0 && y < mPopup.getHeight())) { 1299c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mHandler.postDelayed(mResizePopupRunnable, EXPAND_LIST_TIMEOUT); 1300c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } else if (action == MotionEvent.ACTION_UP) { 1301c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mHandler.removeCallbacks(mResizePopupRunnable); 1302c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1303c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell return false; 1304c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1305c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1306c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1307c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell private class PopupScrollListener implements ListView.OnScrollListener { 1308c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, 1309c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell int totalItemCount) { 1310c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1311c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1312c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell 1313c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell public void onScrollStateChanged(AbsListView view, int scrollState) { 1314c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell if (scrollState == SCROLL_STATE_TOUCH_SCROLL && 1315c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell !isInputMethodNotNeeded() && mPopup.getContentView() != null) { 1316c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mHandler.removeCallbacks(mResizePopupRunnable); 1317c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell mResizePopupRunnable.run(); 1318c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1319c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1320c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell } 1321c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell} 1322