自动完成文本框 - 禁用过滤

22

我正在从一个webservice中检索字符串列表,并希望将它们列在AutoCompleteTextField上,而不管内置的AutoCompleteTextField过滤器。

我该怎么做?有没有一种简单地禁用它的内部过滤方式(最好不需要子类化)的方法? 我已经将所有结果加载到一个ArrayAdapter中,但是由于过滤器的原因,其中一些结果没有显示出来。

如果我方向错误,请指点正确的方向。


浪费了我一半的时间。谢谢你,兄弟 :) - rgv
5个回答

43

可能@Alon的意思是继承ArrayAdapter, 而不是 AutoCompleteTextView。在getFilter() 方法中,需要返回一个自定义的过滤器,在其 performFiltering() 中不执行任何过滤操作。这可能会影响性能,因为线程被创建。最好的方法是从TextEdit派生并实现自己的完成弹出窗口。但对我来说这又太麻烦了。最终,我做了以下的事情,它对我有用。欢迎提供任何反馈。

public class KArrayAdapter<T> 
extends ArrayAdapter<T>
{
    private Filter filter = new KNoFilter();
    public List<T> items;

    @Override
    public Filter getFilter() {
        return filter;
    }

    public KArrayAdapter(Context context, int textViewResourceId,
            List<T> objects) {
        super(context, textViewResourceId, objects);
        Log.v("Krzys", "Adapter created " + filter);
        items = objects;
    }

    private class KNoFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence arg0) {
            FilterResults result = new FilterResults();
                result.values = items;
                result.count = items.size(); 
            return result;
        }

        @Override
        protected void publishResults(CharSequence arg0, FilterResults arg1) {
            notifyDataSetChanged();
        }
    }
}

希望能对你有所帮助。


21

在设置AutoCompleteTextView的文本时,请使用setText(CharSequence text, boolean filter)。 将filter参数设置为false,这样可以在不激活过滤器的情况下设置文本。


这是非常需要的答案! - android6p
1
这应该是所选答案。它可以无缝运行,无需编写额外的代码或覆盖适配器。 - Acemond

9

我通过创建一个继承ArrayAdapter类并覆盖其getFilter()方法的定制适配器来解决了我的问题。这样做可以使列表不基于文本框中放置的任何文本进行过滤,并显示所有项目。

public class MyAdapter extends ArrayAdapter{
    public MyAdapter(@NonNull Context context, int resource) {
        super(context, resource);
    }

    public MyAdapter(@NonNull Context context, int resource, int textViewResourceId) {
        super(context, resource, textViewResourceId);
    }

    public MyAdapter(@NonNull Context context, int resource, @NonNull Object[] objects) {
        super(context, resource, objects);
    }

    public MyAdapter(@NonNull Context context, int resource, int textViewResourceId, @NonNull Object[] objects) {
        super(context, resource, textViewResourceId, objects);
    }

    public MyAdapter(@NonNull Context context, int resource, @NonNull List objects) {
        super(context, resource, objects);
    }

    public MyAdapter(@NonNull Context context, int resource, int textViewResourceId, @NonNull List objects) {
        super(context, resource, textViewResourceId, objects);
    }

    @NonNull
    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                return null;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {

            }
        };
    }
}


5
最终,我创建了一个ArrayAdapter的子类,并通过重写它的getFilter方法禁用了过滤器,在“文本更改”事件期间进行了HTTPRequest。请保留HTML标记。

嗨,谢谢Alon。我有同样的问题。如果您能发布一些相关代码,我将不胜感激。提前致谢。 - Rajiv yadav
2
我完全卡在这里了。 - Rajiv yadav
@Rajivyadav,Krzysztow的新答案有帮到你吗? - Alon Amir
我成功地让所有这些工作方式相同。子类化ArrayAdapter; 覆盖getFilter()并像您在performFiltering()中所做的那样返回null。我还从web api调用中获取我的下拉数据,并在onTextChanged()中调用AsyncTask来检索数据,在onPostExecute()中设置适配器列表和notifyDataSetChanged()。我在我的ArrayAdapter中覆盖getView()以设置下拉布局项。我不得不想知道AutoCompleteTextView是否是正确的解决方案,但我没有更好的解决方案。而且,我还没有弄清楚如何在选择项目时设置文本。 - JJJones_3860
啊!AutoCompleteTextView.setOnClickListener(...) 当从下拉列表中选择项目时调用setText(),其中下拉列表是一个数据类。 - JJJones_3860

0

在寻找类似东西时发现了这个,但可能是在一个有点不寻常的设置中 - 使用 AutocompleteTextView 作为 Spinner(当您想要包装在 TextInputLayout 中的 Spinner 时很有用)。 我还使用 app:simpleItems 方法提供项目,而不是像这样使用自定义适配器:

<com.google.android.material.textfield.MaterialAutoCompleteTextView
                                android:id="@+id/sizes"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"
                                android:inputType="none"
                                app:simpleItems="@array/sizes" />

有两种方法可以解决问题,而且不需要你去子类化适配器:

  1. 在你的 onItemClickListener 中调用 setText(text, false)
view.findViewById<MaterialAutoCompleteTextView>(R.id.sizes).onItemClickListener =
        AdapterView.OnItemClickListener { _, _, position, _ ->
            setText(adapter.getItem(position).toString(), false);
        }
  • 将空数组赋值给过滤器。
  • view.findViewById<MaterialAutoCompleteTextView>(R.id.sampler).filters = arrayOf()
    

    希望这能帮助到某个人。

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