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, но подкласс не работает, пока пользователь не введет букву и не вернет dels. Но не только с onClick ...
amj

9
Это прекрасно работает в сочетании с OnFocusChangeListener, который вызывает showDropDown (), когда представление получает фокус.
Гришка

Я также должен переопределить onFocusChanged, как указано в ответе ниже @David Vávra
Gabriel

4
@commonsWare showDropDown()не работает, afterTextChangedкогда .getText().toString().length()==0. ПОЧЕМУ
Prabs

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 ... />. Я потерял время, чтобы понять это :)
Жюль Колл

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 (); }
Boldijar Paul

7
не очень распространено, но это не сработает, если пользователь не коснется, чтобы перейти к этому EditText. Например, при использовании пульта дистанционного управления с кнопками (например, Android TV).
разработчик Android

2
Вы должны использовать setOnFocusChanged. Кто-то может иметь клавиатуру и нажимать кнопку TAB, иначе прослушиватель с помощью мыши и сенсорного ввода не будет вызван.
barwnikk

onTouchListener будет вызываться разное время для одного касания - Пример: событие может быть MotionEvent.ACTION_DOWN, MotionEvent.ACTION_UP. Так что лучше проверить конкретное событие и написать код
Говинд

18

Код Destil отлично работает, когда есть только один 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

Ответ Destil выше почти работает, но имеет одну тонкую ошибку. Когда пользователь сначала переводит фокус на поле, оно работает, однако, если они уйдут, а затем вернутся в поле, раскрывающееся меню не будет отображаться, поскольку значение 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("");
        }
    }
}

но это также означает, что текст будет сброшен (хотя обычно это нормально) ...
разработчик Android

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.