通过EditText中的输入,实现ListView过滤,主要是让adapter实现Filterable接口。可以参考SimpleAdapter的实现方式。
至于拼音过滤,在google code中有一个pinyin4android的开源项目,已经实现了对中文拼音的匹配。
效果图:
定义一个UserAdapter,对user的name字段进行过滤:
- public class UserAdapter extends BaseAdapter implements Filterable{
- private List<User> users;
- public Context mContext;
- private LayoutInflater mInflater;
- private FilterDemo mFilter;
- private ArrayList<User> mDisplayData;
- //记录索引
- private ArrayList<FilterIndex> mFilterIndexs;
- public UserAdapter(Context context, List<User> users)
- {
- super();
- mContext = context;
- this.users = users;
- mDisplayData = (ArrayList<User>) users;
- mFilterIndexs = new ArrayList<FilterIndex>();
- mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- }
- @Override
- public int getCount()
- {
- // TODO Auto-generated method stub
- return mDisplayData.size();
- }
- @Override
- public Object getItem(int position)
- {
- // TODO Auto-generated method stub
- return mDisplayData.get(position);
- }
- @Override
- public long getItemId(int position)
- {
- // TODO Auto-generated method stub
- return mDisplayData.get(position).getId();
- }
- @Override
- public View getView(final int position, View convertView, ViewGroup parent)
- {
- // TODO Auto-generated method stub
- if (convertView == null)
- convertView = mInflater.inflate(R.layout.item, null);
- ViewHolder holder = new ViewHolder();
- holder.name = (TextView) convertView.findViewById(R.id.name);
- holder.age = (TextView) convertView.findViewById(R.id.age);
- User user = mDisplayData.get(position);
- SpannableStringBuilder ss=new SpannableStringBuilder(user.getName());
- if(!mFilterIndexs.isEmpty())
- ss.setSpan(new ForegroundColorSpan(Color.RED),mFilterIndexs.get(position).getBegin(),mFilterIndexs.get(position).getEnd(),Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
- holder.name.setText(ss);
- holder.age.setText(user.getAge()+"");
- return convertView;
- }
- static class ViewHolder
- {
- TextView name;
- TextView age;
- }
- @Override
- public Filter getFilter()
- {
- // TODO Auto-generated method stub
- if (mFilter == null) {
- mFilter = new FilterDemo();
- }
- return mFilter;
- }
- private class FilterDemo extends Filter {
- @Override
- protected FilterResults performFiltering(CharSequence prefix) {
- FilterResults results = new FilterResults();
- ArrayList<String> mData = new ArrayList<String>();
- mFilterIndexs.clear();
- for(int i = 0; i < users.size(); i ++){
- String name = users.get(i).getName();
- mData.add(name);
- }
- if (prefix == null || prefix.length() == 0) {
- results.values = mData;
- results.count = mData.size();
- } else {
- String prefixString = prefix.toString();
- int count = mData.size();
- ArrayList<String> newValues = new ArrayList<String>(count);
- for (int j = 0; j < count; j++) {
- String s = mData.get(j);
- //
- String s1 = getPinYinHeadChar(s);
- if(s1.contains(prefixString))
- {
- getFilterIndex(s1,prefixString);
- newValues.add(s);
- }else
- if(s.contains(prefixString))
- {
- getFilterIndex(s,prefixString);
- newValues.add(s);
- }
- }
- results.values = newValues;
- results.count = newValues.size();
- }
- return results;
- }
- @SuppressWarnings("unchecked")
- @Override
- protected void publishResults(CharSequence constraint, FilterResults results) {
- mDisplayData = new ArrayList<User>(results.count);
- for(String username:(ArrayList<String>)results.values)
- {
- for(User userInfo:users)
- {
- if(userInfo.getName().equals(username)){
- mDisplayData.add(userInfo);
- }
- }
- }
- notifyDataSetChanged();
- }
- //提取汉字的首字母
- private String getPinYinHeadChar(String str) {
- StringBuilder convert = new StringBuilder();
- int length = str.length();
- for (int j = 0; j < length; j++) {
- char word = str.charAt(j);
- try {
- String pinyinArray = PinyinUtil.toPinyin(mContext, word);
- if (pinyinArray != null) {
- convert.append(pinyinArray.charAt(0));
- } else {
- convert.append(word);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- return convert.toString();
- }
- /**
- * 获取指定字符的开始与结束的位置
- */
- private void getFilterIndex(String father,String child)
- {
- int start = father.indexOf(child);
- int end = start+child.length();
- FilterIndex filterIndex = new FilterIndex(start,end);
- mFilterIndexs.add(filterIndex);
- }
- }
- class FilterIndex
- {
- private int begin;
- private int end;
- public FilterIndex(int begin,int end)
- {
- this.begin = begin;
- this.end = end;
- }
- public int getBegin() {
- return begin;
- }
- public void setBegin(int begin) {
- this.begin = begin;
- }
- public int getEnd() {
- return end;
- }
- public void setEnd(int end) {
- this.end = end;
- }
- }
- }
然后再Activity中使用该adapter,为EditText添加addTextChangedListener:
- private ListView mListView;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- initComponent();
- }
- private void initComponent() {
- // TODO Auto-generated method stub
- EditText edit = (EditText) findViewById(R.id.edit);
- mListView = (ListView) findViewById(R.id.list_view);
- List<User> users = new ArrayList<User>();
- users.add(0, new User("zhangsan", 20));
- users.add(1, new User("lishi", 21));
- users.add(1, new User("wangwu", 21));
- users.add(1, new User("zhaoliu", 21));
- users.add(1, new User("xiaoming", 21));
- users.add(1, new User("daming", 21));
- final UserAdapter adapter = new UserAdapter(this, users);
- mListView.setAdapter(adapter);
- edit.addTextChangedListener(new TextWatcher() {
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- // TODO Auto-generated method stub
- }
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count,
- int after) {
- // TODO Auto-generated method stub
- }
- @Override
- public void afterTextChanged(Editable s) {
- // TODO Auto-generated method stub
- adapter.getFilter().filter(s);
- }
- });
- }