不写文本即可显示AutocompleteTextView中的所有项目

63

我有一个AutocompleteTextView,它可以正常工作。当我输入单词时,它会显示相关结果,但我想在AutocompleteTextView中不输入任何单词的情况下显示所有项。我该怎么做?


尝试使用此链接代码,可能会对您有所帮助...http://stackoverflow.com/questions/15224027/custom-autocompletevview-like-facebook-comments-field-in-android/15247212#15247212 - Umesh Lakhani
这不是我想要的实际解决方案。无论如何,谢谢。 - androidcodehunter
14个回答

92

你需要扩展 AutoCompleteTextView。

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

setThreshold

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 && getFilter()!=null) {
        performFiltering(getText(), 0);
    }
    }

}

在XML中

<AutoCompleteTextView ... /> to <your.namespace.InstantAutoComplete ... />

编辑 1

创建名为InstantAutoComplete的新类,然后将此代码放入该类中。

在您的布局xml中使用此类,例如:

然后在您的活动(onCreate方法)中查找此小部件。

查看此示例。


您不需要扩展您的活动,这是一个新的自定义自动完成文本视图,只需创建并在您的布局中使用即可。请查看编辑后的答案。 - Talha
7
我在使用应用时遇到了 java.lang.NullPointerException 错误,出错位置为 android.widget.AutoCompleteTextView.performFiltering(AutoCompleteTextView.java:841) 和 com.mybusiness.ui.view.InstantAutoComplete.onFocusChanged(InstantAutoComplete.java:35)。你有什么建议吗? - bentzy
1
当阈值小于或等于0时,应用阈值1。这主意也太差了吧...但还是感谢您指出来。 - SePröbläm
这是一个InstantAutoComplete,如果你不加更多的代码,将来会出现错误,不建议这样做。 - user3402040
1
@bentzy 在调用 performFiltering() 之前,请添加一个检查以确保 getFilter() 不为空。 - thijsonline
显示剩余7条评论

58

更好的解决方案

您无需自定义AutoCompleteTextView,只需在需要时调用autoCompleteTextView.showDropDown()即可......干杯 :)


2
不幸的是,这并不总是有效。我不确定为什么,但在某些设备上,当文本字段为空时似乎会忽略该命令。 - Ifrit
你为它设置了任何阈值吗? - Melbourne Lopes
是的,0。我甚至提前调用了requestFocus函数。 - Ifrit
4
这只能在第一次起作用。 但如果您输入了一些内容,然后将其清除,它将显示为空。 这是因为您试图显示适配器的当前状态,但筛选为空字符串后,它为空。 - Simon K. Gerges
@SimonKarmy 即使数据集不为空但文本为空时,弹出窗口也不会显示。每当使用空字符串进行过滤时,我都会使用一些存储的值填充数据集。 - tanay tandon
4
当焦点为true时,应在OnFocusChangeListener中使用showDropDown(),并在长度为0时,在OnTextChangeListener中使用afterTextChanged。 - Leo DroidCoder

33

它适用于我:

将下一个事件方法添加到您的对象中:

    myView.setOnFocusChangeListener(new OnFocusChangeListener() {

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

        }
    });

    myView.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            myView.showDropDown();
            return false;
        }
    });

2
我认为你不需要两个。触摸视图不也会使其获得焦点吗? - velocirabbit
它对我有效。但是除了你的答案之外,我不得不加上“auto_complete_text_view.threshold = 1”。 - Aminul Haque Aome

18

这对我来说完美地解决了问题,这是一种简单的方法:

final ArrayAdapter<String> adapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_dropdown_item_1line, usernameLists);
etUsername.setThreshold(1);
etUsername.setAdapter(adapter);
etUsername.setOnTouchListener(new View.OnTouchListener() {

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouch(View paramView, MotionEvent paramMotionEvent) {
        if (usernameLists.size() > 0) {
                // show all suggestions
                if (!etUsername.getText().toString().equals(""))
                    adapter.getFilter().filter(null);
                etUsername.showDropDown();
            }
        return false;
    }
});

