简单的说就是ListView上面有一个SearchBox,然后searchbox里输入内容后对下面listview进行过滤。
涉及的控件:ListView必须有,EditText用来自定义SearchBox
大概就是这样:
先看这个有图片的EditText,实现方法有两个,一是用相对布局RelativeLayout + ImageView + EditText。
二是直接用EditText的一个属性DrawableLeft,简单的UI这个就可以实现了
所以这个Activity的布局就很简单,可以用ListActivity实现:
1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
2. xmlns:tools="http://schemas.android.com/tools"
3. android:layout_width="match_parent"
4. android:layout_height="match_parent"
5. android:paddingBottom="@dimen/activity_vertical_margin"
6. android:paddingLeft="@dimen/activity_horizontal_margin"
7. android:paddingRight="@dimen/activity_horizontal_margin"
8. android:paddingTop="@dimen/activity_vertical_margin"
9. tools:context=".MainActivity" >
10.
11. <EditText
12. android:id="@+id/searchbox"
13. android:layout_width="wrap_content"
14. android:layout_height="wrap_content"
15. android:layout_alignParentTop="true"
16. android:drawableLeft="@drawable/searchbox"
17. android:hint="Search"
18. android:drawablePadding="5dp"
19. android:singleLine="true"
20. android:ems="10" >
21. <requestFocus />
22. </EditText>
23.
24.
25. <ListView
26. android:id="@android:id/list"
27. android:layout_width="match_parent"
28. android:layout_height="wrap_content"
29. android:layout_below="@id/searchbox">
30. </ListView>
31.
32. </RelativeLayout>
再说过滤功能:这个感觉不想搜索,就像是简单的过滤,如果涉及到去数据库取数据那个才是搜索了
用到了Filterable接口,Filter类
要让数据有过滤功能,我们需要在继承的BaseAdapter的基础上再实现Filterable接口的getFilter方法,同时在Adapter内部写一个继承Filter的内部类来完成过滤功能:
1. private class ListAdapter extends BaseAdapter implements Filterable {1
. private List<Person> list;
2.
3. private Context context;
4.
5. private PersonFilter filter;
6.
7. public ListAdapter(List<Person> list, Context context) {
8. this.list = list;
9. this.context = context;
10. }
11.
12. @Override
13. public int getCount() {
14. return list.size();
15. }
16.
17. @Override
18. public Object getItem(int position) {
19. return list.get(position);
20. }
21.
22. @Override
23. public long getItemId(int position) {
24. return position;
25. }
26.
27. @Override
28. public View getView(int position, View convertView, ViewGroup parent) {
29. if (convertView == null) {
30. null);
31. }
32. Person p = list.get(position);
33. TextView firstname = (TextView)convertView.findViewById(R.id.firstname);
34. TextView lastname = (TextView)convertView.findViewById(R.id.lastname);
35. TextView age = (TextView)convertView.findViewById(R.id.age);
36.
37. firstname.setText(p.firstname);
38. lastname.setText(p.lastname);
39. "");
40. return convertView;
41. }
42.
43. @Override
44. public Filter getFilter() {
45. if (filter == null) {
46. new PersonFilter(list);
47. }
48. return filter;
49. }
50.
51. private class PersonFilter extends Filter {
52.
53. private List<Person> original;
54.
55. public PersonFilter(List<Person> list) {
56. this.original = list;
57. }
58.
59. @Override
60. protected FilterResults performFiltering(CharSequence constraint) {
61. new FilterResults();
62. if (constraint == null || constraint.length() == 0) {
63. results.values = original;
64. results.count = original.size();
65. else {
66. new ArrayList<Person>();
67. for (Person p: original) {
68. if (p.firstname.toUpperCase().startsWith(constraint.toString().toUpperCase())
69. || p.lastname.toUpperCase().startsWith(constraint.toString().toUpperCase())
70. new String(p.age + "").toUpperCase().startsWith(constraint.toString().toUpperCase())) {
71. mList.add(p);
72. }
73. }
74. results.values = mList;
75. results.count = mList.size();
76. }
77. return results;
78. }
79.
80. @Override
81. protected void publishResults(CharSequence constraint,
82. FilterResults results) {
83. list = (List<Person>)results.values;
84. notifyDataSetChanged();
85. }
86.
87. }
88. }
Filter类中的两个方法看名字就是知道一个是执行过滤的,一个刷新listview数据展现结果的。其中我采用了前缀匹配,就是用输入的字符串和ListView里的所有Person的各个属性的前缀做比较。也可以用更加复杂的匹配,例如正则表达式。
关键在于EditText里的数据是如何传入的,要写一个TextWater,并且要让EditText注册一下这个监听器:
1. private TextWatcher filterTextWatcher = new TextWatcher() {
2.
3. @Override
4. public void afterTextChanged(Editable s) {
5.
6. }
7.
8. @Override
9. public void beforeTextChanged(CharSequence s, int start, int count,
10. int after) {
11.
12. }
13.
14. @Override
15. public void onTextChanged(CharSequence s, int start, int before,
16. int count) {
17. //这里传入数据就可以了
18. }
19.
20. };
以上关键代码。非关键代码是Person类以及List_Item的布局:
1. private class Person {
2. public String firstname;
3. public String lastname;
4. public int age;
5.
6. public Person(String firtname, String lastname, int age) {
7. this.firstname = firtname;
8. this.lastname = lastname;
9. this.age = age;
10. }
11. }
1. <?xml version="1.0" encoding="utf-8"?>
2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3. android:layout_width="match_parent"
4. android:layout_height="match_parent"
5. android:orientation="horizontal" >
6.
7. <TextView
8. android:id="@+id/firstname"
9. android:layout_width="wrap_content"
10. android:layout_height="wrap_content"
11. android:layout_margin="10dp"
12. android:text="Firstname" />
13.
14. <TextView
15. android:id="@+id/lastname"
16. android:layout_width="wrap_content"
17. android:layout_height="wrap_content"
18. android:layout_margin="10dp"
19. android:text="Lastname" />
20.
21. <TextView
22. android:id="@+id/age"
23. android:layout_width="wrap_content"
24. android:layout_height="wrap_content"
25. android:layout_margin="10dp"
26. android:text="Age" />
27.
28. </LinearLayout>