IndexOutOfBoundException en el filtrado de SimpleAdapter

Yo sub clasificoSimpleAdapter para agregarle alguna funcionalidad adicional, como cambiar el color de fondo, vistas personalizadas y filtrar. Lo del fondo está funcionando bien, pero el filtro no. Si uso elSimpleFilter el adaptador no proporciona ningún problema, por lo que copié los métodos de la fuente y los puse en mi adaptador. Aunque no toqué nada obtendré unIndexOutOfBoundsException al escribir en el término de búsqueda. Generalmente en el segundo o tercer personaje.

Copié toda la clase pero la parte interesante es laCustomFilter bindView ygetView está funcionando muy bien Después de implementar el filtro cambiado deja de funcionar. La excepción es causada por data.get (posición) en elbindView Método en la primera línea pero el problema tiene que ser el filtro.

<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>

Respuestas a la pregunta(2)

Su respuesta a la pregunta