adapter.getFilter().filter(etUsername.getText().toString()); 保留过滤器。 - Joshy Francis
1
感谢"adapter.getFilter().filter(null);"帮助我显示所有项目,即使autocompletetextview已经填充了默认值。 - Rahmat Ihsan
即使我在滚动表单时,也会激活此下拉列表。 - Krzysztof Dziuba
它可以工作,但是和其他答案一样,在AutoCompleteTextView内的每次点击都会隐藏和显示列表。而且在您键入一个字母(并缩小记录计数)后,再次点击时它将显示完整的列表。 - CoolMind

9
你需要调用requestFocus();方法才能显示键盘,否则键盘不会弹出。
该方法可以强制显示下拉列表。
autocomptv.setOnTouchListener(new OnTouchListener() {

        @SuppressLint("ClickableViewAccessibility")
        @Override
        public boolean onTouch(View paramView, MotionEvent paramMotionEvent) {
            // TODO Auto-generated method stub
            autocomptv.showDropDown();
            autocomptv.requestFocus();
            return false;
        }
    });

谢谢您使用 requestFocus()!这是个好主意!它确实有效,但别忘了设置 autocomptv.threshold = 1(或 android:completionThreshold="1")。如果不设置,列表将在您输入第一个字母后隐藏(然后在输入第二个字母后再次出现)。 - CoolMind
还可以参考以下链接以避免警告:https://dev59.com/TlYN5IYBdhLWcg3wqpmH 和 https://dev59.com/iuk6XIcBkEYKwwoYFf_R#32065442。 - CoolMind
它仍然允许编写文本。 - user924

8
您需要按照以下步骤使其完美运行:
1. 在您的 XML 中添加以下内容:
    <androidx.appcompat.widget.AppCompatAutoCompleteTextView
            android:id="@+id/account_type_spinner"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="@dimen/_16sdp"
            android:layout_marginTop="@dimen/_24sdp"
            android:layout_marginEnd="@dimen/_16sdp"
            android:background="@drawable/rounded_edt_with_border"
            android:completionThreshold="0"
            android:drawableRight="@drawable/ic_arrow_down"
            android:hint="@string/account_type"
            android:imeOptions="actionNext"
            android:inputType="text"
            android:padding="12dp"
            android:textSize="@dimen/_15sp"
             />

您只需要将android:completionThreshold设置为零即可。

2- 在您的java代码中添加以下内容:

  mViewDataBinding.accountTypeSpinner.setOnFocusChangeListener((v, hasFocus) -> {
        if (hasFocus)
            mViewDataBinding.accountTypeSpinner.showDropDown();
    });

1
它可以工作,但如果你按下返回键(并隐藏列表),然后再次点击AutoCompleteTextView内部,它将不会显示列表。在您输入和删除符号之后,它将显示列表。 - CoolMind
这是因为我只使用了 setOnFocusChangeListener,你可以添加 setOnClickListener 并重复相同的代码,它应该能解决问题。 - Abdulmalek Dery
谢谢!我也尝试了其他解决方案。我明白列表会在每次点击AutoCompleteTextView内部时隐藏。所以,当使用setOnClickListener时,它会隐藏和显示列表(除了第一次点击)。 - CoolMind

4

使用这个:

 text.setOnTouchListener(new View.OnTouchListener(){


            @Override
            public boolean onTouch(View arg0, MotionEvent arg1) {
                // TODO Auto-generated method stub
                text.showDropDown();
                return false;
            }
            });

1
必须是答案 - Shady Mohamed Sherif

2

所有答案都已经过时了。使用 Material Design 后,变得更加容易和流畅。请确保将 inputType 设置为 none,以停止打开键盘。

XML

 <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/et_countries_list"
        style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="20dp"
        android:hint="Demo hint"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent"

        >

        <com.google.android.material.textfield.MaterialAutoCompleteTextView
            android:id="@+id/countries_list"
            android:layout_width="match_parent"
            android:inputType="none"
            android:layout_height="60dp"
            />

    </com.google.android.material.textfield.TextInputLayout>

