Android:没有输入文字时,AutoCompleteTextView显示建议


Answers:


159

这是记录的行为

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

您可以通过手动显示下拉菜单showDropDown(),因此您可以安排在需要时显示它。或者,子类AutoCompleteTextView和覆盖enoughToFilter(),返回true所有的时间。


7
showDropDown()似乎可以很好地设置onClickListener,但是直到用户输入字母并返回dels后,子类的东西才起作用。但不仅仅是onClick ...
amj 2013年

9
与视图获得焦点时调用showDropDown()的OnFocusChangeListener完美结合使用。
Grishka

我还必须覆盖onFocusChanged,如@DavidVávra在下面的答案中所述
Gabriel

4
@commonsWare何时showDropDown()无法afterTextChanged使用.getText().toString().length()==0。WHYYY
Prabs

1
只有覆盖足够的ToFilter可以帮助我。谢谢!
Fedir Tsapana

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(focused)”更改为“ if(focused && getAdapter()!= null)”。
2013年

对于AndroidX,请扩展androidx.appcompat.widget.AppCompatAutoCompleteTextView
Mahmudul Hasan Shohag '19

这不会显示方向更改下拉列表。
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 2015年

单击一次onTouchListener的时间将有所不同-例如:事件可以是MotionEvent.ACTION_DOWN,MotionEvent.ACTION_UP。因此最好检查特定事件并编写代码
Govind

18

当只有一个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();
    }
}

它解决了问题。

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


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的值从隐藏时起仍然为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("");
        }
    }
}

但这也意味着将重置文本(尽管通常没问题)...
android开发人员

3

制作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; 
    } 
}

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


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

只需将其粘贴到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"/>

并在“值”下的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()随时调用函数。

感谢@DavidVá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) }

当您专注于此视图时,它将显示所有建议。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.