Android实现Filterable通过输入文本框实现联系人自动筛选

相信大家一定在见过手机通讯录的一个情景就是使用在选人的时候输入文本框里的数据就能自动筛选。实现的效果如下图。

Android实现Filterable通过输入文本框实现联系人自动筛选

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

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

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

    1. et_filter.addTextChangedListener(new TextWatcher() {
    2. @Override
    3. public void onTextChanged(CharSequence s, int start, int before,
    4. int count) {
    5. adapter.getFilter().filter(et_filter.getText().toString());
    6. }
    7. @Override
    8. public void beforeTextChanged(CharSequence s, int start, int count,
    9. int after) {
    10. // TODO Auto-generated method stub
    11. }
    12. @Override
    13. public void afterTextChanged(Editable s) {
    14. // TODO Auto-generated method stub
    15. }
    16. });
上一篇:Ubuntu引导修复问题


下一篇:Alpha-6