http://blog.csdn.net/wyzxk888/article/details/8800407
简单的说就是ListView上面有一个SearchBox,然后searchbox里输入内容后对下面listview进行过滤。
涉及的控件:ListView必须有,EditText用来自定义SearchBox
大概就是这样:
先看这个有图片的EditText,实现方法有两个,一是用相对布局RelativeLayout + ImageView + EditText。
二是直接用EditText的一个属性DrawableLeft,简单的UI这个就可以实现了
所以这个Activity的布局就很简单,可以用ListActivity实现:
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingBottom="@dimen/activity_vertical_margin"
- android:paddingLeft="@dimen/activity_horizontal_margin"
- android:paddingRight="@dimen/activity_horizontal_margin"
- android:paddingTop="@dimen/activity_vertical_margin"
- tools:context=".MainActivity" >
- <EditText
- android:id="@+id/searchbox"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentTop="true"
- android:drawableLeft="@drawable/searchbox"
- android:hint="Search"
- android:drawablePadding="5dp"
- android:singleLine="true"
- android:ems="10" >
- <requestFocus />
- </EditText>
- <ListView
- android:id="@android:id/list"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_below="@id/searchbox">
- </ListView>
- </RelativeLayout>
再说过滤功能:这个感觉不想搜索,就像是简单的过滤,如果涉及到去数据库取数据那个才是搜索了
用到了Filterable接口,Filter类
要让数据有过滤功能,我们需要在继承的BaseAdapter的基础上再实现Filterable接口的getFilter方法,同时在Adapter内部写一个继承Filter的内部类来完成过滤功能:
- private class ListAdapter extends BaseAdapter implements Filterable {
- private List<Person> list;
- private Context context;
- private PersonFilter filter;
- public ListAdapter(List<Person> list, Context context) {
- this.list = list;
- this.context = context;
- }
- @Override
- public int getCount() {
- return list.size();
- }
- @Override
- public Object getItem(int position) {
- return list.get(position);
- }
- @Override
- public long getItemId(int position) {
- return position;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- if (convertView == null) {
- convertView = LayoutInflater.from(context).inflate(R.layout.list_item, null);
- }
- Person p = list.get(position);
- TextView firstname = (TextView)convertView.findViewById(R.id.firstname);
- TextView lastname = (TextView)convertView.findViewById(R.id.lastname);
- TextView age = (TextView)convertView.findViewById(R.id.age);
- firstname.setText(p.firstname);
- lastname.setText(p.lastname);
- age.setText(p.age + "");
- return convertView;
- }
- @Override
- public Filter getFilter() {
- if (filter == null) {
- filter = new PersonFilter(list);
- }
- return filter;
- }
- private class PersonFilter extends Filter {
- private List<Person> original;
- public PersonFilter(List<Person> list) {
- this.original = list;
- }
- @Override
- protected FilterResults performFiltering(CharSequence constraint) {
- FilterResults results = new FilterResults();
- if (constraint == null || constraint.length() == 0) {
- results.values = original;
- results.count = original.size();
- } else {
- List<Person> mList = new ArrayList<Person>();
- for (Person p: original) {
- if (p.firstname.toUpperCase().startsWith(constraint.toString().toUpperCase())
- || p.lastname.toUpperCase().startsWith(constraint.toString().toUpperCase())
- || new String(p.age + "").toUpperCase().startsWith(constraint.toString().toUpperCase())) {
- mList.add(p);
- }
- }
- results.values = mList;
- results.count = mList.size();
- }
- return results;
- }
- @Override
- protected void publishResults(CharSequence constraint,
- FilterResults results) {
- list = (List<Person>)results.values;
- notifyDataSetChanged();
- }
- }
- }
Filter类中的两个方法看名字就是知道一个是执行过滤的,一个刷新listview数据展现结果的。其中我采用了前缀匹配,就是用输入的字符串和ListView里的所有Person的各个属性的前缀做比较。也可以用更加复杂的匹配,例如正则表达式。
关键在于EditText里的数据是如何传入的,要写一个TextWater,并且要让EditText注册一下这个监听器:
- private TextWatcher filterTextWatcher = new TextWatcher() {
- @Override
- public void afterTextChanged(Editable s) {
- }
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count,
- int after) {
- }
- @Override
- public void onTextChanged(CharSequence s, int start, int before,
- int count) {
- listAdapter.getFilter().filter(s); //这里传入数据就可以了
- }
- };
以上关键代码。非关键代码是Person类以及List_Item的布局:
- private class Person {
- public String firstname;
- public String lastname;
- public int age;
- public Person(String firtname, String lastname, int age) {
- this.firstname = firtname;
- this.lastname = lastname;
- this.age = age;
- }
- }
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal" >
- <TextView
- android:id="@+id/firstname"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="10dp"
- android:text="Firstname" />
- <TextView
- android:id="@+id/lastname"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="10dp"
- android:text="Lastname" />
- <TextView
- android:id="@+id/age"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="10dp"
- android:text="Age" />
- </LinearLayout>