过滤Filterable

http://blog.csdn.net/jiahui524

相信大家一定在见过手机通讯录的一个情景就是使用在选人的时候输入文本框里的数据就能自动筛选。今天也受一网友邀请,所以还是整理了一下这块的知识点,现在与大家共享一下,有什么疑惑的可以与我交流。实现的效果如下图。


其实实现这样的效果相信大家一定对另外一个控件不陌生那就AutoCompleteTextview,看一下这个控件的源代码也许就能找到你需要的答案。这里的核心就是一个Filterable。至于Filterable的介绍和做什么用的大家就可以自行上网查找相关知识,其中有两个重要的方法

 

方法名

作用

protected FilterResults performFiltering(CharSequence prefix)

在这个方法里执行过滤方法

protected void publishResults(CharSequence constraint,

            FilterResults results)

在这个方法里发布筛选过后得到的数据同时更新Adapter更新

 

理解这点知识那么就看核心代码吧,这里就是重写BaseAdapter然后实现Filterable

  1. public class UserAdapter extends BaseAdapter implements Filterable { 
  2.  
  3.     private MyFilter myFilter; 
  4.     private List<UserInfo> userInfos; 
  5.     private Context context; 
  6.  
  7.     private ArrayList<UserInfo> mOriginalValues; 
  8.  
  9.     private final Object mLock = new Object(); 
  10.  
  11.     public UserAdapter(Context context, List<UserInfo> userInfos) { 
  12.         this.context = context; 
  13.         this.userInfos = userInfos; 
  14.  
  15.     } 
  16.  
  17.     @Override 
  18.     public int getCount() { 
  19.         // TODO Auto-generated method stub 
  20.         return userInfos.size(); 
  21.     } 
  22.  
  23.     @Override 
  24.     public Object getItem(int arg0) { 
  25.         // TODO Auto-generated method stub 
  26.         return userInfos.get(arg0); 
  27.     } 
  28.  
  29.     @Override 
  30.     public long getItemId(int position) { 
  31.         // TODO Auto-generated method stub 
  32.         return position; 
  33.     } 
  34.  
  35.     @Override 
  36.     public View getView(int position, View convertView, ViewGroup parent) { 
  37.  
  38.         View view = convertView; 
  39.  
  40.         ViewHolder holder; 
  41.         if (view == null) { 
  42.             view = LayoutInflater.from(context).inflate(R.layout.list_item, 
  43.                     null); 
  44.             holder = new ViewHolder(); 
  45.  
  46.             holder.tv_nick = (TextView) view.findViewById(R.id.tv_nick); 
  47.             holder.tv_mobile = (TextView) view.findViewById(R.id.tv_mobile); 
  48.             view.setTag(holder); 
  49.         } else
  50.             holder = (ViewHolder) view.getTag(); 
  51.         } 
  52.  
  53.         holder.tv_nick.setText(userInfos.get(position).getUsername()); 
  54.         holder.tv_mobile.setText(userInfos.get(position).getPhonenum()); 
  55.  
  56.         return view; 
  57.     } 
  58.  
  59.     static class ViewHolder { 
  60.  
  61.         TextView tv_nick; 
  62.         TextView tv_mobile; 
  63.     } 
  64.  
  65.     @Override 
  66.     public Filter getFilter() { 
  67.         if (myFilter == null) { 
  68.             myFilter = new MyFilter(); 
  69.         } 
  70.         return myFilter; 
  71.     } 
  72.  
  73.     class MyFilter extends Filter { 
  74.  
  75.         @Override 
  76.         protected FilterResults performFiltering(CharSequence prefix) { 
  77.             // 持有过滤操作完成之后的数据。该数据包括过滤操作之后的数据的值以及数量。 count:数量 values包含过滤操作之后的数据的值 
  78.             FilterResults results = new FilterResults(); 
  79.  
  80.             if (mOriginalValues == null) { 
  81.                 synchronized (mLock) { 
  82.                     // 将list的用户 集合转换给这个原始数据的ArrayList 
  83.                     mOriginalValues = new ArrayList<UserInfo>(userInfos); 
  84.                 } 
  85.             } 
  86.             if (prefix == null || prefix.length() == 0) { 
  87.                 synchronized (mLock) { 
  88.                     ArrayList<UserInfo> list = new ArrayList<UserInfo>( 
  89.                             mOriginalValues); 
  90.                     results.values = list; 
  91.                     results.count = list.size(); 
  92.                 } 
  93.             } else
  94.                 // 做正式的筛选 
  95.                 String prefixString = prefix.toString().toLowerCase(); 
  96.  
  97.                 // 声明一个临时的集合对象 将原始数据赋给这个临时变量 
  98.                 final ArrayList<UserInfo> values = mOriginalValues; 
  99.  
  100.                 final int count = values.size(); 
  101.  
  102.                 // 新的集合对象 
  103.                 final ArrayList<UserInfo> newValues = new ArrayList<UserInfo>( 
  104.                         count); 
  105.  
  106.                 for (int i = 0; i < count; i++) { 
  107.                     // 如果姓名的前缀相符或者电话相符就添加到新的集合 
  108.                     final UserInfo value = (UserInfo) values.get(i); 
  109.  
  110.                     Log.i("coder", "PinyinUtils.getAlpha(value.getUsername())" 
  111.                             + PinyinUtils.getAlpha(value.getUsername())); 
  112.                     if (PinyinUtils.getAlpha(value.getUsername()).startsWith( 
  113.                             prefixString) 
  114.                             || value.getPhonenum().startsWith(prefixString)||value.getUsername().startsWith(prefixString)) { 
  115.  
  116.                         newValues.add(value); 
  117.                     } 
  118.                 } 
  119.                 // 然后将这个新的集合数据赋给FilterResults对象 
  120.                 results.values = newValues; 
  121.                 results.count = newValues.size(); 
  122.             } 
  123.  
  124.             return results; 
  125.         } 
  126.  
  127.         @Override 
  128.         protected void publishResults(CharSequence constraint, 
  129.                 FilterResults results) { 
  130.             // 重新将与适配器相关联的List重赋值一下 
  131.             userInfos = (List<UserInfo>) results.values; 
  132.  
  133.             if (results.count > 0) { 
  134.                 notifyDataSetChanged(); 
  135.             } else
  136.                 notifyDataSetInvalidated(); 
  137.             } 
  138.         } 
  139.  
  140.     } 