然后准备好你的适配器并添加它。

   ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_dropdown_item_1line, new String[]{
                "Belgium", "France", "Italy", "Germany", "Spain", "Belgium", "France", "Italy", "Germany", "Spain"});
       
        AutoCompleteTextView autoCompleteTextView = (AutoCompleteTextView)
                findViewById(R.id.countries_list);
        autoCompleteTextView.setAdapter(adapter);

完成了。它的效果比旋转框更好。您还可以设置提示、错误和帮助信息。


2
Nothing Custom Required.

我尝试了所有的解决方案,但在某些情况下它们并不起作用。例如:其中一种解决方案仅在第一次工作时有效,但当您删除文本时,它将不再出现。因此,我进行了更深入的挖掘,并找到了以下解决方案。

欢迎提出建议。

XML:

<android.support.design.widget.TextInputLayout
                    android:id="@+id/tl"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content">

                    <android.support.v7.widget.AppCompatAutoCompleteTextView
                        android:id="@+id/autoComplete"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:hint="Hint Here" />


                </android.support.design.widget.TextInputLayout>

Kotlin: 最初的回答
val adapter = ArrayAdapter<BusinessNoResult>(context, android.R.layout.select_dialog_item, listItems)
autoComplete.setAdapter(adapter)
//threshold specifies the minimum number of characters the user has to type in 
//the
//edit box before the drop down list is shown
autoComplete.threshold = 0

//we have to add check for 0 number of character in edit text. When that 
//happens, we will show pop up manually
autoComplete.addTextChangedListener(object : TextWatcher {
    override fun afterTextChanged(s: Editable?) {}

    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}

    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
        //first check if length of input is 0
        if(s?.length ?: 0 == 0){
            //if you don't use handler with post delay, the API will hide pop 
            //up, even if you show it. There could be better ways to this, but 
            //I have implemented this and after 100 millis it gives an animated 
            //look
            Handler().postDelayed({
                //manually show drop down
                autoComplete.showDropDown()
            }, 100) // with 100 millis of delay
        }
    }
})
//when user focus out the view, drop down vanishes. When come back it will not 
//show, so to cover this scenario add following.
autoComplete.setOnFocusChangeListener { _, hasFocus ->
    //when gain focus manually show drop down
    if(hasFocus)
        autoComplete.showDropDown()
}

我删除了BusinessNoResult,添加了implementation 'com.google.android.material:material:1.2.0-beta01',将android.support.design.widget.TextInputLayout更改为com.google.android.material.textfield.TextInputLayout,并将android.support.v7.widget.AppCompatAutoCompleteTextView更改为AutoCompleteTextView。与其他解决方案一样,它会显示列表,但是当您再次单击或按返回按钮时,它将不会显示列表,直到输入一些符号。 - CoolMind

1
如果其他解决方案对您无效,请尝试以下方法。单击时弹出窗口始终显示。
   public class InstantAutoComplete extends AppCompatAutoCompleteTextView {

    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
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            performClick();
        }
        return super.onTouchEvent(event);
    }

    @Override
    public boolean performClick() {
        if (getFilter() != null && !isPopupShowing()) {
            performFiltering(getText(), 0);
            showDropDown();
        }
        return super.performClick();
    }
}

谢谢!可能不需要onTouchEvent。它在单击时显示列表。首先隐藏,然后再显示。我认为这是Spinner在许多事件上隐藏的行为。 - CoolMind
一开始它运行得非常好,直到我将InstantAutoComplete添加到一个复杂的布局中。然后键盘开始隐藏。如果回退到AutoCompleteTextView,它会显示键盘并按预期工作,但不会显示完整的项目列表。如果我删除InstantAutoComplete内的所有3个方法,则不会显示键盘,甚至无法像AutoCompleteTextView那样工作。也许布局中的其他属性有问题。因此,这是一个很好的解决方案,但在复杂的布局中要进行检查。 - CoolMind

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接