0

我正在尝试创建一个自定义 ArrayAdapter,它通过“包含”而不是“startswith”进行过滤。我已经看到有类似的问题,更重要的是,我从这些帖子中制作了我的自定义 ArrayAdapter(比如这个AutoCompleteTextView 没有完成括号内的单词,或者这个另一个将 AutoCompleteTextView 过滤器从“startsWith”更改为“Contains”?)。

但是,在 publishResults 中调用 clear() 时出现 UnsupportedOperationException。有谁知道为什么?

这是我的 ArrayAdapter:

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.TextView;

import com.example.osmdroid.R;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class AutoSuggestAdapterNew<T> extends ArrayAdapter<String> {

    Context context;
    int resource, textViewResourceId;
    List<String> items, tempItems, suggestions;

    public AutoSuggestAdapterNew(Context context, int resource, int
            textViewResourceId, List<String> items) {
        super(context, resource, textViewResourceId, items);
        this.context = context;
        this.resource = resource;
        this.textViewResourceId = textViewResourceId;
        this.items = items;
        tempItems = new ArrayList<String>(items);// this makes the difference.
        suggestions = new ArrayList<String>();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = convertView;
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.autocompletestreets_layout, parent, false);
        }
        String name = items.get(position);
        if (name != null) {
            TextView lblName = (TextView) view.findViewById(R.id.autoCompleteStreets);
            if (lblName != null)
                lblName.setText(name);
        }
        return view;
    }

    @Override
    public Filter getFilter() {
        return nameFilter;
    }
    /**
     * Custom Filter implementation for custom suggestions we provide.
     */
    Filter nameFilter = new Filter() {
        @Override
        public CharSequence convertResultToString(Object resultValue) {
            String str = (String) resultValue;
            return str;
        }

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            if (constraint != null) {

                suggestions.clear();
                FilterResults filterResults = new FilterResults();

                for (String name : tempItems) {
                    if (name.toLowerCase().contains(constraint.toString().toLowerCase())) {

                        suggestions.add(name);
                    }
                }

                /*String[] stringSuggestions = new String[suggestions.size()];
                stringSuggestions = suggestions.toArray(stringSuggestions);*/

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


                return filterResults;
            } else {
                return new FilterResults();
            }
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults
                results) {
            List<String> filterList = (ArrayList<String>) results.values;
            if (results != null && results.count > 0) {
                clear();
                for (String name : filterList) {
                    add(name);
                    notifyDataSetChanged();
                }
            }
        }
    };
}

编辑:我发现我正在传递一个像 Arrays.asList 这样的字符串数组,它返回一个固定大小的列表。因此我使用了 new LinkedList(Arrays.asList()) 并且我的错误消失了。但是我现在得到了一个 ConcurrentModificationException。这些是我的日志:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.osmdroid, PID: 20901
    java.util.ConcurrentModificationException
        at java.util.ArrayList$Itr.next(ArrayList.java:860)
        at com.example.osmdroid.Datos.AutoSuggestAdapterNew$1.publishResults(AutoSuggestAdapterNew.java:97)
        at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:284)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
4

1 回答 1

1

从文档

performFiltering(CharSequence constraint) 在工作线程中调用以根据约束过滤数据。

所以使用suggestionsinpublishResults而不是performFiltering

performFiltering或像这样创建一个新列表

@Override
    protected FilterResults performFiltering(CharSequence constraint) {
        if (constraint != null) {

            final List<String> suggestions = new ArrayList<String>();
            FilterResults filterResults = new FilterResults();

            for (String name : tempItems) {
                if (name.toLowerCase().contains(constraint.toString().toLowerCase())) {

                    suggestions.add(name);
                }
            }

            /*String[] stringSuggestions = new String[suggestions.size()];
            stringSuggestions = suggestions.toArray(stringSuggestions);*/

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


            return filterResults;
        } else {
            return new FilterResults();
        }
    }
于 2020-07-17T11:57:17.393 回答