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;
216a67810228d02e75446d55c4c353275c87e9e769Romain Guyimport android.database.DataSetObserver;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.Drawable;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.Editable;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.Selection;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextWatcher;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyEvent;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.LayoutInflater;
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.EditorInfo;
37c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.inputmethod.InputMethodManager;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
39688df79243762923f6cd34f767cb2f690b11a48cGilles Debunneimport com.android.internal.R;
40688df79243762923f6cd34f767cb2f690b11a48cGilles Debunne
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&lt;String&gt; adapter = new ArrayAdapter&lt;String&gt;(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 *
784c359b76f9a030f92a302ba74a528faa170bad4eScott Main * <p>See the <a href="{@docRoot}guide/topics/ui/controls/text.html">Text Fields</a>
794c359b76f9a030f92a302ba74a528faa170bad4eScott Main * guide.</p>
8041ec65355bd6ded652769725b276d47c54a0d913Scott Main *
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#AutoCompleteTextView_completionHint
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#AutoCompleteTextView_completionThreshold
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#AutoCompleteTextView_completionHintView
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#AutoCompleteTextView_dropDownSelector
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#AutoCompleteTextView_dropDownAnchor
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#AutoCompleteTextView_dropDownWidth
87e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy * @attr ref android.R.styleable#AutoCompleteTextView_dropDownHeight
88aa1c6311d6d900261bcd9f3b0986b6c0394af07aRomain Guy * @attr ref android.R.styleable#AutoCompleteTextView_dropDownVerticalOffset
89aa1c6311d6d900261bcd9f3b0986b6c0394af07aRomain Guy * @attr ref android.R.styleable#AutoCompleteTextView_dropDownHorizontalOffset
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class AutoCompleteTextView extends EditText implements Filter.FilterListener {
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final boolean DEBUG = false;
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String TAG = "AutoCompleteTextView";
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
95348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell    static final int EXPAND_MAX = 3;
96348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private CharSequence mHintText;
98c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private TextView mHintView;
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mHintResource;
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private ListAdapter mAdapter;
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Filter mFilter;
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mThreshold;
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
105c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private ListPopupWindow mPopup;
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mDropDownAnchorId;
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private AdapterView.OnItemClickListener mItemClickListener;
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private AdapterView.OnItemSelectedListener mItemSelectedListener;
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
111875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    private boolean mDropDownDismissedOnCompletion = true;
112875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mLastKeyCode = KeyEvent.KEYCODE_UNKNOWN;
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mOpenBefore;
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Validator mValidator = null;
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
118be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne    // Set to true when text is set directly and no filtering shall be performed
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mBlockCompletion;
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1214a74dbc3f2221af99f94b4f514b8291a16ae3661Gilles Debunne    // When set, an update in the underlying adapter will update the result list popup.
1224a74dbc3f2221af99f94b4f514b8291a16ae3661Gilles Debunne    // Set to false when the list is hidden to prevent asynchronous updates to popup the list again.
1234a74dbc3f2221af99f94b4f514b8291a16ae3661Gilles Debunne    private boolean mPopupCanBeUpdated = true;
1244a74dbc3f2221af99f94b4f514b8291a16ae3661Gilles Debunne
1256a67810228d02e75446d55c4c353275c87e9e769Romain Guy    private PassThroughClickListener mPassThroughClickListener;
1266a67810228d02e75446d55c4c353275c87e9e769Romain Guy    private PopupDataSetObserver mObserver;
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public AutoCompleteTextView(Context context) {
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(context, null);
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public AutoCompleteTextView(Context context, AttributeSet attrs) {
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        this(context, attrs, com.android.internal.R.attr.autoCompleteTextViewStyle);
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public AutoCompleteTextView(Context context, AttributeSet attrs, int defStyle) {
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super(context, attrs, defStyle);
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
139c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup = new ListPopupWindow(context, attrs,
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                com.android.internal.R.attr.autoCompleteTextViewStyle);
141374aaaed32daa8482d98ec16988b2b51547f035dRomain Guy        mPopup.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
142c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.setPromptPosition(ListPopupWindow.POSITION_PROMPT_BELOW);
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TypedArray a =
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            context.obtainStyledAttributes(
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                attrs, com.android.internal.R.styleable.AutoCompleteTextView, defStyle, 0);
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mThreshold = a.getInt(
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                R.styleable.AutoCompleteTextView_completionThreshold, 2);
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
151c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.setListSelector(a.getDrawable(R.styleable.AutoCompleteTextView_dropDownSelector));
152c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.setVerticalOffset((int)
153c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                a.getDimension(R.styleable.AutoCompleteTextView_dropDownVerticalOffset, 0.0f));
154c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.setHorizontalOffset((int)
155c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                a.getDimension(R.styleable.AutoCompleteTextView_dropDownHorizontalOffset, 0.0f));
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Get the anchor's id now, but the view won't be ready, so wait to actually get the
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // view and store it in mDropDownAnchorView lazily in getDropDownAnchorView later.
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Defaults to NO_ID, in which case the getDropDownAnchorView method will simply return
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // this TextView, as a default anchoring point.
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDropDownAnchorId = a.getResourceId(R.styleable.AutoCompleteTextView_dropDownAnchor,
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                View.NO_ID);
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
164980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy        // For dropdown width, the developer can specify a specific width, or MATCH_PARENT
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // (for full screen width) or WRAP_CONTENT (to match the width of the anchored view).
166c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.setWidth(a.getLayoutDimension(
167c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                R.styleable.AutoCompleteTextView_dropDownWidth,
168c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                ViewGroup.LayoutParams.WRAP_CONTENT));
169c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.setHeight(a.getLayoutDimension(
170c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                R.styleable.AutoCompleteTextView_dropDownHeight,
171c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                ViewGroup.LayoutParams.WRAP_CONTENT));
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHintResource = a.getResourceId(R.styleable.AutoCompleteTextView_completionHintView,
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                R.layout.simple_dropdown_hint);
175c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
176c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.setOnItemClickListener(new DropDownItemClickListener());
177c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        setCompletionHint(a.getText(R.styleable.AutoCompleteTextView_completionHint));
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Always turn on the auto complete input type flag, since it
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // makes no sense to use this widget without it.
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int inputType = getInputType();
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((inputType&EditorInfo.TYPE_MASK_CLASS)
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                == EditorInfo.TYPE_CLASS_TEXT) {
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            inputType |= EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE;
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setRawInputType(inputType);
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        a.recycle();
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setFocusable(true);
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        addTextChangedListener(new MyWatcher());
193ddf9856c7de043674d9ede006aefc7769879a4b8Mike LeBeau
19498e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen        mPassThroughClickListener = new PassThroughClickListener();
19598e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen        super.setOnClickListener(mPassThroughClickListener);
19698e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen    }
19798e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen
19898e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen    @Override
19998e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen    public void setOnClickListener(OnClickListener listener) {
20098e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen        mPassThroughClickListener.mWrapped = listener;
20198e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen    }
20298e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen
20398e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen    /**
20498e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen     * Private hook into the on click event, dispatched from {@link PassThroughClickListener}
20598e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen     */
20698e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen    private void onClickImpl() {
207d25eb35b6b80b6f8065ab39b1cf1abb1fd801234Amith Yamasani        // If the dropdown is showing, bring the keyboard to the front
208d25eb35b6b80b6f8065ab39b1cf1abb1fd801234Amith Yamasani        // when the user touches the text field.
209711734a2f8d7529df0ed1bce36da651fc835c144Gilles Debunne        if (isPopupShowing()) {
210d25eb35b6b80b6f8065ab39b1cf1abb1fd801234Amith Yamasani            ensureImeVisible(true);
21198e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen        }
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Sets the optional hint text that is displayed at the bottom of the
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the matching list.  This can be used as a cue to the user on how to
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * best use the list, or to provide extra information.</p>
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param hint the text to be displayed to the user
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2215c49d11a57b0c868e15b9b3a79a9985288b5e15dGilles Debunne     * @see #getCompletionHint()
2225c49d11a57b0c868e15b9b3a79a9985288b5e15dGilles Debunne     *
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @attr ref android.R.styleable#AutoCompleteTextView_completionHint
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setCompletionHint(CharSequence hint) {
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHintText = hint;
227c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (hint != null) {
228c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            if (mHintView == null) {
229c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                final TextView hintView = (TextView) LayoutInflater.from(getContext()).inflate(
230c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        mHintResource, null).findViewById(com.android.internal.R.id.text1);
231c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                hintView.setText(mHintText);
232c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                mHintView = hintView;
233c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                mPopup.setPromptView(hintView);
234c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            } else {
235c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                mHintView.setText(hint);
236c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            }
237c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        } else {
238c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            mPopup.setPromptView(null);
239c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            mHintView = null;
240c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2425c49d11a57b0c868e15b9b3a79a9985288b5e15dGilles Debunne
2435c49d11a57b0c868e15b9b3a79a9985288b5e15dGilles Debunne    /**
2445c49d11a57b0c868e15b9b3a79a9985288b5e15dGilles Debunne     * Gets the optional hint text displayed at the bottom of the the matching list.
2455c49d11a57b0c868e15b9b3a79a9985288b5e15dGilles Debunne     *
2465c49d11a57b0c868e15b9b3a79a9985288b5e15dGilles Debunne     * @return The hint text, if any
2475c49d11a57b0c868e15b9b3a79a9985288b5e15dGilles Debunne     *
2485c49d11a57b0c868e15b9b3a79a9985288b5e15dGilles Debunne     * @see #setCompletionHint(CharSequence)
2495c49d11a57b0c868e15b9b3a79a9985288b5e15dGilles Debunne     *
2505c49d11a57b0c868e15b9b3a79a9985288b5e15dGilles Debunne     * @attr ref android.R.styleable#AutoCompleteTextView_completionHint
2515c49d11a57b0c868e15b9b3a79a9985288b5e15dGilles Debunne     */
2525c49d11a57b0c868e15b9b3a79a9985288b5e15dGilles Debunne    public CharSequence getCompletionHint() {
2535c49d11a57b0c868e15b9b3a79a9985288b5e15dGilles Debunne        return mHintText;
2545c49d11a57b0c868e15b9b3a79a9985288b5e15dGilles Debunne    }
2555c49d11a57b0c868e15b9b3a79a9985288b5e15dGilles Debunne
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Returns the current width for the auto-complete drop down list. This can
258980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy     * be a fixed width, or {@link ViewGroup.LayoutParams#MATCH_PARENT} to fill the screen, or
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the width of its anchor view.</p>
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the width for the drop down list
2627b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     *
2637b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     * @attr ref android.R.styleable#AutoCompleteTextView_dropDownWidth
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getDropDownWidth() {
266c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mPopup.getWidth();
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Sets the current width for the auto-complete drop down list. This can
271980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy     * be a fixed width, or {@link ViewGroup.LayoutParams#MATCH_PARENT} to fill the screen, or
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the width of its anchor view.</p>
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width the width to use
2757b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     *
2767b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     * @attr ref android.R.styleable#AutoCompleteTextView_dropDownWidth
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setDropDownWidth(int width) {
279c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.setWidth(width);
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
281e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy
282e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy    /**
283e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     * <p>Returns the current height for the auto-complete drop down list. This can
284980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy     * be a fixed height, or {@link ViewGroup.LayoutParams#MATCH_PARENT} to fill
285e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     * the screen, or {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the height
286e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     * of the drop down's content.</p>
287e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     *
288e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     * @return the height for the drop down list
289e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     *
290e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     * @attr ref android.R.styleable#AutoCompleteTextView_dropDownHeight
291e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     */
292e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy    public int getDropDownHeight() {
293c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mPopup.getHeight();
294e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy    }
295e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy
296e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy    /**
297e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     * <p>Sets the current height for the auto-complete drop down list. This can
298980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy     * be a fixed height, or {@link ViewGroup.LayoutParams#MATCH_PARENT} to fill
299e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     * the screen, or {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the height
300e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     * of the drop down's content.</p>
301e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     *
302e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     * @param height the height to use
303e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     *
304e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     * @attr ref android.R.styleable#AutoCompleteTextView_dropDownHeight
305e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy     */
306e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy    public void setDropDownHeight(int height) {
307c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.setHeight(height);
308e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy    }
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Returns the id for the view that the auto-complete drop down list is anchored to.</p>
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the view's id, or {@link View#NO_ID} if none specified
3147b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     *
3157b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     * @attr ref android.R.styleable#AutoCompleteTextView_dropDownAnchor
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getDropDownAnchor() {
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mDropDownAnchorId;
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Sets the view to which the auto-complete drop down list should anchor. The view
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * corresponding to this id will not be loaded until the next time it is needed to avoid
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * loading a view which is not yet instantiated.</p>
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param id the id to anchor the drop down list view to
3277b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     *
3287b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     * @attr ref android.R.styleable#AutoCompleteTextView_dropDownAnchor
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setDropDownAnchor(int id) {
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDropDownAnchorId = id;
332c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.setAnchorView(null);
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3347b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project
3357b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project    /**
3367b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     * <p>Gets the background of the auto-complete drop-down list.</p>
3377b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     *
3387b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     * @return the background drawable
3397b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     *
3407b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     * @attr ref android.R.styleable#PopupWindow_popupBackground
3417b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     */
3427b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project    public Drawable getDropDownBackground() {
3437b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project        return mPopup.getBackground();
3447b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project    }
3457b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project
3467b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project    /**
3477b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     * <p>Sets the background of the auto-complete drop-down list.</p>
3487b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     *
3497b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     * @param d the drawable to set as the background
3507b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     *
3517b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     * @attr ref android.R.styleable#PopupWindow_popupBackground
3527b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     */
3537b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project    public void setDropDownBackgroundDrawable(Drawable d) {
3547b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project        mPopup.setBackgroundDrawable(d);
3557b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project    }
3567b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project
3577b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project    /**
3587b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     * <p>Sets the background of the auto-complete drop-down list.</p>
3597b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     *
3607b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     * @param id the id of the drawable to set as the background
3617b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     *
3627b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     * @attr ref android.R.styleable#PopupWindow_popupBackground
3637b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     */
3647b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project    public void setDropDownBackgroundResource(int id) {
3657b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project        mPopup.setBackgroundDrawable(getResources().getDrawable(id));
3667b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project    }
3677b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project
3687b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project    /**
3697b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     * <p>Sets the vertical offset used for the auto-complete drop-down list.</p>
3707b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     *
3717b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     * @param offset the vertical offset
3727b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     */
3737b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project    public void setDropDownVerticalOffset(int offset) {
374c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.setVerticalOffset(offset);
3757b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project    }
3767b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project
3777b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project    /**
3787b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     * <p>Gets the vertical offset used for the auto-complete drop-down list.</p>
3797b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     *
3807b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     * @return the vertical offset
3817b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     */
3827b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project    public int getDropDownVerticalOffset() {
383c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mPopup.getVerticalOffset();
3847b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project    }
3857b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project
3867b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project    /**
3877b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     * <p>Sets the horizontal offset used for the auto-complete drop-down list.</p>
3887b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     *
3897b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     * @param offset the horizontal offset
3907b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     */
3917b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project    public void setDropDownHorizontalOffset(int offset) {
392c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.setHorizontalOffset(offset);
3937b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project    }
3947b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project
3957b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project    /**
3967b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     * <p>Gets the horizontal offset used for the auto-complete drop-down list.</p>
3977b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     *
3987b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     * @return the horizontal offset
3997b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project     */
4007b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project    public int getDropDownHorizontalOffset() {
401c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mPopup.getHorizontalOffset();
4027b0b1ed979aa665175bf3952c8902ce13c763ab8The Android Open Source Project    }
4038f080ec4292be02fad9896260bbd3cf5461f9399The Android Open Source Project
404bff1389c9ab4442a6e278cf84ce37eadad21a9a1The Android Open Source Project     /**
405875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * <p>Sets the animation style of the auto-complete drop-down list.</p>
406875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *
407875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * <p>If the drop-down is showing, calling this method will take effect only
408875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * the next time the drop-down is shown.</p>
409875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *
410875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * @param animationStyle animation style to use when the drop-down appears
411875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *      and disappears.  Set to -1 for the default animation, 0 for no
412875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *      animation, or a resource identifier for an explicit animation.
413875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *
414875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * @hide Pending API council approval
415875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     */
416875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    public void setDropDownAnimationStyle(int animationStyle) {
417875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        mPopup.setAnimationStyle(animationStyle);
418875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    }
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
421875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * <p>Returns the animation style that is used when the drop-down list appears and disappears
422875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * </p>
423875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *
424875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * @return the animation style that is used when the drop-down list appears and disappears
425875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *
426875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * @hide Pending API council approval
427875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     */
428875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    public int getDropDownAnimationStyle() {
429875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        return mPopup.getAnimationStyle();
430875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    }
431875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen
432875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    /**
433875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * @return Whether the drop-down is visible as long as there is {@link #enoughToFilter()}
434875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *
435875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * @hide Pending API council approval
436875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     */
437875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    public boolean isDropDownAlwaysVisible() {
438c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mPopup.isDropDownAlwaysVisible();
439875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    }
440875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen
441875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    /**
442875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * Sets whether the drop-down should remain visible as long as there is there is
443875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * {@link #enoughToFilter()}.  This is useful if an unknown number of results are expected
444875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * to show up in the adapter sometime in the future.
445875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *
446875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * The drop-down will occupy the entire screen below {@link #getDropDownAnchor} regardless
447875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * of the size or content of the list.  {@link #getDropDownBackground()} will fill any space
448875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * that is not used by the list.
449875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *
450875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * @param dropDownAlwaysVisible Whether to keep the drop-down visible.
451875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *
452875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * @hide Pending API council approval
453875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     */
454875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    public void setDropDownAlwaysVisible(boolean dropDownAlwaysVisible) {
455c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.setDropDownAlwaysVisible(dropDownAlwaysVisible);
456875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    }
457875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen
458875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    /**
459875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * Checks whether the drop-down is dismissed when a suggestion is clicked.
460875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *
461875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * @hide Pending API council approval
462875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     */
463875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    public boolean isDropDownDismissedOnCompletion() {
464875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        return mDropDownDismissedOnCompletion;
465875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    }
4666a67810228d02e75446d55c4c353275c87e9e769Romain Guy
467875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    /**
468875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * Sets whether the drop-down is dismissed when a suggestion is clicked. This is
469875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * true by default.
470875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *
471875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * @param dropDownDismissedOnCompletion Whether to dismiss the drop-down.
472875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *
473875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * @hide Pending API council approval
474875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     */
475875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    public void setDropDownDismissedOnCompletion(boolean dropDownDismissedOnCompletion) {
476875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        mDropDownDismissedOnCompletion = dropDownDismissedOnCompletion;
477875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    }
478875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Returns the number of characters the user must type before the drop
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * down list is shown.</p>
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the minimum number of characters to type to show the drop down
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setThreshold(int)
4865c49d11a57b0c868e15b9b3a79a9985288b5e15dGilles Debunne     *
4875c49d11a57b0c868e15b9b3a79a9985288b5e15dGilles Debunne     * @attr ref android.R.styleable#AutoCompleteTextView_completionThreshold
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getThreshold() {
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mThreshold;
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Specifies the minimum number of characters the user has to type in the
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * edit box before the drop down list is shown.</p>
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>When <code>threshold</code> is less than or equals 0, a threshold of
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * 1 is applied.</p>
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param threshold the number of characters to type before the drop down
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                  is shown
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getThreshold()
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @attr ref android.R.styleable#AutoCompleteTextView_completionThreshold
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setThreshold(int threshold) {
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (threshold <= 0) {
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            threshold = 1;
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mThreshold = threshold;
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Sets the listener that will be notified when the user clicks an item
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in the drop down list.</p>
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param l the item click listener
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setOnItemClickListener(AdapterView.OnItemClickListener l) {
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mItemClickListener = l;
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Sets the listener that will be notified when the user selects an item
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in the drop down list.</p>
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param l the item selected listener
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener l) {
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mItemSelectedListener = l;
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Returns the listener that is notified whenever the user clicks an item
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in the drop down list.</p>
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the item click listener
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @deprecated Use {@link #getOnItemClickListener()} intead
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Deprecated
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public AdapterView.OnItemClickListener getItemClickListener() {
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mItemClickListener;
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Returns the listener that is notified whenever the user selects an
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * item in the drop down list.</p>
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the item selected listener
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @deprecated Use {@link #getOnItemSelectedListener()} intead
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Deprecated
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public AdapterView.OnItemSelectedListener getItemSelectedListener() {
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mItemSelectedListener;
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Returns the listener that is notified whenever the user clicks an item
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in the drop down list.</p>
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the item click listener
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public AdapterView.OnItemClickListener getOnItemClickListener() {
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mItemClickListener;
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Returns the listener that is notified whenever the user selects an
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * item in the drop down list.</p>
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the item selected listener
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public AdapterView.OnItemSelectedListener getOnItemSelectedListener() {
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mItemSelectedListener;
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
582780c491fb9905adb3782f34886bb23327ed8f456Adam Powell     * Set a listener that will be invoked whenever the AutoCompleteTextView's
583780c491fb9905adb3782f34886bb23327ed8f456Adam Powell     * list of completions is dismissed.
584780c491fb9905adb3782f34886bb23327ed8f456Adam Powell     * @param dismissListener Listener to invoke when completions are dismissed
585780c491fb9905adb3782f34886bb23327ed8f456Adam Powell     */
586780c491fb9905adb3782f34886bb23327ed8f456Adam Powell    public void setOnDismissListener(final OnDismissListener dismissListener) {
587780c491fb9905adb3782f34886bb23327ed8f456Adam Powell        PopupWindow.OnDismissListener wrappedListener = null;
588780c491fb9905adb3782f34886bb23327ed8f456Adam Powell        if (dismissListener != null) {
589780c491fb9905adb3782f34886bb23327ed8f456Adam Powell            wrappedListener = new PopupWindow.OnDismissListener() {
590780c491fb9905adb3782f34886bb23327ed8f456Adam Powell                @Override public void onDismiss() {
591780c491fb9905adb3782f34886bb23327ed8f456Adam Powell                    dismissListener.onDismiss();
592780c491fb9905adb3782f34886bb23327ed8f456Adam Powell                }
593780c491fb9905adb3782f34886bb23327ed8f456Adam Powell            };
594780c491fb9905adb3782f34886bb23327ed8f456Adam Powell        }
595780c491fb9905adb3782f34886bb23327ed8f456Adam Powell        mPopup.setOnDismissListener(wrappedListener);
596780c491fb9905adb3782f34886bb23327ed8f456Adam Powell    }
597780c491fb9905adb3782f34886bb23327ed8f456Adam Powell
598780c491fb9905adb3782f34886bb23327ed8f456Adam Powell    /**
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Returns a filterable list adapter used for auto completion.</p>
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a data adapter used for auto completion
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ListAdapter getAdapter() {
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mAdapter;
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Changes the list of data used for auto completion. The provided list
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * must be a filterable list adapter.</p>
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The caller is still responsible for managing any resources used by the adapter.
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Notably, when the AutoCompleteTextView is closed or released, the adapter is not notified.
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * A common case is the use of {@link android.widget.CursorAdapter}, which
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * contains a {@link android.database.Cursor} that must be closed.  This can be done
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * automatically (see
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.app.Activity#startManagingCursor(android.database.Cursor)
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * startManagingCursor()}),
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or by manually closing the cursor when the AutoCompleteTextView is dismissed.</p>
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param adapter the adapter holding the auto completion data
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getAdapter()
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.widget.Filterable
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.widget.ListAdapter
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public <T extends ListAdapter & Filterable> void setAdapter(T adapter) {
6276a67810228d02e75446d55c4c353275c87e9e769Romain Guy        if (mObserver == null) {
6286a67810228d02e75446d55c4c353275c87e9e769Romain Guy            mObserver = new PopupDataSetObserver();
6296a67810228d02e75446d55c4c353275c87e9e769Romain Guy        } else if (mAdapter != null) {
6306a67810228d02e75446d55c4c353275c87e9e769Romain Guy            mAdapter.unregisterDataSetObserver(mObserver);
6316a67810228d02e75446d55c4c353275c87e9e769Romain Guy        }
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAdapter = adapter;
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mAdapter != null) {
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //noinspection unchecked
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mFilter = ((Filterable) mAdapter).getFilter();
6366a67810228d02e75446d55c4c353275c87e9e769Romain Guy            adapter.registerDataSetObserver(mObserver);
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mFilter = null;
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
641c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.setAdapter(mAdapter);
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
6468d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn        if (keyCode == KeyEvent.KEYCODE_BACK && isPopupShowing()
647c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                && !mPopup.isDropDownAlwaysVisible()) {
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // special case for the back key, we do not even try to send it
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // to the drop down list but instead, consume it immediately
6502beee4d11084f7b96dda6e335da0ebc08214dfb7Romain Guy            if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
651b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                KeyEvent.DispatcherState state = getKeyDispatcherState();
652b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                if (state != null) {
653b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                    state.startTracking(event, this);
654b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                }
6558d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                return true;
6564eb3efc8b270d2569fd813546f85add92e7f0ab0Bjorn Bringert            } else if (event.getAction() == KeyEvent.ACTION_UP) {
657b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                KeyEvent.DispatcherState state = getKeyDispatcherState();
658b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                if (state != null) {
659b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                    state.handleUpEvent(event);
660b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                }
6614eb3efc8b270d2569fd813546f85add92e7f0ab0Bjorn Bringert                if (event.isTracking() && !event.isCanceled()) {
6624eb3efc8b270d2569fd813546f85add92e7f0ab0Bjorn Bringert                    dismissDropDown();
6634eb3efc8b270d2569fd813546f85add92e7f0ab0Bjorn Bringert                    return true;
6644eb3efc8b270d2569fd813546f85add92e7f0ab0Bjorn Bringert                }
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return super.onKeyPreIme(keyCode, event);
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onKeyUp(int keyCode, KeyEvent event) {
672c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        boolean consumed = mPopup.onKeyUp(keyCode, event);
673c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (consumed) {
674c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            switch (keyCode) {
675c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            // if the list accepts the key events and the key event
676c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            // was a click, the text view gets the selected item
677c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            // from the drop down as its content
678c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            case KeyEvent.KEYCODE_ENTER:
679c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            case KeyEvent.KEYCODE_DPAD_CENTER:
6804e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown            case KeyEvent.KEYCODE_TAB:
6814e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown                if (event.hasNoModifiers()) {
6824e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown                    performCompletion();
6834e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown                }
684c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                return true;
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
687a4a5758b5f51834f7555ec909e8188c432fc5dc4Gilles Debunne
688a4a5758b5f51834f7555ec909e8188c432fc5dc4Gilles Debunne        if (isPopupShowing() && keyCode == KeyEvent.KEYCODE_TAB && event.hasNoModifiers()) {
689a4a5758b5f51834f7555ec909e8188c432fc5dc4Gilles Debunne            performCompletion();
690a4a5758b5f51834f7555ec909e8188c432fc5dc4Gilles Debunne            return true;
691a4a5758b5f51834f7555ec909e8188c432fc5dc4Gilles Debunne        }
692a4a5758b5f51834f7555ec909e8188c432fc5dc4Gilles Debunne
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return super.onKeyUp(keyCode, event);
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onKeyDown(int keyCode, KeyEvent event) {
698c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (mPopup.onKeyDown(keyCode, event)) {
699c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            return true;
700c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
701c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
702c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (!isPopupShowing()) {
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch(keyCode) {
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case KeyEvent.KEYCODE_DPAD_DOWN:
7054e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown                if (event.hasNoModifiers()) {
7064e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown                    performValidation();
7074e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown                }
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
711a4a5758b5f51834f7555ec909e8188c432fc5dc4Gilles Debunne        if (isPopupShowing() && keyCode == KeyEvent.KEYCODE_TAB && event.hasNoModifiers()) {
712a4a5758b5f51834f7555ec909e8188c432fc5dc4Gilles Debunne            return true;
713a4a5758b5f51834f7555ec909e8188c432fc5dc4Gilles Debunne        }
714a4a5758b5f51834f7555ec909e8188c432fc5dc4Gilles Debunne
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLastKeyCode = keyCode;
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean handled = super.onKeyDown(keyCode, event);
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLastKeyCode = KeyEvent.KEYCODE_UNKNOWN;
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
719c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (handled && isPopupShowing()) {
720c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project            clearListSelection();
721c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project        }
722c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return handled;
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns <code>true</code> if the amount of text in the field meets
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or exceeds the {@link #getThreshold} requirement.  You can override
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this to impose a different standard for when filtering will be
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * triggered.
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean enoughToFilter() {
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DEBUG) Log.v(TAG, "Enough to filter: len=" + getText().length()
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " threshold=" + mThreshold);
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return getText().length() >= mThreshold;
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is used to watch for edits to the text view.  Note that we call
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to methods on the auto complete text view class so that we can access
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * private vars without going through thunks.
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class MyWatcher implements TextWatcher {
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void afterTextChanged(Editable s) {
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            doAfterTextChanged();
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            doBeforeTextChanged();
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onTextChanged(CharSequence s, int start, int before, int count) {
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void doBeforeTextChanged() {
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBlockCompletion) return;
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // when text is changed, inserted or deleted, we attempt to show
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // the drop down
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOpenBefore = isPopupShowing();
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DEBUG) Log.v(TAG, "before text changed: open=" + mOpenBefore);
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void doAfterTextChanged() {
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mBlockCompletion) return;
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // if the list was open before the keystroke, but closed afterwards,
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // then something in the keystroke processing (an input filter perhaps)
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // called performCompletion() and we shouldn't do any more processing.
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DEBUG) Log.v(TAG, "after text changed: openBefore=" + mOpenBefore
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " open=" + isPopupShowing());
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mOpenBefore && !isPopupShowing()) {
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // the drop down is shown only when a minimum number of characters
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // was typed in the text view
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (enoughToFilter()) {
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mFilter != null) {
7794a74dbc3f2221af99f94b4f514b8291a16ae3661Gilles Debunne                mPopupCanBeUpdated = true;
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
7854a74dbc3f2221af99f94b4f514b8291a16ae3661Gilles Debunne            if (!mPopup.isDropDownAlwaysVisible()) {
7864a74dbc3f2221af99f94b4f514b8291a16ae3661Gilles Debunne                dismissDropDown();
7874a74dbc3f2221af99f94b4f514b8291a16ae3661Gilles Debunne            }
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mFilter != null) {
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mFilter.filter(null);
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Indicates whether the popup menu is showing.</p>
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if the popup menu is showing, false otherwise
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isPopupShowing() {
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mPopup.isShowing();
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Converts the selected item from the drop down list into a sequence
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of character that can be used in the edit box.</p>
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param selectedItem the item selected by the user for completion
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return a sequence of characters representing the selected suggestion
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected CharSequence convertSelectionToString(Object selectedItem) {
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mFilter.convertResultToString(selectedItem);
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Clear the list selection.  This may only be temporary, as user input will often bring
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * it back.
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void clearListSelection() {
820c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.clearListSelection();
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set the position of the dropdown view selection.
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param position The position to move the selector to.
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setListSelection(int position) {
829c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.setSelection(position);
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Get the position of the dropdown view selection, if there is one.  Returns
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ListView#INVALID_POSITION ListView.INVALID_POSITION} if there is no dropdown or if
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * there is no selection.
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the position of the current selection, if there is one, or
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link ListView#INVALID_POSITION ListView.INVALID_POSITION} if not.
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see ListView#getSelectedItemPosition()
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getListSelection() {
843c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mPopup.getSelectedItemPosition();
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
845ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project
846ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project    /**
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Starts filtering the content of the drop down list. The filtering
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * pattern is the content of the edit box. Subclasses should override this
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * method to filter with a different pattern, for instance a substring of
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <code>text</code>.</p>
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param text the filtering pattern
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param keyCode the last character inserted in the edit box; beware that
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this will be null when text is being added through a soft input method.
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SuppressWarnings({ "UnusedDeclaration" })
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void performFiltering(CharSequence text, int keyCode) {
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFilter.filter(text, this);
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Performs the text completion by converting the selected item from
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the drop down list into a string, replacing the text box's content with
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this string and finally dismissing the drop down menu.</p>
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void performCompletion() {
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        performCompletion(null, -1, -1);
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onCommitCompletion(CompletionInfo completion) {
8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isPopupShowing()) {
873c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            mPopup.performItemClick(completion.getPosition());
8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void performCompletion(View selectedView, int position, long id) {
8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isPopupShowing()) {
8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Object selectedItem;
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (position < 0) {
881c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                selectedItem = mPopup.getSelectedItem();
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                selectedItem = mAdapter.getItem(position);
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (selectedItem == null) {
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.w(TAG, "performCompletion: no selected item");
8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mBlockCompletion = true;
8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            replaceText(convertSelectionToString(selectedItem));
892be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne            mBlockCompletion = false;
8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mItemClickListener != null) {
895c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                final ListPopupWindow list = mPopup;
8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (selectedView == null || position < 0) {
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    selectedView = list.getSelectedView();
8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    position = list.getSelectedItemPosition();
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    id = list.getSelectedItemId();
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
902c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                mItemClickListener.onItemClick(list.getListView(), selectedView, position, id);
9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
906c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (mDropDownDismissedOnCompletion && !mPopup.isDropDownAlwaysVisible()) {
907875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen            dismissDropDown();
908875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        }
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Identifies whether the view is currently performing a text completion, so subclasses
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * can decide whether to respond to text changed events.
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isPerformingCompletion() {
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mBlockCompletion;
9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
920875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * Like {@link #setText(CharSequence)}, except that it can disable filtering.
921875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *
922875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * @param filter If <code>false</code>, no filtering will be performed
923875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *        as a result of this call.
924875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     */
925875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    public void setText(CharSequence text, boolean filter) {
926875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        if (filter) {
927875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen            setText(text);
928875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        } else {
929875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen            mBlockCompletion = true;
930875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen            setText(text);
931875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen            mBlockCompletion = false;
932875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        }
933875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    }
9346a67810228d02e75446d55c4c353275c87e9e769Romain Guy
935875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    /**
9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Performs the text completion by replacing the current text by the
9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * selected item. Subclasses should override this method to avoid replacing
9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the whole content of the edit box.</p>
9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param text the selected suggestion in the drop down list
9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void replaceText(CharSequence text) {
943c1d2748d442f06a7266be04b9e9c7d20609ad5ccDaisuke Miyakawa        clearComposingText();
944c1d2748d442f06a7266be04b9e9c7d20609ad5ccDaisuke Miyakawa
9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setText(text);
9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // make sure we keep the caret at the end of the text view
9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Editable spannable = getText();
9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Selection.setSelection(spannable, spannable.length());
9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
951875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    /** {@inheritDoc} */
9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onFilterComplete(int count) {
9534a74dbc3f2221af99f94b4f514b8291a16ae3661Gilles Debunne        updateDropDownForFilter(count);
9544f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy    }
9554f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy
9564a74dbc3f2221af99f94b4f514b8291a16ae3661Gilles Debunne    private void updateDropDownForFilter(int count) {
95750145bc883909c4b1533894a2b947eed21312514Bjorn Bringert        // Not attached to window, don't update drop-down
95850145bc883909c4b1533894a2b947eed21312514Bjorn Bringert        if (getWindowVisibility() == View.GONE) return;
9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * This checks enoughToFilter() again because filtering requests
9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * are asynchronous, so the result may come back after enough text
9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * has since been deleted to make it no longer appropriate
9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * to filter.
9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
967c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        final boolean dropDownAlwaysVisible = mPopup.isDropDownAlwaysVisible();
968d513e9746f09611db6478e368207ac7b112a253dGilles Debunne        final boolean enoughToFilter = enoughToFilter();
969d513e9746f09611db6478e368207ac7b112a253dGilles Debunne        if ((count > 0 || dropDownAlwaysVisible) && enoughToFilter) {
9704a74dbc3f2221af99f94b4f514b8291a16ae3661Gilles Debunne            if (hasFocus() && hasWindowFocus() && mPopupCanBeUpdated) {
9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                showDropDown();
9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9734a74dbc3f2221af99f94b4f514b8291a16ae3661Gilles Debunne        } else if (!dropDownAlwaysVisible && isPopupShowing()) {
9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dismissDropDown();
9754a74dbc3f2221af99f94b4f514b8291a16ae3661Gilles Debunne            // When the filter text is changed, the first update from the adapter may show an empty
9764a74dbc3f2221af99f94b4f514b8291a16ae3661Gilles Debunne            // count (when the query is being performed on the network). Future updates when some
9774a74dbc3f2221af99f94b4f514b8291a16ae3661Gilles Debunne            // content has been retrieved should still be able to update the list.
9784a74dbc3f2221af99f94b4f514b8291a16ae3661Gilles Debunne            mPopupCanBeUpdated = true;
9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onWindowFocusChanged(boolean hasWindowFocus) {
9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onWindowFocusChanged(hasWindowFocus);
985c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (!hasWindowFocus && !mPopup.isDropDownAlwaysVisible()) {
9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dismissDropDown();
9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
99143c9cdffb619f93d9d4525dffd05701dc9c8c4bfRomain Guy    protected void onDisplayHint(int hint) {
99243c9cdffb619f93d9d4525dffd05701dc9c8c4bfRomain Guy        super.onDisplayHint(hint);
99343c9cdffb619f93d9d4525dffd05701dc9c8c4bfRomain Guy        switch (hint) {
99443c9cdffb619f93d9d4525dffd05701dc9c8c4bfRomain Guy            case INVISIBLE:
995c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                if (!mPopup.isDropDownAlwaysVisible()) {
99643c9cdffb619f93d9d4525dffd05701dc9c8c4bfRomain Guy                    dismissDropDown();
99743c9cdffb619f93d9d4525dffd05701dc9c8c4bfRomain Guy                }
99843c9cdffb619f93d9d4525dffd05701dc9c8c4bfRomain Guy                break;
99943c9cdffb619f93d9d4525dffd05701dc9c8c4bfRomain Guy        }
100043c9cdffb619f93d9d4525dffd05701dc9c8c4bfRomain Guy    }
100143c9cdffb619f93d9d4525dffd05701dc9c8c4bfRomain Guy
100243c9cdffb619f93d9d4525dffd05701dc9c8c4bfRomain Guy    @Override
10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onFocusChanged(focused, direction, previouslyFocusedRect);
1005280c753ae30502a7ffa3648a2152b2b784327277Evan Millar        // Perform validation if the view is losing focus.
1006280c753ae30502a7ffa3648a2152b2b784327277Evan Millar        if (!focused) {
1007280c753ae30502a7ffa3648a2152b2b784327277Evan Millar            performValidation();
1008280c753ae30502a7ffa3648a2152b2b784327277Evan Millar        }
1009c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (!focused && !mPopup.isDropDownAlwaysVisible()) {
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dismissDropDown();
10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onAttachedToWindow() {
10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onAttachedToWindow();
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onDetachedFromWindow() {
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dismissDropDown();
10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onDetachedFromWindow();
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Closes the drop down if present on screen.</p>
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void dismissDropDown() {
10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputMethodManager imm = InputMethodManager.peekInstance();
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (imm != null) {
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            imm.displayCompletions(this, null);
10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPopup.dismiss();
10344a74dbc3f2221af99f94b4f514b8291a16ae3661Gilles Debunne        mPopupCanBeUpdated = false;
10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
10383e141685003939a9addce21ba2492ea3a8aebee6Romain Guy    protected boolean setFrame(final int l, int t, final int r, int b) {
10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean result = super.setFrame(l, t, r, b);
10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1041711734a2f8d7529df0ed1bce36da651fc835c144Gilles Debunne        if (isPopupShowing()) {
10423e141685003939a9addce21ba2492ea3a8aebee6Romain Guy            showDropDown();
10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return result;
10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1049fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath     * Issues a runnable to show the dropdown as soon as possible.
10501b1a6e406c4233b309baee85e14f5a563ca63c48Satish Sampath     *
1051ffe3ecf2b1ee04288008758c0f60ae22238797c1Mike LeBeau     * @hide internal used only by SearchDialog
1052fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath     */
1053fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath    public void showDropDownAfterLayout() {
1054c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.postShow();
1055fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath    }
1056ffe3ecf2b1ee04288008758c0f60ae22238797c1Mike LeBeau
1057ffe3ecf2b1ee04288008758c0f60ae22238797c1Mike LeBeau    /**
1058ffe3ecf2b1ee04288008758c0f60ae22238797c1Mike LeBeau     * Ensures that the drop down is not obscuring the IME.
1059d25eb35b6b80b6f8065ab39b1cf1abb1fd801234Amith Yamasani     * @param visible whether the ime should be in front. If false, the ime is pushed to
1060d25eb35b6b80b6f8065ab39b1cf1abb1fd801234Amith Yamasani     * the background.
1061ffe3ecf2b1ee04288008758c0f60ae22238797c1Mike LeBeau     * @hide internal used only here and SearchDialog
1062ffe3ecf2b1ee04288008758c0f60ae22238797c1Mike LeBeau     */
1063d25eb35b6b80b6f8065ab39b1cf1abb1fd801234Amith Yamasani    public void ensureImeVisible(boolean visible) {
1064d25eb35b6b80b6f8065ab39b1cf1abb1fd801234Amith Yamasani        mPopup.setInputMethodMode(visible
1065c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                ? ListPopupWindow.INPUT_METHOD_NEEDED : ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
1066c27cc01f6abf8564dc9b7b6cd7f2a12a347f725dRomain Guy        if (mPopup.isDropDownAlwaysVisible() || (mFilter != null && enoughToFilter())) {
1067c27cc01f6abf8564dc9b7b6cd7f2a12a347f725dRomain Guy            showDropDown();
1068c27cc01f6abf8564dc9b7b6cd7f2a12a347f725dRomain Guy        }
1069ffe3ecf2b1ee04288008758c0f60ae22238797c1Mike LeBeau    }
1070fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath
1071fef8d3e4d8f6f46c098d04b3a57409c947ec1c75Satish Sampath    /**
1072003ad48380fe90556da408fedba7dfc1a37790b9Bjorn Bringert     * @hide internal used only here and SearchDialog
1073003ad48380fe90556da408fedba7dfc1a37790b9Bjorn Bringert     */
1074003ad48380fe90556da408fedba7dfc1a37790b9Bjorn Bringert    public boolean isInputMethodNotNeeded() {
1075c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mPopup.getInputMethodMode() == ListPopupWindow.INPUT_METHOD_NOT_NEEDED;
1076003ad48380fe90556da408fedba7dfc1a37790b9Bjorn Bringert    }
1077003ad48380fe90556da408fedba7dfc1a37790b9Bjorn Bringert
1078003ad48380fe90556da408fedba7dfc1a37790b9Bjorn Bringert    /**
10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Displays the drop down on screen.</p>
10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void showDropDown() {
1082d513e9746f09611db6478e368207ac7b112a253dGilles Debunne        buildImeCompletions();
1083d513e9746f09611db6478e368207ac7b112a253dGilles Debunne
1084c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (mPopup.getAnchorView() == null) {
1085c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            if (mDropDownAnchorId != View.NO_ID) {
1086c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                mPopup.setAnchorView(getRootView().findViewById(mDropDownAnchorId));
1087e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy            } else {
1088c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                mPopup.setAnchorView(this);
1089e29f064383cbc745c8605c707000ab4e16ee0aacRomain Guy            }
10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1091711734a2f8d7529df0ed1bce36da651fc835c144Gilles Debunne        if (!isPopupShowing()) {
1092711734a2f8d7529df0ed1bce36da651fc835c144Gilles Debunne            // Make sure the list does not obscure the IME when shown for the first time.
1093711734a2f8d7529df0ed1bce36da651fc835c144Gilles Debunne            mPopup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NEEDED);
1094348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell            mPopup.setListItemExpandMax(EXPAND_MAX);
1095711734a2f8d7529df0ed1bce36da651fc835c144Gilles Debunne        }
1096c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.show();
1097348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell        mPopup.getListView().setOverScrollMode(View.OVER_SCROLL_ALWAYS);
10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1099d513e9746f09611db6478e368207ac7b112a253dGilles Debunne
1100d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau    /**
1101d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau     * Forces outside touches to be ignored. Normally if {@link #isDropDownAlwaysVisible()} is
1102d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau     * false, we allow outside touch to dismiss the dropdown. If this is set to true, then we
1103d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau     * ignore outside touch even when the drop down is not set to always visible.
1104d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau     *
1105d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau     * @hide used only by SearchDialog
1106d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau     */
1107d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau    public void setForceIgnoreOutsideTouch(boolean forceIgnoreOutsideTouch) {
1108c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.setForceIgnoreOutsideTouch(forceIgnoreOutsideTouch);
1109d4760d77e7e8ab66af0307dcae39e0a8e9d90a14Mike LeBeau    }
1110d513e9746f09611db6478e368207ac7b112a253dGilles Debunne
1111c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private void buildImeCompletions() {
11124f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy        final ListAdapter adapter = mAdapter;
11134f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy        if (adapter != null) {
11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputMethodManager imm = InputMethodManager.peekInstance();
11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (imm != null) {
11164f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy                final int count = Math.min(adapter.getCount(), 20);
11174f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy                CompletionInfo[] completions = new CompletionInfo[count];
11184f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy                int realCount = 0;
11194f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy
11204f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy                for (int i = 0; i < count; i++) {
11214f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy                    if (adapter.isEnabled(i)) {
11224f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy                        Object item = adapter.getItem(i);
11234f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy                        long id = adapter.getItemId(i);
1124f0d3b7ff72511c9f6b9bf228e5b14ba6a2e35f34Gilles Debunne                        completions[realCount] = new CompletionInfo(id, realCount,
1125f0d3b7ff72511c9f6b9bf228e5b14ba6a2e35f34Gilles Debunne                                convertSelectionToString(item));
1126f0d3b7ff72511c9f6b9bf228e5b14ba6a2e35f34Gilles Debunne                        realCount++;
11274f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy                    }
11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
11294f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy
11304f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy                if (realCount != count) {
11314f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy                    CompletionInfo[] tmp = new CompletionInfo[realCount];
11324f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy                    System.arraycopy(completions, 0, tmp, 0, realCount);
11334f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy                    completions = tmp;
11344f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy                }
11354f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy
11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                imm.displayCompletions(this, completions);
11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the validator used to perform text validation.
11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param validator The validator used to validate the text entered in this widget.
11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getValidator()
11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #performValidation()
11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setValidator(Validator validator) {
11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mValidator = validator;
11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the Validator set with {@link #setValidator},
11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or <code>null</code> if it was not set.
11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setValidator(android.widget.AutoCompleteTextView.Validator)
11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #performValidation()
11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Validator getValidator() {
11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mValidator;
11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If a validator was set on this view and the current string is not valid,
11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ask the validator to fix it.
11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #getValidator()
11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #setValidator(android.widget.AutoCompleteTextView.Validator)
11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void performValidation() {
11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mValidator == null) return;
11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CharSequence text = getText();
11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!TextUtils.isEmpty(text) && !mValidator.isValid(text)) {
11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setText(mValidator.fixText(text));
11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the Filter obtained from {@link Filterable#getFilter},
11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or <code>null</code> if {@link #setAdapter} was not called with
11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a Filterable.
11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected Filter getFilter() {
11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mFilter;
11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class DropDownItemClickListener implements AdapterView.OnItemClickListener {
11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onItemClick(AdapterView parent, View v, int position, long id) {
11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            performCompletion(v, position, id);
11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This interface is used to make sure that the text entered in this TextView complies to
11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a certain format.  Since there is no foolproof way to prevent the user from leaving
11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this View with an incorrect value in it, all we can do is try to fix it ourselves
12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when this happens.
12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface Validator {
12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Validates the specified text.
12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @return true If the text currently in the text editor is valid.
12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @see #fixText(CharSequence)
12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean isValid(CharSequence text);
12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Corrects the specified text to make it valid.
12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param invalidText A string that doesn't pass validation: isValid(invalidText)
12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *        returns false
12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @return A string based on invalidText such as invoking isValid() on it returns true.
12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @see #isValid(CharSequence)
12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CharSequence fixText(CharSequence invalidText);
12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1224ddf9856c7de043674d9ede006aefc7769879a4b8Mike LeBeau
122598e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen    /**
1226780c491fb9905adb3782f34886bb23327ed8f456Adam Powell     * Listener to respond to the AutoCompleteTextView's completion list being dismissed.
1227780c491fb9905adb3782f34886bb23327ed8f456Adam Powell     * @see AutoCompleteTextView#setOnDismissListener(OnDismissListener)
1228780c491fb9905adb3782f34886bb23327ed8f456Adam Powell     */
1229780c491fb9905adb3782f34886bb23327ed8f456Adam Powell    public interface OnDismissListener {
1230780c491fb9905adb3782f34886bb23327ed8f456Adam Powell        /**
1231780c491fb9905adb3782f34886bb23327ed8f456Adam Powell         * This method will be invoked whenever the AutoCompleteTextView's list
1232780c491fb9905adb3782f34886bb23327ed8f456Adam Powell         * of completion options has been dismissed and is no longer available
1233780c491fb9905adb3782f34886bb23327ed8f456Adam Powell         * for user interaction.
1234780c491fb9905adb3782f34886bb23327ed8f456Adam Powell         */
1235780c491fb9905adb3782f34886bb23327ed8f456Adam Powell        void onDismiss();
1236780c491fb9905adb3782f34886bb23327ed8f456Adam Powell    }
1237780c491fb9905adb3782f34886bb23327ed8f456Adam Powell
1238780c491fb9905adb3782f34886bb23327ed8f456Adam Powell    /**
123998e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen     * Allows us a private hook into the on click event without preventing users from setting
124098e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen     * their own click listener.
124198e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen     */
124298e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen    private class PassThroughClickListener implements OnClickListener {
124398e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen
124498e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen        private View.OnClickListener mWrapped;
124598e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen
124698e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen        /** {@inheritDoc} */
124798e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen        public void onClick(View v) {
124898e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen            onClickImpl();
124998e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen
125098e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen            if (mWrapped != null) mWrapped.onClick(v);
125198e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen        }
125298e333f551a4bf2ebb50bb97a2a56b14bfdcd74bKarl Rosaen    }
12536a67810228d02e75446d55c4c353275c87e9e769Romain Guy
12546a67810228d02e75446d55c4c353275c87e9e769Romain Guy    private class PopupDataSetObserver extends DataSetObserver {
12556a67810228d02e75446d55c4c353275c87e9e769Romain Guy        @Override
12566a67810228d02e75446d55c4c353275c87e9e769Romain Guy        public void onChanged() {
1257c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            if (mAdapter != null) {
12584f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy                // If the popup is not showing already, showing it will cause
12594f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy                // the list of data set observers attached to the adapter to
12604f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy                // change. We can't do it from here, because we are in the middle
1261be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne                // of iterating through the list of observers.
12624f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy                post(new Runnable() {
12634f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy                    public void run() {
12647254afd4c275dec243d4825f8f68c815ced1342cKenny Root                        final ListAdapter adapter = mAdapter;
12657254afd4c275dec243d4825f8f68c815ced1342cKenny Root                        if (adapter != null) {
1266be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne                            // This will re-layout, thus resetting mDataChanged, so that the
1267be2c4f92a990ca48ad6ede252343dd9574dfe505Gilles Debunne                            // listView click listener stays responsive
12684a74dbc3f2221af99f94b4f514b8291a16ae3661Gilles Debunne                            updateDropDownForFilter(adapter.getCount());
12697254afd4c275dec243d4825f8f68c815ced1342cKenny Root                        }
12704f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy                    }
12714f43ae09d2cb0cce2b9e794f1b80f7198333c94bRomain Guy                });
12726a67810228d02e75446d55c4c353275c87e9e769Romain Guy            }
12736a67810228d02e75446d55c4c353275c87e9e769Romain Guy        }
12746a67810228d02e75446d55c4c353275c87e9e769Romain Guy    }
12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1276