IndexOutOfBoundException na filtrowaniu SimpleAdapter

Ja sklasyfikowałemSimpleAdapter aby dodać do niego dodatkowe funkcje, takie jak zmiana koloru tła, niestandardowe widoki i filtrowanie. Sprawa tła działa świetnie, ale filtr nie jest. Jeśli korzystam zSimpleFilter dostarczone przez adapter nie ma żadnego problemu, więc skopiowałem metody ze źródła i umieściłem je w moim adapterze. Chociaż niczego nie dotknąłem, dostanęIndexOutOfBoundsException podczas wpisywania wyszukiwanego terminu. Zazwyczaj na drugim lub trzecim znaku.

Skopiowałem całą klasę, ale interesującą częścią jestCustomFilter bindView igetView działa świetnie. Po zaimplementowaniu zmienionego filtra przestaje działać. Wyjątkiem jest data.get (pozycja) wbindView metoda w pierwszej linii, ale problemem musi być filtr.

<code>public class ChangingColorAdapter extends SimpleAdapter {

    int resource;
    int[] to;

    List<Map<String, String>> data, mUnfilteredData;
    String[] from;

    Context context;
    Resources res;
    Filter filter;

    /*
     * A custom adapter which changes background colors on the elements
     * and implements custom filtering
     */
    public ChangingColorAdapter(Context context,
            List<Map<String, String>> data, int resource, String[] from, int[] to) {

        super(context, data, resource, from, to);
        this.context = context;
        this.resource = resource;
        this.data = data;
        this.from = from;
        this.to = to;
        this.res = context.getResources();

    }

    @Override
    public Filter getFilter() {
        if(filter != null) return filter;
        else return filter = new CustomFilter();
    }

    /*
     * A custom filter which is copied from the simplefilter in simpleadapter.
     * Changed word check from .startswith to .contains
     */
    private class CustomFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence prefix) {
            FilterResults results = new FilterResults();

            if (mUnfilteredData == null) {
                mUnfilteredData = new ArrayList<Map<String, String>>(data);
            }

            if (prefix == null || prefix.length() == 0) {
                List<Map<String, String>> list = mUnfilteredData;
                results.values = list;
                results.count = list.size();
            } else {
                String prefixString = prefix.toString().toLowerCase();

                List<Map<String, String>> unfilteredValues = mUnfilteredData;
                int count = unfilteredValues.size();

                ArrayList<Map<String, ?>> newValues = new ArrayList<Map<String, ?>>(count);

                for (int i = 0; i < count; i++) {
                    Map<String, ?> h = unfilteredValues.get(i);
                    if (h != null) {

                        int len = to.length;

                        for (int j=0; j<len; j++) {
                            String str =  (String)h.get(from[j]);

                            String[] words = str.split(" ");
                            int wordCount = words.length;

                            for (int k = 0; k < wordCount; k++) {
                                String word = words[k];

                                if (word.toLowerCase().contains(prefixString)) {
                                    newValues.add(h);
                                    break;
                                }
                            }
                        }
                    }
                }

                results.values = newValues;
                results.count = newValues.size();
            }

            return results;
        }

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            data = (List<Map<String, String>>) results.values;
            if (results.count > 0) {
                 notifyDataSetChanged();
            } else {
                 notifyDataSetInvalidated();
            }
        }
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v;
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = inflater.inflate(resource, parent, false);
        } else {
            v = convertView;
        }

        bindView(position, v);

        if(position%2!=0) {
            v.setBackgroundColor(Color.DKGRAY);
        }
        else {
            v.setBackgroundColor(Color.BLACK);
        }

        return v;
    }

    /*
     * Iterate over all elements, check which type the given view is and fill in the data
     */
    private void bindView(int position, View view) {
        final Map<String, String> dataSet = data.get(position);
        if (dataSet == null) {
            return;
        }

        final ViewBinder binder = getViewBinder();
        final String[] from = this.from;
        final int[] to = this.to;
        final int count = to.length;

        for (int i = 0; i < count; i++) {
            final View v = view.findViewById(to[i]);
            if (v != null) {
                final Object data = dataSet.get(from[i]);
                String text = data == null ? "" : data.toString();
                if (text == null) {
                    text = "";
                }

                boolean bound = false;
                if (binder != null) {
                    bound = binder.setViewValue(v, data, text);
                }

                if (!bound) {
                    if (v instanceof Checkable) {
                        if (data instanceof Boolean) {
                            ((Checkable) v).setChecked((Boolean) data);
                        } else if (v instanceof TextView) {
                            setViewText((TextView) v, text);
                        } else {
                            throw new IllegalStateException(v.getClass().getName() +
                                    " should be bound to a Boolean, not a " +
                                    (data == null ? "<unknown type>" : data.getClass()));
                        }
                    } else if (v instanceof TermView) {
                        if(text.length()==10) {
                            int year = Integer.parseInt(text.substring(0,4));
                            if(text.substring(5, 7).equals("04")) {
                                setViewText((TextView) v, res.getString(R.string.summerterm) + " " + year);
                            }
                            else {
                                setViewText((TextView) v, res.getString(R.string.winterterm) + " " + year + "/" + (year+1));
                            }   
                        }
                        else {
                            setViewText((TextView) v, text);
                        }
                    } else if (v instanceof TextView) {
                        setViewText((TextView) v, text);
                    } else if (v instanceof ImageView) {
                        if (data instanceof Integer) {
                            setViewImage((ImageView) v, (Integer) data);                            
                        } else {
                            setViewImage((ImageView) v, text);
                        }
                    } else {
                        throw new IllegalStateException(v.getClass().getName() + " is not a " +
                                " view that can be bounds by this SimpleAdapter");
                    }
                }
            }
        }
    }
}
</code>

questionAnswers(2)

yourAnswerToTheQuestion