Android自定义列表视图过滤器

时间:2013-07-14 15:51:37

标签: android listview filter android-arrayadapter

我知道有很多教程,之前已经有人问过这个教程,但是在完成了一些教程之后(tutorial),我不断关闭这个教程。该列表过滤sorta但滚动导致一个力关闭,它将结果放在顶部,但列表的长度停止,所以一旦我通过我的结果我得到一个越界错误,因为过滤后数组大小较小。我的代码低于任何帮助,非常感谢!

    public class Holder {
        public boolean checked;
        public String name;
        public String type;
        public String number;

        public Holder(boolean checked, String name, String type, String number) {
            this.checked=checked;
            this.name=name;
            this.type=type;
            this.number=number;
        }
    }

public class MyCustomAdapter extends ArrayAdapter<Holder> implements Filterable {
    ArrayList<Holder> array;
    LayoutInflater inflater2;
    HolderFilter holderFilter;
    public MyCustomAdapter(LayoutInflater inflater, Context context, int resource, int textViewResourceId, ArrayList<Holder> litem) {
        super(context, resource, textViewResourceId, litem);
        inflater2 = inflater;
        array = litem;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) { 
            convertView = inflater2.inflate(R.layout.contactrow, null);
            holder = new ViewHolder();
            holder.checkBox = (CheckBox)convertView.findViewById(R.id.checkBox);
            holder.name = (TextView)convertView.findViewById(R.id.recipient_name);
            holder.type = (TextView)convertView.findViewById(R.id.recipient_type);
            holder.number = (TextView)convertView.findViewById(R.id.recipient_number);
            convertView.setTag(holder);
        }else{
            holder = (ViewHolder) convertView.getTag();
        }
        holder.checkBox.setOnClickListener(checkChange);
        holder.checkBox.setChecked(holderarray.get(position).checked);
        holder.checkBox.setTag(position);
        holder.name.setText(holderarray.get(position).name);
        holder.type.setText(types[Integer.valueOf(holderarray.get(position).type)]);
        holder.number.setText(holderarray.get(position).number);
        return convertView;
    }

    @Override
    public Filter getFilter() {
        if (holderFilter == null){
            holderFilter = new HolderFilter();
        }
        return holderFilter;
    }

    private class HolderFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults();
            if (constraint == null || constraint.length() == 0) {
                results.values = holderarray;
                results.count = holderarray.size();
            }else {
                List<Holder> nHolderList = new ArrayList<Holder>();
                for (Holder h : holderarray) {
                    if (h.name.toUpperCase().startsWith(constraint.toString().toUpperCase()) || h.number.startsWith(constraint.toString()))
                        nHolderList.add(h);
                }
                results.values = nHolderList;
                results.count = nHolderList.size();
            }
            return results;
        }
        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint,FilterResults results) {
            if (results.count == 0)
                notifyDataSetInvalidated();
            else {
                holderarray = (ArrayList<Holder>) results.values;
                notifyDataSetChanged();
            }
        }
    }
}

static class ViewHolder {
    CheckBox checkBox;
    TextView name;
    TextView type;
    TextView number;
}

然后我在编辑文本上执行以下操作以搜索

    final EditText search = (EditText)findViewById(R.id.search);
    search.addTextChangedListener(new TextWatcher(){
        @Override
        public void afterTextChanged(Editable arg0) {

        }
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            aadapter.getFilter().filter(s.toString());
        }
    });

logcat的输出

