过滤SimpleAdapter时发生IndexOutOfBoundException [英] IndexOutOfBoundException on filtering SimpleAdapter

查看:183
本文介绍了过滤SimpleAdapter时发生IndexOutOfBoundException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将其分类为 SimpleAdapter ,为其添加一些额外的功能,例如更改背景颜色,自定义视图和过滤。背景的东西很好,但过滤器不是。如果我使用适配器提供的 SimpleFilter ,则完全没有问题,所以我从源代码复制了方法,并将它们放到我的适配器中。虽然我没有碰到任何东西,但是在输入搜索词时,我会得到 IndexOutOfBoundsException 。通常在第二个或第三个字符。

我复制了整个类,但有趣的部分是 CustomFilter bindView getView 工作得很好。执行过滤器后,改变它停止工作。这个异常是由第一行的 bindView 方法中的data.get(position)造成的,但问题必须是过滤器。

  public class ChangingColorAdapter extends SimpleAdapter {

int resource;
int [] to;

List< Map< String,String>>数据,mUnfilteredData;
String [] from;

上下文环境;
资源res;
过滤器;
$ b / *
*改变元素背景颜色的自定义适配器
*并实现自定义过滤
* /
public ChangingColorAdapter(上下文上下文,
List< Map< String,String>> data,int resource,String [] from,int [] to){

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


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

/ *
*从simpleadapter中的simplefilter复制的自定义过滤器。
*将单词检查从.startswith更改为.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 {
字符串prefixString = prefix.toString()。toLowerCase();

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

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

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

int len = to.length;

(int j = 0; j String str =(String)h.get(from [j]);

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

for(int k = 0; k String word = words [k];

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

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

返回结果;

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



$覆盖
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;

$ b $ * b $ b *遍历所有元素,检查给定视图的类型并填写数据
* /
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);

$ b $ if(!bound){
if(v instanceof Checkable){
if(data instanceof Boolean){
((Checkable)v ).setChecked((布尔)数据);
} else if(v instanceof TextView){
setViewText((TextView)v,text);
} else {
throw new IllegalStateException(v.getClass()。getName()+
应该绑定到布尔值,而不是+
(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) ;
$ b $ 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()+不是+
视图,可以被这个SimpleAdapter );





$ b code $ pre

解决方案

试试这段代码:

  @SuppressWarnings 未选中)
@Override
protected void publishResults(CharSequence约束,FilterResults结果){
data.clear();
data.addAll((List< Map< String,String>>)results.values);
if(results.count> 0){
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}


I sub classed SimpleAdapter to add some extra functionality to it, like changing background color, custom views and filtering. The background thing is working out great but the filter isn't. If I use the SimpleFilter provided by the adapter there is no problem at all, so I copied the methods from the source and put them into my adapter. Although I didn't touch anything I'll get a IndexOutOfBoundsException when typing in the search term. Usually on the second or third character.

I copied the whole class but the interesting part is the CustomFilter bindView and getView is working great. After implementing the filter changed it stops working. The exception is caused by data.get(position) in the bindView method on the first line but the problem has to be the filter.

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");
                    }
                }
            }
        }
    }
}

解决方案

Try this code:

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

这篇关于过滤SimpleAdapter时发生IndexOutOfBoundException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