Android: AutoCompleteTextView показує пропозиції, коли не вводиться текст


127

Я використовую AutoCompleteTextView, коли користувач натискає на нього, я хочу показати пропозиції, навіть якщо у них немає тексту - але setThreshold(0)працює точно так само, як setThreshold(1)- тому користувачеві потрібно ввести принаймні 1 символ, щоб показати пропозиції.


Я роблю щось подібне ТУТ !!! stackoverflow.com/questions/12854336 / ...
toobsco42

Відповіді:


159

Це задокументоване поведінка :

Коли thresholdменше або дорівнює 0, застосовується поріг 1.

Ви можете вручну показати спадне меню через showDropDown(), так що, можливо, ви можете домовитись, щоб показати його, коли захочете. Або підклас AutoCompleteTextViewі переосмислення enoughToFilter(), повертаючи trueвесь час.


7
ShowDropDown (), здається, добре працює на розміщенні onClickListener, але річ підкласу не працює, поки користувач не введе лист і поверне дели. Але не тільки з onClick ...
amj

9
Це прекрасно працює в поєднанні з OnFocusChangeListener, який викликає showDropDown (), коли погляд отримує фокус.
Гришка

Я також повинен перемогти onFocusChanged, як сказано у відповіді нижче від @David Vávra
Габріель

4
@commonsWare showDropDown()не працює, afterTextChangedколи .getText().toString().length()==0. ЧОМУ
Прабс

1
Мені допомагає лише переоцінка достатньоToFilter. Дякую!
Федір Цапана

121

Ось мій клас InstantAutoComplete . Це щось середнє AutoCompleteTextViewі Spinner.

import android.content.Context;  
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.AutoCompleteTextView;

public class InstantAutoComplete extends AutoCompleteTextView {

    public InstantAutoComplete(Context context) {
        super(context);
    }

    public InstantAutoComplete(Context arg0, AttributeSet arg1) {
        super(arg0, arg1);
    }

    public InstantAutoComplete(Context arg0, AttributeSet arg1, int arg2) {
        super(arg0, arg1, arg2);
    }

    @Override
    public boolean enoughToFilter() {
        return true;
    }

    @Override
    protected void onFocusChanged(boolean focused, int direction,
            Rect previouslyFocusedRect) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect);
        if (focused && getAdapter() != null) {
            performFiltering(getText(), 0);
        }
    }

}

Використовуйте його у своєму xml так:

<your.namespace.InstantAutoComplete ... />

12
Це чудово! Я б також хотів би відзначити, що в файлі XML макет ви повинні змінити <AutoCompleteTextView ... />до <your.namespace.InstantAutoComplete ... />. Я втратив деякий час, з'ясовуючи це :)
Jules Colle

3
Чудовий клас - лише пропозиція буде в методі onFocusChanged, змінити "if (сфокусований)" на "if (сфокусований && getAdapter ()! = Null)".
Яків Табак

Для AndroidX продовжте androidx.appcompat.widget.AppCompatAutoCompleteTextView.
Махмудул Хасан Шогаг

Це не відображає спадне значення щодо зміни орієнтації.
Miha_x64

45

Найпростіший спосіб:

Просто використовуйте setOnTouchListener і showDropDown ()

AutoCompleteTextView text;
.....
.....
text.setOnTouchListener(new View.OnTouchListener(){
   @Override
   public boolean onTouch(View v, MotionEvent event){
      text.showDropDown();
      return false;
   }
});

Щоб зробити це ще краще, використовуйте if (! Text.isPopupShowing ()) {text.showDropDown (); }
Болдіяр Пол

7
не так часто, але це не працює, якщо користувач не торкнеться, щоб перейти до цього редагування. Наприклад, при використанні пульта дистанційного керування кнопками (наприклад, Android TV).
андроїд розробник

2
Ви повинні використовувати setOnFocusChanged. Хтось може мати клавіатуру та натиснути кнопку TAB, або за допомогою миші та сенсорного слухача не називатимуться.
barwnikk

