Андроид:AutoCompleteTextView показывает предложения, когда текст не введен
-
22-09-2019 - |
Вопрос
Я использую AutoCompleteTextView
, когда пользователь нажимает на него, я хочу показывать предложения, даже если там нет текста, но setThreshold(0)
работает точно так же, как setThreshold(1)
- поэтому пользователь должен ввести хотя бы 1 символ, чтобы отобразить предложения.
Решение
Это документированное поведение:
Когда
threshold
меньше или равна 0, применяется порог 1.
Вы можете вручную отобразить раскрывающийся список с помощью showDropDown()
, так что, возможно, вы сможете показать его, когда захотите.Или подкласс AutoCompleteTextView
и переопределить enoughToFilter()
, возвращаясь true
все время.
Другие советы
Вот мой класс Мгновенное автозаполнение.Это что-то между 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 ... />
Самый простой способ:
Просто используйте setOnTouchListener и showDropDown().
AutoCompleteTextView text;
.....
.....
text.setOnTouchListener(new View.OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event){
text.showDropDown();
return false;
}
});
Код 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();
}
}
это решило проблему.
Это всего лишь правильно скомбинированные два ответа, но я надеюсь, что это поможет кому-то сэкономить время.
Изначально адаптер не выполняет фильтрацию.
Если фильтрация не выполняется, выпадающий список пуст.
поэтому вам, возможно, придется сначала запустить фильтрацию.
Для этого вы можете вызвать filter()
после завершения добавления записей:
adapter.add("a1");
adapter.add("a2");
adapter.add("a3");
adapter.getFilter().filter(null);
Ответ Дестиля выше почти работает, но имеет одну тонкую ошибку.Когда пользователь сначала фокусируется на поле, это работает, однако, если он уйдет, а затем вернется в поле, раскрывающийся список не будет отображаться, поскольку значение 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("");
}
}
}
Вы можете использовать onFocusChangeListener;
TCKimlikNo.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
TCKimlikNo.showDropDown();
}
}
});
Чтобы сделать CustomAutoCompleteTextView.1.переопределить метод setThreshold,enoughToFilter,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;
}
}
Просто вызовите этот метод при касании или щелчке по событию autoCompleteTextView или там, где вы хотите.
autoCompleteTextView.showDropDown()
попробуй
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;
}
}):
Это сработало для меня, псевдокод:
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);
}
}
Просто вставьте это в свой метод 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>
И вы готовы идти.
Ребята, семь лет спустя проблема осталась прежней.Вот класс с функцией, которая заставляет это дурацкое всплывающее окно показываться в любых условиях.Все, что вам нужно сделать, это установить адаптер для вашего 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)
}
}
}