Android實現Filterable通過輸入文本框實現聯繫人自動篩選

 

相信大家一定在見過手機通訊錄的一個情景就是使用在選人的時候輸入文本框裏的數據就能自動篩選。今天也受一網友邀請,所以還是整理了一下這塊的知識點,現在與大家共享一下,有什麼疑惑的可以與我交流。實現的效果如下圖。


其實實現這樣的效果相信大家一定對另外一個控件不陌生那就AutoCompleteTextview,看一下這個控件的源代碼也許就能找到你需要的答案。這裏的核心就是一個Filterable。至於Filterable的介紹和做什麼用的大家就可以自行上網查找相關知識,其中有兩個重要的方法

方法名

作用

protected FilterResults performFiltering(CharSequence prefix)

在這個方法裏執行過濾方法

protected void publishResults(CharSequence constraint,

            FilterResults results)

在這個方法裏發佈篩選過後得到的數據同時更新Adapter更新

 

 

理解這點知識那麼就看核心代碼吧,這裏就是重寫BaseAdapter然後實現Filterable

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

最後再看一下是怎麼用的吧

et_filter.addTextChangedListener(new TextWatcher() {

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

			}

			@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

			}
		});


 

好了這麼一樣的一個功能就如此簡單的完成了,希望能對大家有所幫助了

如需轉載引用請註明出處:http://blog.csdn.net/jiahui524

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章