onTouchListener буде викликати різні часи за один дотик - Наприклад: подія може бути MotionEvent.ACTION_DOWN, MotionEvent.ACTION_UP. Тож краще перевірити конкретну подію і написати код
Govind

18

Код Дестіля працює просто чудово, коли є лише один InstantAutoCompleteоб’єкт. Хоча з двома не працювало - не знаю чому. Але коли я вкладаю showDropDown()(як саме рекомендував CommonsWare) onFocusChanged()так:

@Override
protected void onFocusChanged(boolean focused, int direction,
        Rect previouslyFocusedRect) {
    super.onFocusChanged(focused, direction, previouslyFocusedRect);
    if (focused) {
        performFiltering(getText(), 0);
        showDropDown();
    }
}

це вирішило проблему.

Це лише два відповіді, правильно поєднані, але я сподіваюся, що це може врятувати когось деякий час.


2
Ваше доповнення допомогло, але я отримав помилку, якщо в InstantAutoComplete був текст, а орієнтація екрана змінилася. Я зафіксував це за допомогою перевірки видимості вікна, я опублікував тут новий код: gist.github.com/furycomptuers/4961368
FuryComputers

9

Адаптер не виконує фільтрацію спочатку.
Коли фільтрація не виконується, випадаючий список порожній.
тому, можливо, доведеться спочатку фільтрувати.

Для цього ви можете звернутися filter()після завершення додавання записів:

adapter.add("a1");
adapter.add("a2");
adapter.add("a3");
adapter.getFilter().filter(null);

6

Ви можете використовувати onFocusChangeListener;

TCKimlikNo.setOnFocusChangeListener(new OnFocusChangeListener() {

        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (hasFocus) {
                TCKimlikNo.showDropDown();

            }

        }
    });

6

Відповідь Дестіля вище майже працює, але має одну тонку помилку. Коли користувач спочатку зосередиться на полі, воно працює, однак, якщо вони покинуть, а потім повернуться в поле, воно не відобразиться, оскільки значення mPopupCanBeUpdated все ще буде помилковим з моменту, коли воно було приховано. Виправлення полягає в тому, щоб змінити метод onFocusChanged на:

@Override
protected void onFocusChanged(boolean focused, int direction,
        Rect previouslyFocusedRect) {
    super.onFocusChanged(focused, direction, previouslyFocusedRect);
    if (focused) {
        if (getText().toString().length() == 0) {
            // We want to trigger the drop down, replace the text.
            setText("");
        }
    }
}

але це також означає, що текст буде скинутий (хоча це зазвичай нормально) ...
андроїд розробник

3

Щоб зробити CustomAutoCompleteTextView. 1. Перевизначити метод setThreshold, доситьToFilter, onFocusChanged

public class CustomAutoCompleteTextView  extends AutoCompleteTextView { 

    private int myThreshold; 

    public CustomAutoCompleteTextView  (Context context) { 
        super(context); 
    } 

    public CustomAutoCompleteTextView  (Context context, AttributeSet attrs, int defStyle) { 
        super(context, attrs, defStyle); 
    } 

    public CustomAutoCompleteTextView  (Context context, AttributeSet attrs) { 
        super(context, attrs); 
    } 
     //set threshold 0.
    public void setThreshold(int threshold) { 
        if (threshold < 0) { 
            threshold = 0; 
        } 
        myThreshold = threshold; 
    } 
    //if threshold   is 0 than return true
    public boolean enoughToFilter() { 
         return true;
        } 
    //invoke on focus 
    protected void onFocusChanged(boolean focused, int direction,
            Rect previouslyFocusedRect) {
                    //skip space and backspace 
        super.performFiltering("", 67);
        // TODO Auto-generated method stub
        super.onFocusChanged(focused, direction, previouslyFocusedRect);

    }

    protected void performFiltering(CharSequence text, int keyCode) {
        // TODO Auto-generated method stub
        super.performFiltering(text, keyCode);
    }