public class UserAdapter extends BaseAdapter implements Filterable {

	private MyFilter myFilter;
	private List<UserInfo> userInfos;
	private Context context;

	private ArrayList<UserInfo> mOriginalValues;

	private final Object mLock = new Object();

	public UserAdapter(Context context, List<UserInfo> userInfos) {
		this.context = context;
		this.userInfos = userInfos;

	}

	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return userInfos.size();
	}

	@Override
	public Object getItem(int arg0) {
		// TODO Auto-generated method stub
		return userInfos.get(arg0);
	}

	@Override
	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {

		View view = convertView;

		ViewHolder holder;
		if (view == null) {
			view = LayoutInflater.from(context).inflate(R.layout.list_item,
					null);
			holder = new ViewHolder();

			holder.tv_nick = (TextView) view.findViewById(R.id.tv_nick);
			holder.tv_mobile = (TextView) view.findViewById(R.id.tv_mobile);
			view.setTag(holder);
		} else {
			holder = (ViewHolder) view.getTag();
		}

		holder.tv_nick.setText(userInfos.get(position).getUsername());
		holder.tv_mobile.setText(userInfos.get(position).getPhonenum());

		return view;
	}

	static class ViewHolder {

		TextView tv_nick;
		TextView tv_mobile;
	}

	@Override
	public Filter getFilter() {
		if (myFilter == null) {
			myFilter = new MyFilter();
		}
		return myFilter;
	}

	class MyFilter extends Filter {

		@Override
		protected FilterResults performFiltering(CharSequence prefix) {
			// 持有过滤操作完成之后的数据。该数据包括过滤操作之后的数据的值以及数量。 count:数量 values包含过滤操作之后的数据的值
			FilterResults results = new FilterResults();

			if (mOriginalValues == null) {
				synchronized (mLock) {
					// 将list的用户 集合转换给这个原始数据的ArrayList
					mOriginalValues = new ArrayList<UserInfo>(userInfos);
				}
			}
			if (prefix == null || prefix.length() == 0) {
				synchronized (mLock) {
					ArrayList<UserInfo> list = new ArrayList<UserInfo>(
							mOriginalValues);
					results.values = list;
					results.count = list.size();
				}
			} else {
				// 做正式的筛选
				String prefixString = prefix.toString().toLowerCase();

				// 声明一个临时的集合对象 将原始数据赋给这个临时变量
				final ArrayList<UserInfo> values = mOriginalValues;

				final int count = values.size();

				// 新的集合对象
				final ArrayList<UserInfo> newValues = new ArrayList<UserInfo>(
						count);

				for (int i = 0; i < count; i++) {
					// 如果姓名的前缀相符或者电话相符就添加到新的集合
					final UserInfo value = (UserInfo) values.get(i);

					Log.i("coder", "PinyinUtils.getAlpha(value.getUsername())"
							+ PinyinUtils.getAlpha(value.getUsername()));
					if (PinyinUtils.getAlpha(value.getUsername()).startsWith(
							prefixString)
							|| value.getPhonenum().startsWith(prefixString)||value.getUsername().startsWith(prefixString)) {

						newValues.add(value);
					}
				}
				// 然后将这个新的集合数据赋给FilterResults对象
				results.values = newValues;
				results.count = newValues.size();
			}

			return results;
		}

		@Override
		protected void publishResults(CharSequence constraint,
				FilterResults results) {
			// 重新将与适配器相关联的List重赋值一下
			userInfos = (List<UserInfo>) results.values;

			if (results.count > 0) {
				notifyDataSetChanged();
			} else {
				notifyDataSetInvalidated();
			}
		}

	}
}


具体有看不懂的代码可以看注释或者加我QQ

最后再看一下是怎么用的吧

  1. et_filter.addTextChangedListener(new TextWatcher() { 
  2.  
  3.             @Override 
  4.             public void onTextChanged(CharSequence s, int start, int before, 
  5.                     int count) { 
  6.                 adapter.getFilter().filter(et_filter.getText().toString()); 
  7.  
  8.             } 
  9.  
  10.             @Override 
  11.             public void beforeTextChanged(CharSequence s, int start, int count, 
  12.                     int after) { 
  13.                 // TODO Auto-generated method stub 
  14.  
  15.             } 
  16.  
  17.             @Override 
  18.             public void afterTextChanged(Editable s) { 
  19.                 // TODO Auto-generated method stub 
  20.  
  21.             } 
  22.         }); 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值