Android: AutoCompleteTextView 在没有输入文本时显示建议

我使用的是 AutoCompleteTextView,当用户点击它的时候,我想显示建议,即使它没有文本-但是 setThreshold(0)的工作原理和 setThreshold(1)完全一样-所以用户必须输入至少1个字符来显示建议。

100159 次浏览

这里是 记录在案的行为:

threshold小于或等于0时,阈值1为 应用。

您可以通过 showDropDown()手动显示下拉列表,所以也许您可以安排在需要时显示它。或者,子类 AutoCompleteTextView并重写 enoughToFilter(),始终返回 true

这是我的课 即时自动完成。它介于 AutoCompleteTextViewSpinner之间。

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 ... />

创建 CustomAutoCompleteTextView。 覆盖 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;
}
}

当只有一个 InstantAutoComplete对象时,Destil 的代码工作得非常好。不知道为什么。但是当我像这样把 showDropDown()(就像 CommonsWare 建议的那样)放到 onFocusChanged()中时:

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

问题解决了。

这只是两个答案的恰当组合,但我希望它可以节省一些人的时间。

您可以使用 onFocusChangeListener;

TCKimlikNo.setOnFocusChangeListener(new OnFocusChangeListener() {


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


}


}
});

最简单的方法:

只需使用 setOnTouchListener 和 showDropDown ()

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

Destil 上面的回答几乎可行,但有一个微妙的缺陷。当用户第一次将焦点放到它工作的字段时,但是如果他们离开然后返回到字段,它将不会显示下拉列表,因为 mPopupCanBeUpdated 的值在它被隐藏时仍然是 false。补丁是将 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("");
}
}
}

适配器最初不执行筛选。
未执行筛选时,下拉列表为空。
因此,最初可能需要进行过滤。 < br/>

为此,您可以在完成添加条目之后调用 filter():

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

试试看

    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;
}
}):

只需在触摸时调用此方法或单击 autoCompleteTextView 的事件或在需要的位置调用此方法即可。

autoCompleteTextView.showDropDown()

这对我很有用,伪代码:

    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);
}
}

只需将其粘贴到 Java 中的 onCreate 方法

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"/>

并在 value 下面的 string.xml 中创建一个 Array..。

<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)
}
}
}

在 FocusChangeListener 上,检查

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

在你的过滤器中,只需修剪这个值:

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

当你专注于这个观点时,它会显示所有的建议。

对我来说,是:

 autoCompleteText.setThreshold(0);

表演魔术。