    public int getThreshold() { 
        return myThreshold; 
    } 
}

3

Спробуй це

    searchAutoComplete.setThreshold(0);
    searchAutoComplete.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                }

                @Override
                public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {//cut last probel
                    if (charSequence.length() > 1) {
                        if (charSequence.charAt(charSequence.length() - 1) == ' ') {
                            searchAutoComplete.setText(charSequence.subSequence(0, charSequence.length() - 1));
                            searchAutoComplete.setSelection(charSequence.length() - 1);
                        }
                    }
                   }


                @Override
                public void afterTextChanged(Editable editable) {
                }
            });


    //when clicked in autocomplete text view
        @Override
        public void onClick(View view) {
            switch (view.getId()) {
              case R.id.header_search_etv:
                    if (searchAutoComplete.getText().toString().length() == 0) {
                        searchAutoComplete.setText(" ");
                    }
             break;
            }
        }):

3

Просто зателефонуйте цьому методу при натисканні або натисканні події autoCompleteTextView або де ви хочете.

autoCompleteTextView.showDropDown()

0

Це працювало для мене, псевдокод:

    public class CustomAutoCompleteTextView extends AutoCompleteTextView {
    public CustomAutoCompleteTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean enoughToFilter() {
        return true;
    }

    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect);
        if (focused) {
            performFiltering(getText(), 0);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        this.showDropDown();
        return super.onTouchEvent(event);
    }
}


0

Просто вставте це у свій метод onCreate на Java

final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(
            this, android.R.layout.simple_spinner_dropdown_item,
            getResources().getStringArray(R.array.Loc_names));

    textView1 =(AutoCompleteTextView) findViewById(R.id.acT1);
    textView1.setAdapter(arrayAdapter);

    textView1.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(final View arg0) {
            textView1.setMaxLines(5);
            textView1.showDropDown();

        }
    });

І це до вашого Xml-файлу ...

<AutoCompleteTextView
            android:layout_width="200dp"
            android:layout_height="30dp"
            android:hint="@string/select_location"
            android:id="@+id/acT1"
            android:textAlignment="center"/>

І створіть масив у string.xml у розділі Значення ...

<string-array name="Loc_names">

        <item>Pakistan</item>
        <item>Germany</item>
        <item>Russia/NCR</item>
        <item>China</item>
        <item>India</item>
        <item>Sweden</item>
        <item>Australia</item>
    </string-array>

І вам добре піти.


0

Сім років потому, хлопці, проблема залишається такою ж. Ось клас з функцією, яка змушує цей дурний спливаючий вікно проявити себе в будь-яких умовах. Все, що вам потрібно зробити, - це встановити адаптер до свого AutoCompleteTextView, додати в нього деякі дані та зателефонувати у showDropdownNow()будь-який час.

Кредити @David Vávra. Він заснований на його коді.

import android.content.Context
import android.util.AttributeSet
import android.widget.AutoCompleteTextView

class InstantAutoCompleteTextView : AutoCompleteTextView {

    constructor(context: Context) : super(context)

    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)

    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    override fun enoughToFilter(): Boolean {
        return true
    }

    fun showDropdownNow() {
        if (adapter != null) {
            // Remember a current text
            val savedText = text

            // Set empty text and perform filtering. As the result we restore all items inside of
            // a filter's internal item collection.
            setText(null, true)

            // Set back the saved text and DO NOT perform filtering. As the result of these steps
            // we have a text shown in UI, and what is more important we have items not filtered
            setText(savedText, false)

            // Move cursor to the end of a text
            setSelection(text.length)

            // Now we can show a dropdown with full list of options not filtered by displayed text
            performFiltering(null, 0)
        }
    }
}

0

на FocusChangeListener, перевірте

if (hasFocus) {
            tvAutoComplete.setText(" ")

у своєму фільтрі просто обріжте це значення:

filter { it.contains(constraint.trim(), true) }

і він покаже всі пропозиції, коли ви зосередитесь на цьому погляді.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.