AutoCompleteTextView.java revision 8d37426c754e9822feaa8c6cc0b7c13e8523e217
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.Drawable; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.Editable; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.Selection; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextWatcher; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyEvent; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.LayoutInflater; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.MotionEvent; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewGroup; 34374aaaed32daa8482d98ec16988b2b51547f035dRomain Guyimport android.view.WindowManager; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.CompletionInfo; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputMethodManager; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.EditorInfo; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.R; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>An editable text view that shows completion suggestions automatically 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * while the user is typing. The list of suggestions is displayed in a drop 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * down menu from which the user can choose an item to replace the content 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the edit box with.</p> 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The drop down can be dismissed at any time by pressing the back key or, 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if no item is selected in the drop down, by pressing the enter/dpad center 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * key.</p> 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The list of suggestions is obtained from a data adapter and appears 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * only after a given number of characters defined by 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #getThreshold() the threshold}.</p> 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The following code snippet shows how to create a text view which suggests 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * various countries names while the user is typing:</p> 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre class="prettyprint"> 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * public class CountriesActivity extends Activity { 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * protected void onCreate(Bundle icicle) { 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * super.onCreate(icicle); 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * setContentView(R.layout.countries); 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * android.R.layout.simple_dropdown_item_1line, COUNTRIES); 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * AutoCompleteTextView textView = (AutoCompleteTextView) 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * findViewById(R.id.countries_list); 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * textView.setAdapter(adapter); 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * } 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * private static final String[] COUNTRIES = new String[] { 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * "Belgium", "France", "Italy", "Germany", "Spain" 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * }; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * } 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </pre> 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#AutoCompleteTextView_completionHint 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#AutoCompleteTextView_completionThreshold 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#AutoCompleteTextView_completionHintView 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#AutoCompleteTextView_dropDownSelector 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#AutoCompleteTextView_dropDownAnchor 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#AutoCompleteTextView_dropDownWidth 84e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * @attr ref android.R.styleable#AutoCompleteTextView_dropDownHeight 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class AutoCompleteTextView extends EditText implements Filter.FilterListener { 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG = false; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final String TAG = "AutoCompleteTextView"; 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int HINT_VIEW_ID = 0x17; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private CharSequence mHintText; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mHintResource; 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ListAdapter mAdapter; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Filter mFilter; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mThreshold; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private PopupWindow mPopup; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private DropDownListView mDropDownList; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mDropDownVerticalOffset; 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mDropDownHorizontalOffset; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mDropDownAnchorId; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View mDropDownAnchorView; // view is retrieved lazily from id once needed 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mDropDownWidth; 106e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy private int mDropDownHeight; 1075420d01cef810c34d754cadfaa1e8cae13af06deBjorn Bringert private final Rect mTempRect = new Rect(); 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Drawable mDropDownListHighlight; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private AdapterView.OnItemClickListener mItemClickListener; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private AdapterView.OnItemSelectedListener mItemSelectedListener; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final DropDownItemClickListener mDropDownItemClickListener = 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new DropDownItemClickListener(); 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 117875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen private boolean mDropDownAlwaysVisible = false; 118875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen 119875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen private boolean mDropDownDismissedOnCompletion = true; 120d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau 121d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau private boolean mForceIgnoreOutsideTouch = false; 122875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLastKeyCode = KeyEvent.KEYCODE_UNKNOWN; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mOpenBefore; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Validator mValidator = null; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mBlockCompletion; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private AutoCompleteTextView.ListSelectorHider mHideSelector; 131fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath private Runnable mShowDropDownRunnable; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13398e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen private AutoCompleteTextView.PassThroughClickListener mPassThroughClickListener; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AutoCompleteTextView(Context context) { 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, null); 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AutoCompleteTextView(Context context, AttributeSet attrs) { 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, attrs, com.android.internal.R.attr.autoCompleteTextViewStyle); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AutoCompleteTextView(Context context, AttributeSet attrs, int defStyle) { 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(context, attrs, defStyle); 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPopup = new PopupWindow(context, attrs, 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.attr.autoCompleteTextViewStyle); 148374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy mPopup.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TypedArray a = 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project context.obtainStyledAttributes( 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attrs, com.android.internal.R.styleable.AutoCompleteTextView, defStyle, 0); 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mThreshold = a.getInt( 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R.styleable.AutoCompleteTextView_completionThreshold, 2); 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHintText = a.getText(R.styleable.AutoCompleteTextView_completionHint); 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownListHighlight = a.getDrawable( 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R.styleable.AutoCompleteTextView_dropDownSelector); 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownVerticalOffset = (int) 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.getDimension(R.styleable.AutoCompleteTextView_dropDownVerticalOffset, 0.0f); 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownHorizontalOffset = (int) 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.getDimension(R.styleable.AutoCompleteTextView_dropDownHorizontalOffset, 0.0f); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Get the anchor's id now, but the view won't be ready, so wait to actually get the 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // view and store it in mDropDownAnchorView lazily in getDropDownAnchorView later. 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Defaults to NO_ID, in which case the getDropDownAnchorView method will simply return 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this TextView, as a default anchoring point. 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownAnchorId = a.getResourceId(R.styleable.AutoCompleteTextView_dropDownAnchor, 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View.NO_ID); 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // For dropdown width, the developer can specify a specific width, or FILL_PARENT 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // (for full screen width) or WRAP_CONTENT (to match the width of the anchored view). 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownWidth = a.getLayoutDimension(R.styleable.AutoCompleteTextView_dropDownWidth, 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewGroup.LayoutParams.WRAP_CONTENT); 177e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy mDropDownHeight = a.getLayoutDimension(R.styleable.AutoCompleteTextView_dropDownHeight, 178e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy ViewGroup.LayoutParams.WRAP_CONTENT); 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHintResource = a.getResourceId(R.styleable.AutoCompleteTextView_completionHintView, 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R.layout.simple_dropdown_hint); 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Always turn on the auto complete input type flag, since it 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // makes no sense to use this widget without it. 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int inputType = getInputType(); 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((inputType&EditorInfo.TYPE_MASK_CLASS) 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project == EditorInfo.TYPE_CLASS_TEXT) { 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inputType |= EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE; 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setRawInputType(inputType); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setFocusable(true); 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addTextChangedListener(new MyWatcher()); 197ddf9856c7de043674d9ede006aefc7769879a4b8Mike LeBeau 19898e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen mPassThroughClickListener = new PassThroughClickListener(); 19998e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen super.setOnClickListener(mPassThroughClickListener); 20098e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen } 20198e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen 20298e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen @Override 20398e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen public void setOnClickListener(OnClickListener listener) { 20498e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen mPassThroughClickListener.mWrapped = listener; 20598e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen } 20698e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen 20798e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen /** 20898e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen * Private hook into the on click event, dispatched from {@link PassThroughClickListener} 20998e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen */ 21098e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen private void onClickImpl() { 211470c565b6adf4847db7e10611b18f67bf9111768Mike LeBeau // If the dropdown is showing, bring it back in front of the soft 212470c565b6adf4847db7e10611b18f67bf9111768Mike LeBeau // keyboard when the user touches the text field. 213003ad48380fe90556da408fedba7dfc1a37790b9Bjorn Bringert if (mPopup.isShowing() && isInputMethodNotNeeded()) { 214ffe3ecf2b1ee04288008758c0f60ae22238797c1Mike LeBeau ensureImeVisible(); 21598e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen } 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets this to be single line; a separate method so 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * MultiAutoCompleteTextView can skip this. 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* package */ void finishInit() { 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setSingleLine(); 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Sets the optional hint text that is displayed at the bottom of the 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the matching list. This can be used as a cue to the user on how to 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * best use the list, or to provide extra information.</p> 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param hint the text to be displayed to the user 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#AutoCompleteTextView_completionHint 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setCompletionHint(CharSequence hint) { 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHintText = hint; 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Returns the current width for the auto-complete drop down list. This can 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be a fixed width, or {@link ViewGroup.LayoutParams#FILL_PARENT} to fill the screen, or 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the width of its anchor view.</p> 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the width for the drop down list 2457b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * 2467b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * @attr ref android.R.styleable#AutoCompleteTextView_dropDownWidth 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getDropDownWidth() { 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDropDownWidth; 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Sets the current width for the auto-complete drop down list. This can 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be a fixed width, or {@link ViewGroup.LayoutParams#FILL_PARENT} to fill the screen, or 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the width of its anchor view.</p> 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param width the width to use 2587b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * 2597b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * @attr ref android.R.styleable#AutoCompleteTextView_dropDownWidth 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setDropDownWidth(int width) { 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownWidth = width; 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 264e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy 265e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy /** 266e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * <p>Returns the current height for the auto-complete drop down list. This can 267e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * be a fixed height, or {@link ViewGroup.LayoutParams#FILL_PARENT} to fill 268e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * the screen, or {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the height 269e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * of the drop down's content.</p> 270e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * 271e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * @return the height for the drop down list 272e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * 273e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * @attr ref android.R.styleable#AutoCompleteTextView_dropDownHeight 274e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy */ 275e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy public int getDropDownHeight() { 276e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy return mDropDownHeight; 277e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy } 278e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy 279e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy /** 280e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * <p>Sets the current height for the auto-complete drop down list. This can 281e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * be a fixed height, or {@link ViewGroup.LayoutParams#FILL_PARENT} to fill 282e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * the screen, or {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the height 283e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * of the drop down's content.</p> 284e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * 285e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * @param height the height to use 286e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * 287e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * @attr ref android.R.styleable#AutoCompleteTextView_dropDownHeight 288e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy */ 289e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy public void setDropDownHeight(int height) { 290e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy mDropDownHeight = height; 291e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy } 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Returns the id for the view that the auto-complete drop down list is anchored to.</p> 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the view's id, or {@link View#NO_ID} if none specified 2977b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * 2987b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * @attr ref android.R.styleable#AutoCompleteTextView_dropDownAnchor 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getDropDownAnchor() { 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDropDownAnchorId; 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Sets the view to which the auto-complete drop down list should anchor. The view 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * corresponding to this id will not be loaded until the next time it is needed to avoid 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * loading a view which is not yet instantiated.</p> 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param id the id to anchor the drop down list view to 3107b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * 3117b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * @attr ref android.R.styleable#AutoCompleteTextView_dropDownAnchor 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setDropDownAnchor(int id) { 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownAnchorId = id; 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownAnchorView = null; 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3177b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project 3187b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project /** 3197b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * <p>Gets the background of the auto-complete drop-down list.</p> 3207b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * 3217b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * @return the background drawable 3227b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * 3237b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * @attr ref android.R.styleable#PopupWindow_popupBackground 3247b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project */ 3257b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project public Drawable getDropDownBackground() { 3267b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project return mPopup.getBackground(); 3277b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project } 3287b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project 3297b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project /** 3307b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * <p>Sets the background of the auto-complete drop-down list.</p> 3317b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * 3327b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * @param d the drawable to set as the background 3337b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * 3347b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * @attr ref android.R.styleable#PopupWindow_popupBackground 3357b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project */ 3367b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project public void setDropDownBackgroundDrawable(Drawable d) { 3377b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project mPopup.setBackgroundDrawable(d); 3387b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project } 3397b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project 3407b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project /** 3417b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * <p>Sets the background of the auto-complete drop-down list.</p> 3427b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * 3437b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * @param id the id of the drawable to set as the background 3447b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * 3457b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * @attr ref android.R.styleable#PopupWindow_popupBackground 3467b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project */ 3477b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project public void setDropDownBackgroundResource(int id) { 3487b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project mPopup.setBackgroundDrawable(getResources().getDrawable(id)); 3497b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project } 3507b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project 3517b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project /** 3527b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * <p>Sets the vertical offset used for the auto-complete drop-down list.</p> 3537b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * 3547b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * @param offset the vertical offset 3557b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project */ 3567b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project public void setDropDownVerticalOffset(int offset) { 3577b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project mDropDownVerticalOffset = offset; 3587b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project } 3597b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project 3607b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project /** 3617b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * <p>Gets the vertical offset used for the auto-complete drop-down list.</p> 3627b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * 3637b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * @return the vertical offset 3647b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project */ 3657b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project public int getDropDownVerticalOffset() { 3667b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project return mDropDownVerticalOffset; 3677b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project } 3687b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project 3697b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project /** 3707b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * <p>Sets the horizontal offset used for the auto-complete drop-down list.</p> 3717b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * 3727b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * @param offset the horizontal offset 3737b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project */ 3747b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project public void setDropDownHorizontalOffset(int offset) { 3757b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project mDropDownHorizontalOffset = offset; 3767b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project } 3777b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project 3787b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project /** 3797b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * <p>Gets the horizontal offset used for the auto-complete drop-down list.</p> 3807b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * 3817b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project * @return the horizontal offset 3827b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project */ 3837b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project public int getDropDownHorizontalOffset() { 3847b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project return mDropDownHorizontalOffset; 3857b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project } 3868f080ec4292be02fad9896260bbd3cf5461f9399The Android Open Source Project 387bff1389c9ab4442a6e278cf84ce37eadad21a9a1The Android Open Source Project /** 388875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * <p>Sets the animation style of the auto-complete drop-down list.</p> 389875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * 390875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * <p>If the drop-down is showing, calling this method will take effect only 391875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * the next time the drop-down is shown.</p> 392875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * 393875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * @param animationStyle animation style to use when the drop-down appears 394875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * and disappears. Set to -1 for the default animation, 0 for no 395875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * animation, or a resource identifier for an explicit animation. 396875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * 397875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * @hide Pending API council approval 398875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen */ 399875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen public void setDropDownAnimationStyle(int animationStyle) { 400875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen mPopup.setAnimationStyle(animationStyle); 401875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen } 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 404875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * <p>Returns the animation style that is used when the drop-down list appears and disappears 405875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * </p> 406875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * 407875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * @return the animation style that is used when the drop-down list appears and disappears 408875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * 409875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * @hide Pending API council approval 410875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen */ 411875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen public int getDropDownAnimationStyle() { 412875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen return mPopup.getAnimationStyle(); 413875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen } 414875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen 415875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen /** 416875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * @return Whether the drop-down is visible as long as there is {@link #enoughToFilter()} 417875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * 418875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * @hide Pending API council approval 419875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen */ 420875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen public boolean isDropDownAlwaysVisible() { 421875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen return mDropDownAlwaysVisible; 422875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen } 423875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen 424875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen /** 425875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * Sets whether the drop-down should remain visible as long as there is there is 426875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * {@link #enoughToFilter()}. This is useful if an unknown number of results are expected 427875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * to show up in the adapter sometime in the future. 428875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * 429875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * The drop-down will occupy the entire screen below {@link #getDropDownAnchor} regardless 430875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * of the size or content of the list. {@link #getDropDownBackground()} will fill any space 431875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * that is not used by the list. 432875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * 433875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * @param dropDownAlwaysVisible Whether to keep the drop-down visible. 434875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * 435875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * @hide Pending API council approval 436875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen */ 437875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen public void setDropDownAlwaysVisible(boolean dropDownAlwaysVisible) { 438875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen mDropDownAlwaysVisible = dropDownAlwaysVisible; 439875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen } 440875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen 441875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen /** 442875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * Checks whether the drop-down is dismissed when a suggestion is clicked. 443875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * 444875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * @hide Pending API council approval 445875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen */ 446875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen public boolean isDropDownDismissedOnCompletion() { 447875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen return mDropDownDismissedOnCompletion; 448875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen } 449875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen 450875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen /** 451875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * Sets whether the drop-down is dismissed when a suggestion is clicked. This is 452875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * true by default. 453875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * 454875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * @param dropDownDismissedOnCompletion Whether to dismiss the drop-down. 455875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * 456875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * @hide Pending API council approval 457875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen */ 458875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen public void setDropDownDismissedOnCompletion(boolean dropDownDismissedOnCompletion) { 459875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen mDropDownDismissedOnCompletion = dropDownDismissedOnCompletion; 460875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen } 461875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Returns the number of characters the user must type before the drop 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * down list is shown.</p> 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the minimum number of characters to type to show the drop down 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setThreshold(int) 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getThreshold() { 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mThreshold; 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Specifies the minimum number of characters the user has to type in the 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * edit box before the drop down list is shown.</p> 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>When <code>threshold</code> is less than or equals 0, a threshold of 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1 is applied.</p> 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param threshold the number of characters to type before the drop down 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is shown 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getThreshold() 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#AutoCompleteTextView_completionThreshold 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setThreshold(int threshold) { 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (threshold <= 0) { 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project threshold = 1; 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mThreshold = threshold; 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Sets the listener that will be notified when the user clicks an item 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the drop down list.</p> 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param l the item click listener 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setOnItemClickListener(AdapterView.OnItemClickListener l) { 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mItemClickListener = l; 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Sets the listener that will be notified when the user selects an item 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the drop down list.</p> 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param l the item selected listener 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener l) { 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mItemSelectedListener = l; 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Returns the listener that is notified whenever the user clicks an item 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the drop down list.</p> 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the item click listener 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated Use {@link #getOnItemClickListener()} intead 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AdapterView.OnItemClickListener getItemClickListener() { 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mItemClickListener; 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Returns the listener that is notified whenever the user selects an 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * item in the drop down list.</p> 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the item selected listener 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated Use {@link #getOnItemSelectedListener()} intead 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AdapterView.OnItemSelectedListener getItemSelectedListener() { 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mItemSelectedListener; 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Returns the listener that is notified whenever the user clicks an item 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the drop down list.</p> 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the item click listener 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AdapterView.OnItemClickListener getOnItemClickListener() { 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mItemClickListener; 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Returns the listener that is notified whenever the user selects an 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * item in the drop down list.</p> 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the item selected listener 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AdapterView.OnItemSelectedListener getOnItemSelectedListener() { 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mItemSelectedListener; 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Returns a filterable list adapter used for auto completion.</p> 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return a data adapter used for auto completion 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ListAdapter getAdapter() { 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAdapter; 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Changes the list of data used for auto completion. The provided list 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * must be a filterable list adapter.</p> 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The caller is still responsible for managing any resources used by the adapter. 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notably, when the AutoCompleteTextView is closed or released, the adapter is not notified. 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A common case is the use of {@link android.widget.CursorAdapter}, which 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * contains a {@link android.database.Cursor} that must be closed. This can be done 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * automatically (see 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.app.Activity#startManagingCursor(android.database.Cursor) 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * startManagingCursor()}), 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or by manually closing the cursor when the AutoCompleteTextView is dismissed.</p> 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param adapter the adapter holding the auto completion data 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getAdapter() 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.widget.Filterable 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.widget.ListAdapter 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public <T extends ListAdapter & Filterable> void setAdapter(T adapter) { 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAdapter = adapter; 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAdapter != null) { 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //noinspection unchecked 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFilter = ((Filterable) mAdapter).getFilter(); 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFilter = null; 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDropDownList != null) { 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownList.setAdapter(mAdapter); 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onKeyPreIme(int keyCode, KeyEvent event) { 6068d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn if (keyCode == KeyEvent.KEYCODE_BACK && isPopupShowing() 6078d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn && !mDropDownAlwaysVisible) { 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // special case for the back key, we do not even try to send it 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to the drop down list but instead, consume it immediately 6108d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn if (event.getAction() == KeyEvent.ACTION_DOWN 6118d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn && event.getRepeatCount() == 0) { 6128d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn getKeyDispatcherState().startTracking(event, this); 6138d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn return true; 6148d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn } else if (event.getAction() == KeyEvent.ACTION_UP 6158d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn && event.isTracking() && !event.isCanceled()) { 6168d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn dismissDropDown(); 6178d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn return true; 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.onKeyPreIme(keyCode, event); 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onKeyUp(int keyCode, KeyEvent event) { 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isPopupShowing() && mDropDownList.getSelectedItemPosition() >= 0) { 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean consumed = mDropDownList.onKeyUp(keyCode, event); 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (consumed) { 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (keyCode) { 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if the list accepts the key events and the key event 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // was a click, the text view gets the selected item 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // from the drop down as its content 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_ENTER: 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_CENTER: 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project performCompletion(); 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.onKeyUp(keyCode, event); 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onKeyDown(int keyCode, KeyEvent event) { 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // when the drop down is shown, we drive it directly 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isPopupShowing()) { 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the key events are forwarded to the list in the drop down view 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // note that ListView handles space but we don't want that to happen 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // also if selection is not currently in the drop down, then don't 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // let center or enter presses go there since that would cause it 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to select one of its items 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (keyCode != KeyEvent.KEYCODE_SPACE 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (mDropDownList.getSelectedItemPosition() >= 0 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || (keyCode != KeyEvent.KEYCODE_ENTER 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && keyCode != KeyEvent.KEYCODE_DPAD_CENTER))) { 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int curIndex = mDropDownList.getSelectedItemPosition(); 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean consumed; 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean below = !mPopup.isAboveAnchor(); 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((below && keyCode == KeyEvent.KEYCODE_DPAD_UP && curIndex <= 0) || 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (!below && keyCode == KeyEvent.KEYCODE_DPAD_DOWN && curIndex >= 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownList.getAdapter().getCount() - 1)) { 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // When the selection is at the top, we block the key 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // event to prevent focus from moving. 663465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy clearListSelection(); 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); 665e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy showDropDown(); 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 667465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy } else { 668465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy // WARNING: Please read the comment where mListSelectionHidden 669465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy // is declared 670465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy mDropDownList.mListSelectionHidden = false; 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 672465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project consumed = mDropDownList.onKeyDown(keyCode, event); 674465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy if (DEBUG) Log.v(TAG, "Key down: code=" + keyCode + " list consumed=" + consumed); 675465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (consumed) { 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If it handled the key event, then the user is 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // navigating in the list, so we should put it in front. 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Here's a little trick we need to do to make sure that 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the list view is actually showing its focus indicator, 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // by ensuring it has focus and getting its window out 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // of touch mode. 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownList.requestFocusFromTouch(); 685e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy showDropDown(); 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (keyCode) { 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // avoid passing the focus from the text view to the 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // next component 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_ENTER: 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_CENTER: 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_DOWN: 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_UP: 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (below && keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // when the selection is at the bottom, we block the 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // event to avoid going to the next focusable widget 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Adapter adapter = mDropDownList.getAdapter(); 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (adapter != null && curIndex == adapter.getCount() - 1) { 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (!below && keyCode == KeyEvent.KEYCODE_DPAD_UP && curIndex == 0) { 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch(keyCode) { 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_DOWN: 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project performValidation(); 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastKeyCode = keyCode; 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean handled = super.onKeyDown(keyCode, event); 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastKeyCode = KeyEvent.KEYCODE_UNKNOWN; 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 720c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project if (handled && isPopupShowing() && mDropDownList != null) { 721c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project clearListSelection(); 722c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project } 723c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return handled; 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns <code>true</code> if the amount of text in the field meets 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or exceeds the {@link #getThreshold} requirement. You can override 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this to impose a different standard for when filtering will be 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * triggered. 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean enoughToFilter() { 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "Enough to filter: len=" + getText().length() 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " threshold=" + mThreshold); 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return getText().length() >= mThreshold; 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is used to watch for edits to the text view. Note that we call 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to methods on the auto complete text view class so that we can access 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * private vars without going through thunks. 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class MyWatcher implements TextWatcher { 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void afterTextChanged(Editable s) { 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project doAfterTextChanged(); 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void beforeTextChanged(CharSequence s, int start, int count, int after) { 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project doBeforeTextChanged(); 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onTextChanged(CharSequence s, int start, int before, int count) { 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void doBeforeTextChanged() { 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBlockCompletion) return; 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // when text is changed, inserted or deleted, we attempt to show 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the drop down 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOpenBefore = isPopupShowing(); 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "before text changed: open=" + mOpenBefore); 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void doAfterTextChanged() { 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBlockCompletion) return; 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if the list was open before the keystroke, but closed afterwards, 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // then something in the keystroke processing (an input filter perhaps) 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // called performCompletion() and we shouldn't do any more processing. 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "after text changed: openBefore=" + mOpenBefore 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " open=" + isPopupShowing()); 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOpenBefore && !isPopupShowing()) { 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the drop down is shown only when a minimum number of characters 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // was typed in the text view 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enoughToFilter()) { 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFilter != null) { 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project performFiltering(getText(), mLastKeyCode); 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // drop down is automatically dismissed when enough characters 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // are deleted from the text view 7857299807d1895ea25cbe45d32b6edfd9a5723ee7aRomain Guy if (!mDropDownAlwaysVisible) dismissDropDown(); 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFilter != null) { 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFilter.filter(null); 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicates whether the popup menu is showing.</p> 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the popup menu is showing, false otherwise 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isPopupShowing() { 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPopup.isShowing(); 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Converts the selected item from the drop down list into a sequence 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of character that can be used in the edit box.</p> 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selectedItem the item selected by the user for completion 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return a sequence of characters representing the selected suggestion 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected CharSequence convertSelectionToString(Object selectedItem) { 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFilter.convertResultToString(selectedItem); 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Clear the list selection. This may only be temporary, as user input will often bring 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * it back. 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clearListSelection() { 818465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy final DropDownListView list = mDropDownList; 819465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy if (list != null) { 820465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy // WARNING: Please read the comment where mListSelectionHidden is declared 821465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy list.mListSelectionHidden = true; 822465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy list.hideSelector(); 823465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy list.requestLayout(); 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set the position of the dropdown view selection. 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param position The position to move the selector to. 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setListSelection(int position) { 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPopup.isShowing() && (mDropDownList != null)) { 834fb7ed107356a66a55f003a43a7acc2fdbed1e9c2Romain Guy mDropDownList.mListSelectionHidden = false; 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownList.setSelection(position); 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ListView.setSelection() will call requestLayout() 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Get the position of the dropdown view selection, if there is one. Returns 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link ListView#INVALID_POSITION ListView.INVALID_POSITION} if there is no dropdown or if 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * there is no selection. 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the position of the current selection, if there is one, or 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link ListView#INVALID_POSITION ListView.INVALID_POSITION} if not. 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see ListView#getSelectedItemPosition() 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getListSelection() { 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPopup.isShowing() && (mDropDownList != null)) { 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDropDownList.getSelectedItemPosition(); 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ListView.INVALID_POSITION; 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 856ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project 857a7a3b6ef0fdaf6b17993642b76baf90a03ae0077Karl Rosaen 858a7a3b6ef0fdaf6b17993642b76baf90a03ae0077Karl Rosaen /** 859a7a3b6ef0fdaf6b17993642b76baf90a03ae0077Karl Rosaen * @hide 860a7a3b6ef0fdaf6b17993642b76baf90a03ae0077Karl Rosaen * @return {@link android.widget.ListView#getChildCount()} of the drop down if it is showing, 861a7a3b6ef0fdaf6b17993642b76baf90a03ae0077Karl Rosaen * otherwise 0. 862a7a3b6ef0fdaf6b17993642b76baf90a03ae0077Karl Rosaen */ 863a7a3b6ef0fdaf6b17993642b76baf90a03ae0077Karl Rosaen protected int getDropDownChildCount() { 864a7a3b6ef0fdaf6b17993642b76baf90a03ae0077Karl Rosaen return mDropDownList == null ? 0 : mDropDownList.getChildCount(); 865a7a3b6ef0fdaf6b17993642b76baf90a03ae0077Karl Rosaen } 866a7a3b6ef0fdaf6b17993642b76baf90a03ae0077Karl Rosaen 867ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project /** 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Starts filtering the content of the drop down list. The filtering 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * pattern is the content of the edit box. Subclasses should override this 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * method to filter with a different pattern, for instance a substring of 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>text</code>.</p> 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param text the filtering pattern 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param keyCode the last character inserted in the edit box; beware that 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this will be null when text is being added through a soft input method. 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings({ "UnusedDeclaration" }) 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void performFiltering(CharSequence text, int keyCode) { 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFilter.filter(text, this); 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Performs the text completion by converting the selected item from 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the drop down list into a string, replacing the text box's content with 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this string and finally dismissing the drop down menu.</p> 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void performCompletion() { 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project performCompletion(null, -1, -1); 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onCommitCompletion(CompletionInfo completion) { 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isPopupShowing()) { 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBlockCompletion = true; 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replaceText(completion.getText()); 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBlockCompletion = false; 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mItemClickListener != null) { 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final DropDownListView list = mDropDownList; 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note that we don't have a View here, so we will need to 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // supply null. Hopefully no existing apps crash... 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mItemClickListener.onItemClick(list, null, completion.getPosition(), 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project completion.getId()); 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void performCompletion(View selectedView, int position, long id) { 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isPopupShowing()) { 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object selectedItem; 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (position < 0) { 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project selectedItem = mDropDownList.getSelectedItem(); 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project selectedItem = mAdapter.getItem(position); 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (selectedItem == null) { 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "performCompletion: no selected item"); 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBlockCompletion = true; 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replaceText(convertSelectionToString(selectedItem)); 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBlockCompletion = false; 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mItemClickListener != null) { 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final DropDownListView list = mDropDownList; 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (selectedView == null || position < 0) { 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project selectedView = list.getSelectedView(); 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project position = list.getSelectedItemPosition(); 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project id = list.getSelectedItemId(); 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mItemClickListener.onItemClick(list, selectedView, position, id); 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9377299807d1895ea25cbe45d32b6edfd9a5723ee7aRomain Guy if (mDropDownDismissedOnCompletion && !mDropDownAlwaysVisible) { 938875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen dismissDropDown(); 939875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen } 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Identifies whether the view is currently performing a text completion, so subclasses 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * can decide whether to respond to text changed events. 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isPerformingCompletion() { 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBlockCompletion; 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 951875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * Like {@link #setText(CharSequence)}, except that it can disable filtering. 952875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * 953875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * @param filter If <code>false</code>, no filtering will be performed 954875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * as a result of this call. 955875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * 956875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * @hide Pending API council approval. 957875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen */ 958875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen public void setText(CharSequence text, boolean filter) { 959875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen if (filter) { 960875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen setText(text); 961875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen } else { 962875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen mBlockCompletion = true; 963875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen setText(text); 964875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen mBlockCompletion = false; 965875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen } 966875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen } 967875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen 968875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen /** 969875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * Like {@link #setTextKeepState(CharSequence)}, except that it can disable filtering. 970875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * 971875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * @param filter If <code>false</code>, no filtering will be performed 972875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * as a result of this call. 973875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * 974875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * @hide Pending API council approval. 975875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen */ 976875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen public void setTextKeepState(CharSequence text, boolean filter) { 977875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen if (filter) { 978875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen setTextKeepState(text); 979875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen } else { 980875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen mBlockCompletion = true; 981875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen setTextKeepState(text); 982875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen mBlockCompletion = false; 983875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen } 984875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen } 985875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen 986875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen /** 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Performs the text completion by replacing the current text by the 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * selected item. Subclasses should override this method to avoid replacing 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the whole content of the edit box.</p> 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param text the selected suggestion in the drop down list 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void replaceText(CharSequence text) { 994c1d2748d442f06a7266be04b9e9c7d20609ad5ccDaisuke Miyakawa clearComposingText(); 995c1d2748d442f06a7266be04b9e9c7d20609ad5ccDaisuke Miyakawa 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setText(text); 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // make sure we keep the caret at the end of the text view 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Editable spannable = getText(); 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Selection.setSelection(spannable, spannable.length()); 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1002875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen /** {@inheritDoc} */ 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onFilterComplete(int count) { 100450145bc883909c4b1533894a2b947eed21312514Bjorn Bringert // Not attached to window, don't update drop-down 100550145bc883909c4b1533894a2b947eed21312514Bjorn Bringert if (getWindowVisibility() == View.GONE) return; 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This checks enoughToFilter() again because filtering requests 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * are asynchronous, so the result may come back after enough text 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * has since been deleted to make it no longer appropriate 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to filter. 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1014875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen if ((count > 0 || mDropDownAlwaysVisible) && enoughToFilter()) { 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (hasFocus() && hasWindowFocus()) { 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project showDropDown(); 10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10187299807d1895ea25cbe45d32b6edfd9a5723ee7aRomain Guy } else if (!mDropDownAlwaysVisible) { 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dismissDropDown(); 10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onWindowFocusChanged(boolean hasWindowFocus) { 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onWindowFocusChanged(hasWindowFocus); 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project performValidation(); 10277299807d1895ea25cbe45d32b6edfd9a5723ee7aRomain Guy if (!hasWindowFocus && !mDropDownAlwaysVisible) { 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dismissDropDown(); 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onFocusChanged(focused, direction, previouslyFocusedRect); 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project performValidation(); 10367299807d1895ea25cbe45d32b6edfd9a5723ee7aRomain Guy if (!focused && !mDropDownAlwaysVisible) { 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dismissDropDown(); 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onAttachedToWindow() { 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onAttachedToWindow(); 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onDetachedFromWindow() { 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dismissDropDown(); 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onDetachedFromWindow(); 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Closes the drop down if present on screen.</p> 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dismissDropDown() { 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputMethodManager imm = InputMethodManager.peekInstance(); 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (imm != null) { 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project imm.displayCompletions(this, null); 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPopup.dismiss(); 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPopup.setContentView(null); 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownList = null; 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected boolean setFrame(int l, int t, int r, int b) { 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean result = super.setFrame(l, t, r, b); 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPopup.isShowing()) { 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPopup.update(this, r - l, -1); 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Used for lazy instantiation of the anchor view from the id we have. If the value of 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the id is NO_ID or we can't find a view for the given id, we return this TextView as 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the default anchoring point.</p> 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View getDropDownAnchorView() { 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDropDownAnchorView == null && mDropDownAnchorId != View.NO_ID) { 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownAnchorView = getRootView().findViewById(mDropDownAnchorId); 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDropDownAnchorView == null ? this : mDropDownAnchorView; 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1089fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath * Issues a runnable to show the dropdown as soon as possible. 10901b1a6e406c4233b309baee85e14f5a563ca63c48Satish Sampath * 1091ffe3ecf2b1ee04288008758c0f60ae22238797c1Mike LeBeau * @hide internal used only by SearchDialog 1092fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath */ 1093fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath public void showDropDownAfterLayout() { 1094fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath post(mShowDropDownRunnable); 1095fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath } 1096ffe3ecf2b1ee04288008758c0f60ae22238797c1Mike LeBeau 1097ffe3ecf2b1ee04288008758c0f60ae22238797c1Mike LeBeau /** 1098ffe3ecf2b1ee04288008758c0f60ae22238797c1Mike LeBeau * Ensures that the drop down is not obscuring the IME. 1099ffe3ecf2b1ee04288008758c0f60ae22238797c1Mike LeBeau * 1100ffe3ecf2b1ee04288008758c0f60ae22238797c1Mike LeBeau * @hide internal used only here and SearchDialog 1101ffe3ecf2b1ee04288008758c0f60ae22238797c1Mike LeBeau */ 1102ffe3ecf2b1ee04288008758c0f60ae22238797c1Mike LeBeau public void ensureImeVisible() { 1103ffe3ecf2b1ee04288008758c0f60ae22238797c1Mike LeBeau mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); 1104ffe3ecf2b1ee04288008758c0f60ae22238797c1Mike LeBeau showDropDown(); 1105ffe3ecf2b1ee04288008758c0f60ae22238797c1Mike LeBeau } 1106fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath 1107fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath /** 1108003ad48380fe90556da408fedba7dfc1a37790b9Bjorn Bringert * @hide internal used only here and SearchDialog 1109003ad48380fe90556da408fedba7dfc1a37790b9Bjorn Bringert */ 1110003ad48380fe90556da408fedba7dfc1a37790b9Bjorn Bringert public boolean isInputMethodNotNeeded() { 1111003ad48380fe90556da408fedba7dfc1a37790b9Bjorn Bringert return mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED; 1112003ad48380fe90556da408fedba7dfc1a37790b9Bjorn Bringert } 1113003ad48380fe90556da408fedba7dfc1a37790b9Bjorn Bringert 1114003ad48380fe90556da408fedba7dfc1a37790b9Bjorn Bringert /** 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Displays the drop down on screen.</p> 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void showDropDown() { 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int height = buildDropDown(); 1119e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy 1120e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy int widthSpec = 0; 1121e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy int heightSpec = 0; 1122e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy 1123003ad48380fe90556da408fedba7dfc1a37790b9Bjorn Bringert boolean noInputMethod = isInputMethodNotNeeded(); 1124e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPopup.isShowing()) { 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDropDownWidth == ViewGroup.LayoutParams.FILL_PARENT) { 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The call to PopupWindow's update method below can accept -1 for any 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // value you do not want to update. 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project widthSpec = -1; 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) { 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project widthSpec = getDropDownAnchorView().getWidth(); 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project widthSpec = mDropDownWidth; 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1135e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy 1136e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy if (mDropDownHeight == ViewGroup.LayoutParams.FILL_PARENT) { 1137e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy // The call to PopupWindow's update method below can accept -1 for any 1138e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy // value you do not want to update. 1139e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy heightSpec = noInputMethod ? height : ViewGroup.LayoutParams.FILL_PARENT; 1140e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy if (noInputMethod) { 1141e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy mPopup.setWindowLayoutMode( 1142e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy mDropDownWidth == ViewGroup.LayoutParams.FILL_PARENT ? 1143e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy ViewGroup.LayoutParams.FILL_PARENT : 0, 0); 1144e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy } else { 1145e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy mPopup.setWindowLayoutMode( 1146e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy mDropDownWidth == ViewGroup.LayoutParams.FILL_PARENT ? 1147e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy ViewGroup.LayoutParams.FILL_PARENT : 0, 1148e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy ViewGroup.LayoutParams.FILL_PARENT); 1149e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy } 1150e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy } else if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) { 1151e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy heightSpec = height; 1152e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy } else { 1153e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy heightSpec = mDropDownHeight; 1154e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy } 1155e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy 1156d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau mPopup.setOutsideTouchable(mForceIgnoreOutsideTouch ? false : !mDropDownAlwaysVisible); 1157d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPopup.update(getDropDownAnchorView(), mDropDownHorizontalOffset, 1159e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy mDropDownVerticalOffset, widthSpec, heightSpec); 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDropDownWidth == ViewGroup.LayoutParams.FILL_PARENT) { 1162e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy widthSpec = ViewGroup.LayoutParams.FILL_PARENT; 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) { 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPopup.setWidth(getDropDownAnchorView().getWidth()); 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPopup.setWidth(mDropDownWidth); 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1170e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy 1171e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy if (mDropDownHeight == ViewGroup.LayoutParams.FILL_PARENT) { 1172e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy heightSpec = ViewGroup.LayoutParams.FILL_PARENT; 1173e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy } else { 1174e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) { 1175e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy mPopup.setHeight(height); 1176e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy } else { 1177e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy mPopup.setHeight(mDropDownHeight); 1178e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy } 1179e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy } 1180e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy 1181e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy mPopup.setWindowLayoutMode(widthSpec, heightSpec); 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); 118398e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen 118498e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen // use outside touchable to dismiss drop down when touching outside of it, so 118598e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen // only set this if the dropdown is not always visible 1186d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau mPopup.setOutsideTouchable(mForceIgnoreOutsideTouch ? false : !mDropDownAlwaysVisible); 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPopup.setTouchInterceptor(new PopupTouchIntercepter()); 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPopup.showAsDropDown(getDropDownAnchorView(), 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownHorizontalOffset, mDropDownVerticalOffset); 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownList.setSelection(ListView.INVALID_POSITION); 1191465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy clearListSelection(); 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project post(mHideSelector); 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1195d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau 1196d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau /** 1197d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau * Forces outside touches to be ignored. Normally if {@link #isDropDownAlwaysVisible()} is 1198d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau * false, we allow outside touch to dismiss the dropdown. If this is set to true, then we 1199d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau * ignore outside touch even when the drop down is not set to always visible. 1200d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau * 1201d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau * @hide used only by SearchDialog 1202d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau */ 1203d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau public void setForceIgnoreOutsideTouch(boolean forceIgnoreOutsideTouch) { 1204d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau mForceIgnoreOutsideTouch = forceIgnoreOutsideTouch; 1205d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau } 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Builds the popup window's content and returns the height the popup 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should have. Returns -1 when the content already exists.</p> 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the content's height or -1 if content already exists 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int buildDropDown() { 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewGroup dropDownView; 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int otherHeights = 0; 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAdapter != null) { 12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputMethodManager imm = InputMethodManager.peekInstance(); 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (imm != null) { 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int N = mAdapter.getCount(); 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (N > 20) N = 20; 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CompletionInfo[] completions = new CompletionInfo[N]; 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < N; i++) { 12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object item = mAdapter.getItem(i); 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long id = mAdapter.getItemId(i); 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project completions[i] = new CompletionInfo(id, i, 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project convertSelectionToString(item)); 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project imm.displayCompletions(this, completions); 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDropDownList == null) { 12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Context context = getContext(); 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHideSelector = new ListSelectorHider(); 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1238fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath /** 1239fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath * This Runnable exists for the sole purpose of checking if the view layout has got 1240fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath * completed and if so call showDropDown to display the drop down. This is used to show 1241fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath * the drop down as soon as possible after user opens up the search dialog, without 1242fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath * waiting for the normal UI pipeline to do it's job which is slower than this method. 1243fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath */ 1244fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath mShowDropDownRunnable = new Runnable() { 1245fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath public void run() { 1246fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath // View layout should be all done before displaying the drop down. 1247fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath View view = getDropDownAnchorView(); 1248fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath if (view != null && view.getWindowToken() != null) { 1249fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath showDropDown(); 1250fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath } 1251fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath } 1252fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath }; 1253fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath 12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownList = new DropDownListView(context); 12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownList.setSelector(mDropDownListHighlight); 12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownList.setAdapter(mAdapter); 12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownList.setVerticalFadingEdgeEnabled(true); 12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownList.setOnItemClickListener(mDropDownItemClickListener); 12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownList.setFocusable(true); 12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownList.setFocusableInTouchMode(true); 1261465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy mDropDownList.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 1262465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy public void onItemSelected(AdapterView<?> parent, View view, 1263465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy int position, long id) { 1264465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy 1265465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy if (position != -1) { 1266d072154bddbfda8eb99a65b724922785f896f8ebEric Fischer DropDownListView dropDownList = mDropDownList; 1267d072154bddbfda8eb99a65b724922785f896f8ebEric Fischer 1268d072154bddbfda8eb99a65b724922785f896f8ebEric Fischer if (dropDownList != null) { 1269d072154bddbfda8eb99a65b724922785f896f8ebEric Fischer dropDownList.mListSelectionHidden = false; 1270d072154bddbfda8eb99a65b724922785f896f8ebEric Fischer } 1271465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy } 1272465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy } 1273465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy 1274465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy public void onNothingSelected(AdapterView<?> parent) { 1275465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy } 1276465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy }); 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mItemSelectedListener != null) { 12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDropDownList.setOnItemSelectedListener(mItemSelectedListener); 12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dropDownView = mDropDownList; 12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View hintView = getHintView(context); 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (hintView != null) { 12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if an hint has been specified, we accomodate more space for it and 12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // add a text view in the drop down menu, at the bottom of the list 12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LinearLayout hintContainer = new LinearLayout(context); 12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hintContainer.setOrientation(LinearLayout.VERTICAL); 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LinearLayout.LayoutParams hintParams = new LinearLayout.LayoutParams( 12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewGroup.LayoutParams.FILL_PARENT, 0, 1.0f 12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ); 12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hintContainer.addView(dropDownView, hintParams); 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hintContainer.addView(hintView); 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // measure the hint's height to find how much more vertical space 12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we need to add to the drop down's height 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int widthSpec = MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST); 13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int heightSpec = MeasureSpec.UNSPECIFIED; 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hintView.measure(widthSpec, heightSpec); 13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hintParams = (LinearLayout.LayoutParams) hintView.getLayoutParams(); 13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project otherHeights = hintView.getMeasuredHeight() + hintParams.topMargin 13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + hintParams.bottomMargin; 13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dropDownView = hintContainer; 13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPopup.setContentView(dropDownView); 13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dropDownView = (ViewGroup) mPopup.getContentView(); 13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View view = dropDownView.findViewById(HINT_VIEW_ID); 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (view != null) { 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LinearLayout.LayoutParams hintParams = 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (LinearLayout.LayoutParams) view.getLayoutParams(); 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project otherHeights = view.getMeasuredHeight() + hintParams.topMargin 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + hintParams.bottomMargin; 13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 132200a5b99229e41c173afd3071f15aaa725f531814Bjorn Bringert // Max height available on the screen for a popup. 132300a5b99229e41c173afd3071f15aaa725f531814Bjorn Bringert boolean ignoreBottomDecorations = 132498acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED; 132598acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau final int maxHeight = mPopup.getMaxAvailableHeight( 132698acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau getDropDownAnchorView(), mDropDownVerticalOffset, ignoreBottomDecorations); 13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1328e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy if (mDropDownAlwaysVisible) { 13295420d01cef810c34d754cadfaa1e8cae13af06deBjorn Bringert // getMaxAvailableHeight() subtracts the padding, so we put it back, 13305420d01cef810c34d754cadfaa1e8cae13af06deBjorn Bringert // to get the available height for the whole window 13315420d01cef810c34d754cadfaa1e8cae13af06deBjorn Bringert int padding = 0; 13325420d01cef810c34d754cadfaa1e8cae13af06deBjorn Bringert Drawable background = mPopup.getBackground(); 13335420d01cef810c34d754cadfaa1e8cae13af06deBjorn Bringert if (background != null) { 13345420d01cef810c34d754cadfaa1e8cae13af06deBjorn Bringert background.getPadding(mTempRect); 13355420d01cef810c34d754cadfaa1e8cae13af06deBjorn Bringert padding = mTempRect.top + mTempRect.bottom; 13365420d01cef810c34d754cadfaa1e8cae13af06deBjorn Bringert } 13375420d01cef810c34d754cadfaa1e8cae13af06deBjorn Bringert return maxHeight + padding; 1338e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy } 1339875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen 1340e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy return mDropDownList.measureHeightOfChildren(MeasureSpec.UNSPECIFIED, 1341e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy 0, ListView.NO_POSITION, maxHeight - otherHeights, 2) + otherHeights; 13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View getHintView(Context context) { 13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHintText != null && mHintText.length() > 0) { 13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final TextView hintView = (TextView) LayoutInflater.from(context).inflate( 13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHintResource, null).findViewById(com.android.internal.R.id.text1); 13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hintView.setText(mHintText); 13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hintView.setId(HINT_VIEW_ID); 13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return hintView; 13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the validator used to perform text validation. 13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param validator The validator used to validate the text entered in this widget. 13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getValidator() 13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #performValidation() 13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setValidator(Validator validator) { 13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mValidator = validator; 13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the Validator set with {@link #setValidator}, 13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or <code>null</code> if it was not set. 13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setValidator(android.widget.AutoCompleteTextView.Validator) 13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #performValidation() 13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Validator getValidator() { 13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mValidator; 13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If a validator was set on this view and the current string is not valid, 13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ask the validator to fix it. 13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getValidator() 13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setValidator(android.widget.AutoCompleteTextView.Validator) 13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void performValidation() { 13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mValidator == null) return; 13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CharSequence text = getText(); 13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!TextUtils.isEmpty(text) && !mValidator.isValid(text)) { 13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setText(mValidator.fixText(text)); 13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the Filter obtained from {@link Filterable#getFilter}, 13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or <code>null</code> if {@link #setAdapter} was not called with 13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a Filterable. 14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected Filter getFilter() { 14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFilter; 14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class ListSelectorHider implements Runnable { 14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 1407465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy clearListSelection(); 14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class PopupTouchIntercepter implements OnTouchListener { 14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onTouch(View v, MotionEvent event) { 14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event.getAction() == MotionEvent.ACTION_DOWN) { 14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); 141598acd54fa6657e8131b3a2a957de7882a2f511abMike LeBeau showDropDown(); 14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class DropDownItemClickListener implements AdapterView.OnItemClickListener { 14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onItemClick(AdapterView parent, View v, int position, long id) { 14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project performCompletion(v, position, id); 14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Wrapper class for a ListView. This wrapper hijacks the focus to 14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * make sure the list uses the appropriate drawables and states when 14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * displayed on screen within a drop down. The focus is never actually 14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * passed to the drop down; the list only looks focused.</p> 14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static class DropDownListView extends ListView { 1434465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy /* 1435465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * WARNING: This is a workaround for a touch mode issue. 1436465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * 1437465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * Touch mode is propagated lazily to windows. This causes problems in 1438465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * the following scenario: 1439465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * - Type something in the AutoCompleteTextView and get some results 1440465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * - Move down with the d-pad to select an item in the list 1441465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * - Move up with the d-pad until the selection disappears 1442465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * - Type more text in the AutoCompleteTextView *using the soft keyboard* 1443465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * and get new results; you are now in touch mode 1444465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * - The selection comes back on the first item in the list, even though 1445465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * the list is supposed to be in touch mode 1446465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * 1447465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * Using the soft keyboard triggers the touch mode change but that change 1448465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * is propagated to our window only after the first list layout, therefore 1449465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * after the list attempts to resurrect the selection. 1450465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * 1451465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * The trick to work around this issue is to pretend the list is in touch 1452465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * mode when we know that the selection should not appear, that is when 1453465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * we know the user moved the selection away from the list. 1454465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * 1455465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * This boolean is set to true whenever we explicitely hide the list's 1456465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * selection and reset to false whenver we know the user moved the 1457465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * selection back to the list. 1458465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * 1459465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * When this boolean is true, isInTouchMode() returns true, otherwise it 1460465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy * returns super.isInTouchMode(). 1461465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy */ 1462465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy private boolean mListSelectionHidden; 1463465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy 14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Creates a new list view wrapper.</p> 14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context this view's context 14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public DropDownListView(Context context) { 14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(context, null, com.android.internal.R.attr.dropDownListViewStyle); 14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Avoids jarring scrolling effect by ensuring that list elements 14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * made of a text view fit on a single line.</p> 14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param position the item index in the list to get a view for 14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the view for the specified item 14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected View obtainView(int position) { 14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View view = super.obtainView(position); 14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (view instanceof TextView) { 14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((TextView) view).setHorizontallyScrolling(true); 14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return view; 14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Returns the top padding of the currently selected view.</p> 14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the height of the top padding for the selection 14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getSelectionPaddingTop() { 14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSelectionTopPadding; 14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Returns the bottom padding of the currently selected view.</p> 15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the height of the bottom padding for the selection 15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getSelectionPaddingBottom() { 15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSelectionBottomPadding; 15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1509465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy @Override 1510465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy public boolean isInTouchMode() { 1511465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy // WARNING: Please read the comment where mListSelectionHidden is declared 1512465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy return mListSelectionHidden || super.isInTouchMode(); 1513465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy } 1514465dee4b4b491fdbb082218e5eb1010a416992f9Romain Guy 15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Returns the focus state in the drop down.</p> 15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true always 15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean hasWindowFocus() { 15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Returns the focus state in the drop down.</p> 15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true always 15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isFocused() { 15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Returns the focus state in the drop down.</p> 15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true always 15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean hasFocus() { 15429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 15439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected int[] onCreateDrawableState(int extraSpace) { 15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] res = super.onCreateDrawableState(extraSpace); 1547c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project //noinspection ConstantIfStatement 15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (false) { 15499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project StringBuilder sb = new StringBuilder("Created drawable state: ["); 15509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<res.length; i++) { 15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i > 0) sb.append(", "); 15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append("0x"); 15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append(Integer.toHexString(res[i])); 15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sb.append("]"); 15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.i(TAG, sb.toString()); 15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return res; 15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This interface is used to make sure that the text entered in this TextView complies to 15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a certain format. Since there is no foolproof way to prevent the user from leaving 15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this View with an incorrect value in it, all we can do is try to fix it ourselves 15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when this happens. 15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface Validator { 15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Validates the specified text. 15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true If the text currently in the text editor is valid. 15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #fixText(CharSequence) 15759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isValid(CharSequence text); 15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Corrects the specified text to make it valid. 15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param invalidText A string that doesn't pass validation: isValid(invalidText) 15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * returns false 15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return A string based on invalidText such as invoking isValid() on it returns true. 15859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #isValid(CharSequence) 15879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CharSequence fixText(CharSequence invalidText); 15899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1590ddf9856c7de043674d9ede006aefc7769879a4b8Mike LeBeau 159198e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen /** 159298e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen * Allows us a private hook into the on click event without preventing users from setting 159398e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen * their own click listener. 159498e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen */ 159598e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen private class PassThroughClickListener implements OnClickListener { 159698e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen 159798e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen private View.OnClickListener mWrapped; 159898e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen 159998e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen /** {@inheritDoc} */ 160098e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen public void onClick(View v) { 160198e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen onClickImpl(); 160298e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen 160398e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen if (mWrapped != null) mWrapped.onClick(v); 160498e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen } 160598e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen } 1606ddf9856c7de043674d9ede006aefc7769879a4b8Mike LeBeau 16079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1608