自定义AutoCompleteTextView行为

Chr*_*han 8 android filtering autocompletetextview android-arrayadapter

开箱即用,AutoCompleteTextView小部件似乎无法匹配列表值中间的输入字符串 - 匹配始终在开头; 例如,输入" ar"匹配" argentina",但不输入" hungary".

如何搜索单词中间的文本?谁能给我一个想法?

提前致谢 !

Vic*_*tor 7

您需要编写自定义Filter类并performFiltering自己实现该方法.此方法接受一个CharSequence参数,您可以使用该参数执行所需的任何String操作,以便从数据集生成匹配列表(在您的情况下,您可以使用String.contains而不是String.startsWith).该performFiltering功能未在UI线程上运行.

然后,您将匹配列表作为FilterResults对象返回,其中包含一个Object (您的匹配列表,可能是一个ArrayList)和一个匹配列表大小的int 计数.

最后,实现publishResults回调方法,该方法在工作线程生成匹配列表后返回,允许您调用notifyDataSetChangedAutoCompleteTextView的适配器以便它可以显示结果.

  • Victor 是对的,这里有一个简单的方法:只需将 android.widget.ArrayAdapter 的全部内容复制粘贴到名为 CustomArrayAdapter 的新类中,并将位于 PerformFiltering 和publishResults 中的 2 个“startsWith”更改为“contains”。简单的。 (2认同)

Rya*_*n C 6

老问题,但仍然相关。按照其他几个问题的指导,使用 filterable 实现了一个自定义适配器。我制作了一个简单的通用适配器,可以使用 contains 进行搜索。关于它的快速说明:

我正在使用黄油刀,但很容易用 findviewbyid 做 viewHolder。

布局 R.layout.list_item_simple 是一个带有 textview R.id.text_view_simple 的简单布局。

该对象需要一个将被比较的 toString。

public class SimpleContainsAutocompleteAdapter <T> extends ArrayAdapter<T> implements Filterable {
    private List <T> listObjects;
    List<T> suggestions = new ArrayList<>();
    private int resource;

    private Filter mFilter = new Filter(){
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults filterResults = new FilterResults();

            if(constraint != null) {
                suggestions.clear();
                for(T object : listObjects){
                    if(object.toString().toLowerCase().contains(constraint.toString().toLowerCase())){
                        suggestions.add(object);
                    }
                }

                filterResults.values = suggestions;
                filterResults.count = suggestions.size();
            }

            return filterResults;
        }

        @Override
        protected void publishResults(CharSequence contraint, FilterResults results) {
            if(results == null){
                return;
            }

            List<T> filteredList = (List<T>) results.values;
            if(results.count > 0) {
                clear();
                for (T filteredObject : filteredList) {
                    add(filteredObject);
                }
                notifyDataSetChanged();
            }
        }
    };

    public SimpleContainsAutocompleteAdapter(Context context, List<T> listObjects) {
        super(context, R.layout.list_item_simple, listObjects);
        this.listObjects = new ArrayList<>(listObjects);
        this.resource = R.layout.list_item_simple;
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Object listObject = getItem(position);
        viewHolder holder;
        if(convertView != null) {
            holder = (viewHolder) convertView.getTag();
        }else{
            convertView = LayoutInflater.from(getContext()).inflate(resource, parent, false);
            holder = new viewHolder(convertView);
            convertView.setTag(holder);
        }

        holder.name.setText(listObject.toString());

        return convertView;
    }


    static class viewHolder {
        @InjectView(R.id.text_view_simple) TextView name;

        public viewHolder(View view) {
            ButterKnife.inject(this, view);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)