E/EmbeddedLogger(  509): App crashed! Process: com.test.app
E/EmbeddedLogger(  509): App crashed! Package: com.test.app v1 (1.0)
E/AndroidRuntime(29973): FATAL EXCEPTION: main
E/AndroidRuntime(29973): java.lang.IndexOutOfBoundsException: Invalid index 4, size is 4
E/AndroidRuntime(29973):    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
E/AndroidRuntime(29973):    at java.util.ArrayList.get(ArrayList.java:304)
E/AndroidRuntime(29973):    at com.test.app.sms.ContactPicker$MyCustomAdapter.getView(ContactPicker.java:197)
E/AndroidRuntime(29973):    at android.widget.AbsListView.obtainView(AbsListView.java:2350)
E/AndroidRuntime(29973):    at android.widget.ListView.makeAndAddView(ListView.java:1937)
E/AndroidRuntime(29973):    at android.widget.ListView.fillDown(ListView.java:789)
E/AndroidRuntime(29973):    at android.widget.ListView.fillGap(ListView.java:753)
E/AndroidRuntime(29973):    at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5259)
E/AndroidRuntime(29973):    at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3323)
E/AndroidRuntime(29973):    at android.widget.AbsListView.onTouchEvent(AbsListView.java:3609)
E/AndroidRuntime(29973):    at android.widget.ListView.onTouchEvent(ListView.java:4027)
E/AndroidRuntime(29973):    at android.view.View.dispatchTouchEvent(View.java:7175)
E/AndroidRuntime(29973):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2181)
E/AndroidRuntime(29973):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1916)
E/AndroidRuntime(29973):    at android.widget.AbsListView.dispatchTouchEvent(AbsListView.java:6882)
E/AndroidRuntime(29973):    at android.widget.ListView.dispatchTouchEvent(ListView.java:4441)
E/AndroidRuntime(29973):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2187)
E/AndroidRuntime(29973):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1930)
E/AndroidRuntime(29973):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2187)
E/AndroidRuntime(29973):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1930)
E/AndroidRuntime(29973):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2187)
E/AndroidRuntime(29973):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1930)
E/AndroidRuntime(29973):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2187)
E/AndroidRuntime(29973):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1930)
E/AndroidRuntime(29973):    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2041)
E/AndroidRuntime(29973):    at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1495)
E/AndroidRuntime(29973):    at android.app.Activity.dispatchTouchEvent(Activity.java:2454)
E/AndroidRuntime(29973):    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1989)
E/AndroidRuntime(29973):    at android.view.View.dispatchPointerEvent(View.java:7369)
E/AndroidRuntime(29973):    at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3549)
E/AndroidRuntime(29973):    at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3478)
E/AndroidRuntime(29973):    at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4587)
E/AndroidRuntime(29973):    at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4566)
E/AndroidRuntime(29973):    at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4658)
E/AndroidRuntime(29973):    at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:184)
E/AndroidRuntime(29973):    at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
E/AndroidRuntime(29973):    at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:171)
E/AndroidRuntime(29973):    at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:4637)
E/AndroidRuntime(29973):    at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:4686)
E/AndroidRuntime(29973):    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
E/AndroidRuntime(29973):    at android.view.Choreographer.doCallbacks(Choreographer.java:555)
E/AndroidRuntime(29973):    at android.view.Choreographer.doFrame(Choreographer.java:523)
E/AndroidRuntime(29973):    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
E/AndroidRuntime(29973):    at android.os.Handler.handleCallback(Handler.java:615)
E/AndroidRuntime(29973):    at android.os.Handler.dispatchMessage(Handler.java:92)
E/AndroidRuntime(29973):    at android.os.Looper.loop(Looper.java:155)
E/AndroidRuntime(29973):    at android.app.ActivityThread.main(ActivityThread.java:5485)
E/AndroidRuntime(29973):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(29973):    at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(29973):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
E/AndroidRuntime(29973):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:795)
E/AndroidRuntime(29973):    at dalvik.system.NativeStart.main(Native Method)
E/EmbeddedLogger(  509): Application Label: Test App
W/ActivityManager(  509):   Force finishing activity com.test.app/.sms.ContactPicker

1 个答案:

答案 0 :(得分:1)

找到我需要的东西 ArrayIndexOutOfBoundsException with ArrayAdapter with filter

基本上我刚添加了这个

@Override
public int getCount () {
    return holderarray.size ();
}

现在一切都很好