Filter 过滤器

    一、结构

    public abstract class Filter extends Object
 
java.lang.Object
     android.widget.Filter
 

  二、概述

    过滤器通过过滤模式来约束数据,通常由实现了Filterable接口的子类来生成。 过滤操作是通过调用 filter(CharSequence) 或者 filter(CharSequence, android.widget.Filter.FilterListener)这些异步方法来完成的。以上方法一旦被调用,过滤请求就会被递交到请求队列中等待处理,同时该操作会取消那些之前递交的但是还没有被处理的请求。
 

  三、构造函数

         public Filter ()
  创建一个新的异步过滤器。
 
 

  四、公共方法

 
  public CharSequence convertResultToString (Object resultValue)
        将受过滤的集合对象转换成CharSequence文本。所有继承了Filter的子类应该重写该方法。该方法的默认实现:如果参数为null则返回空字符串或者返回参数的字符串形式.
  参数
                            resultValue 转换成CharSequence文本的对象
                 返回值
                            CharSequence 文本
                  
  public final void filter(CharSequence constraint, Filter.FilterListener listener)
  启动一个异步的过滤操作。对该方法的调用会取消之前队列中等待处理的过滤请求并且递交新的过滤请求等待执行。完成过滤操作之后,通知监听器。
  参数
                   constraint 过滤数据的约束条件
  listener 监听过滤操作完成之后发出的通知
    参见
                   filter(CharSequence)
  performFiltering(CharSequence)
  publishResults(CharSequence, android.widget.Filter.FilterResults)
 
  public final void filter(CharSequence constraint)
  启动一个异步的过滤操作。对该方法的调用会取消之前队列中等待处理的过滤请求并且递交新的过滤请求等待执行。
  参数
                  constraint 过滤数据的约束条件
                 参见
                              filter(CharSequence, android.widget.Filter.FilterListener) 
 

  五、 受保护方法

 
  protected abstract Filter.FilterResults performFiltering (CharSequence constraint)
  根据约束条件调用一个工作线程过滤数据。子类必须实现该方法来执行过滤操作。过滤结果以Filter.FilterResults的形式返回,然后在UI线程中通过publishResults(CharSequence,android.widget.Filter.FilterResults)方法来发布。
  约定:当约束条件为null时,原始数据必须被恢复。
  参数
  constraint       约束条件
  返回值
  过滤结果
  参见
                       filter(CharSequence, android.widget.Filter.FilterListener)
                       publishResults(CharSequence, android.widget.Filter.FilterResults)
                        Filter.FilterResults
 
  protected abstract void publishResults (CharSequence constraint, Filter.FilterResults results)
  通过调用UI线程在用户界面发布过滤结果。子类必须实现该方法来显示performFiltering(CharSequence)的过滤结果。
  参数
  constraint       约束条件
  results    过滤结果
  参见
                       filter(CharSequence, android.widget.Filter.FilterListener)
  performFiltering(CharSequence)
        Filter.FilterResults 
 

  六、示例代码

为过滤器设置约束条件(只显示年龄为22的用户)
public class TestFilter extends ListActivity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        ArrayList<HashMap<String,String>> list = new
                      ArrayList <HashMap<String, String>>();
        HashMap<String, String> map1 = new HashMap<String, String>();
        HashMap<String, String> map2 = new HashMap<String, String>();
        HashMap<String, String> map3 = new HashMap<String, String>();
        map1.put("name", "henly");
        map1.put("age", "22");
        map2.put("name", "john");
        map2.put("age", "23");
        map3.put("name", "lilei");
        map3.put("age", "22");
        list.add(map1);
        list.add(map2);
        list.add(map3);
        SimpleAdapter simpleAdapter = new SimpleAdapter(this, list, R.layout.user, new String[]{"name","age"}, new int[]{R.id.name,R.id.age});
        String str = new String("22");
        CharSequence constraint = str.subSequence(0, str.length());
        Filter filter = simpleAdapter.getFilter(); //得到一个过滤器
        filter.filter(constraint);  //为该过滤器设置约束条件
        setListAdapter(simpleAdapter);
    }
}

       main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <LinearLayout android:id="@+id/listlinearlayout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <ListView android:id="@id/android:list"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:drawSelectorOnTop="false"
            android:scrollbars="vertical" />
        </LinearLayout>
</LinearLayout>
      user.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:paddingLeft="12dip"
    android:paddingRight="12dip"
    android:paddingTop="1dip"
    android:paddingBottom="1dip"
    >
<TextView android:id="@+id/name"
    android:layout_width="150dip"
    android:layout_height="30dip"
    android:textSize="12pt"
    />
<TextView android:id="@+id/age"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="12pt"
    />
</LinearLayout>


码简单的说就是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的各个属性的前缀做比较。也可以用更加复杂的匹配,例如正则表达式。
以上关键代码。非关键代码是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>  



欢迎扫描二维码,关注公众号

Filter 过滤器_第1张图片

你可能感兴趣的:(android,filter)