带自定义适配器的Android ListView搜索无法正常工作

时间:2014-04-28 11:07:01

标签: android android-listview custom-adapter

我正在尝试在ndroid ListView上应用搜索,但它不适用于我,这是我尝试过的代码。

final ArrayList<Users> uData = new ArrayList<Users>();
listView = (ListView) findViewById(R.id.listView1);
listView.setAdapter(new CustomListAdapter(this, uData));

searchBox.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
                // When user changed the Text
                ((Filterable) ViewInfo.this.listView.getAdapter()).getFilter().filter(cs);  
            }

            @Override
            public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
                    int arg3) {
                // TODO Auto-generated method stub

            }

            @Override
            public void afterTextChanged(Editable arg0) {
                // TODO Auto-generated method stub                         
            }


        });

这是Users类

public class Users implements Serializable 
{
private String name;
private String date;
private String email;
private String image;


public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public String getDate() {
    return date;
}
public void setDate(String date) {
    this.date = date;
}
public String getEmail() {
    return email;
}
public void setEmail(String email) {
    this.email = email;
}
public String getimage() {
    return image;
}
public void setimage(String image) {
    this.image = image;
}

这里是CustomListAdapter

public class CustomListAdapter extends BaseAdapter {

    private ArrayList<Users> listData;
     private LayoutInflater layoutInflater;
     Users Act = new Users();

     public CustomListAdapter(Context context, ArrayList<Users> listData) {
            this.listData = listData;
            layoutInflater = LayoutInflater.from(context);
        }

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

        @Override
        public Object getItem(int position) {
            return listData.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            if (convertView == null) {
                convertView = layoutInflater.inflate(R.layout.list_row, null);
                holder = new ViewHolder();
                holder.picView = (ImageView) convertView.findViewById(R.id.pic);
                holder.dateView = (TextView) convertView.findViewById(R.id.date);
                holder.nameView = (TextView) convertView.findViewById(R.id.name);
                holder.emailView = (TextView) convertView.findViewById(R.id.email);

                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }

            Users act = listData.get(position);

            holder.picView.setImageBitmap(decodeFile(act.getimage()));
            holder.dateView.setText(act.getDate());
            holder.nameView.setText(act.getName());
            holder.emailView.setText(act.getEmail());


            return convertView;
        }

        static class ViewHolder {
            ImageView picView;

            TextView dateView;
            TextView emailView;
            TextView nameView;

        }
      }

这就是LogCat所说的

04-28 15:55:52.677: E/AndroidRuntime(25953): FATAL EXCEPTION: main
04-28 15:55:52.677: E/AndroidRuntime(25953): java.lang.ClassCastException: com.assignment1.reginfo.CustomListAdapter cannot be cast to android.widget.Filterable
04-28 15:55:52.677: E/AndroidRuntime(25953):    at com.assignment1.reginfo.ViewInfo$4.onTextChanged(ViewInfo.java:186)
04-28 15:55:52.677: E/AndroidRuntime(25953):    at android.widget.TextView.sendOnTextChanged(TextView.java:7518)
04-28 15:55:52.677: E/AndroidRuntime(25953):    at android.widget.TextView.handleTextChanged(TextView.java:7580)
04-28 15:55:52.677: E/AndroidRuntime(25953):    at android.widget.TextView$ChangeWatcher.onTextChanged(TextView.java:9329)
04-28 15:55:52.677: E/AndroidRuntime(25953):    at android.text.SpannableStringBuilder.sendTextChanged(SpannableStringBuilder.java:962)
04-28 15:55:52.677: E/AndroidRuntime(25953):    at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:496)

3 个答案:

答案 0 :(得分:1)

您使用的适配器不适用于Filter。它仅适用于ArrayAdapter。因此,要么使用ArrayAdapter,要么编写自己的代码来过滤数据。

答案 1 :(得分:1)

You may follow below step:
1) Implements your Base adapter class with filterable class
2) You will get overriden method "public Filter getFilter()" you can use below code for filtering data

mListe is the original ArrayList<ContactsPojo>
mListSearch is the filtered ArrayList<ContactsPojo>

@Override
    public Filter getFilter() {
        Filter filter = new Filter() {

            @SuppressWarnings("null")
            @SuppressLint("DefaultLocale")
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults result = new FilterResults();

                if (constraint != null && constraint.length() > 0) {
                    synchronized (this) {
                        mListSearch = new ArrayList<ContactsPojo>();
                        for (int i = 0; i < mListe.size(); i++) {
                            if ((mListe.get(i).getContactsName().toUpperCase())
                                    .contains(constraint.toString()
                                            .toUpperCase())) {

                                ContactsPojo contacts = new ContactsPojo();
                                contacts.setContactsName(mListe.get(i)
                                        .getContactsName());
                                contacts.setImage(mListe.get(i).getImage());
                                mListSearch.add(contacts);
                            }
                        }

                    }

                    result.count = mListSearch.size();
                    result.values = mListSearch;
                } else if (constraint == null && constraint.length() == 0) {

                    synchronized (this) {
                        result.count = mListe.size();
                        result.values = mListe;

                    }

                }

                return result;
            }

            @SuppressWarnings("unchecked")
            @Override
            protected void publishResults(CharSequence constraint,
                    FilterResults result) {
                if (result.count == 0) {
//                  mListe = (ArrayList<ContactsPojo>) mListe;
                    notifyDataSetInvalidated();
                } else {
                    mListe = (ArrayList<ContactsPojo>) result.values;
                    notifyDataSetChanged();
                }
            }

        };

        return filter;
    }


3) Then you can add this filter to edittext 
     edtSearchContacts.addTextChangedListener(new TextWatcher() {

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

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

            }

            @SuppressLint("NewApi")
            @Override
            public void afterTextChanged(Editable s) {
                if (s.toString().isEmpty()) {
                    mlistAdapter = new MyListAdapterTwoLine(_con, al3);
                    lvPhnContacts.setAdapter(mlistAdapter);

                }
            }
        });
    }

In afterTextChanged method you will get original items back to listview.

答案 2 :(得分:0)

您无法将BaseAdapter转换为Filterable。因BaseAdapter未实施Filterable。尝试使用SimpleAdapter