(4.1.42)Android之Filter过滤数据

来源:互联网 发布:淘宝客api教程 编辑:程序博客网 时间:2024/06/16 11:05

一、何谓Android的过滤机制?

Android对数据的处理是分层的,从上到下,可以分为:数据层、提供层、Cursor层(不好意思,没找到一个词来表示)、适配层、显示层。每个层次通过一定的机制,可以使数据发生变化时能够上下通知。如下图:

  • 显示层(ListView,GridView,AutoCompleteTextView等)
  • 适配层(Adpater)
  • Cursor层(Cursor)
  • 提供层(ContentProvider)
  • 数据层(文件、sqlite、SharedPreference)

数据层是数据具体的存储方式,它可以包括文件、sqlite数据库以及SharedPreference。提供层向上层提供了统一的数据调用方式,并负责向其它应用共享数据。Cursor层将查询的数据统一成Cursor的形式来使用。适配层用来连接Cursor层和显示层,将数据和界面连接起来。显示层负责数据的显示。

另外,Andriod提供了数据的过滤机制,也就是在不改变数据存储的情况下,异步或同步的过滤符合条件的数据,并即时的显示在界面上。

Android原生的例子当中,最明显的例子就是AutoCompleteTextView
这里写图片描述
当输入“C程”时,数据库中自动过滤出了还有该字符串的联系人姓名,并显示出来。

二、Android做了哪些?

  1. 为了实现数据的过滤,andorid设计了抽象类Filter,进行异步和同步的数据过滤操作。
  2. 在Adapter中继承Filterable,提供给使用者Filter,进行过滤。
  3. 在不同的View中,获得查询约束字符串,传递给Adapter,并且提供配合数据过滤的界面支持。

三、Filter类

Filter的使用流程如下:

调用filter方法->在另一线程中调用performFiltering进行数据查询->得到数据过滤结果后调用publishResults将结果返回到使用它的客户端。

该类中的performFiltering和publishResults均为抽象方法,需要继承者自己重写。

四、Filterable接口

常用的Adapter基本上都继承了Filterable接口,如CursorAdapter,ArrayAdapter,SimpleAdapter等。该接口只有一个函数,名为getFilter,通过该函数可以通过Adaper获取Filter,然后通过该Filter进行过滤。

五、数据过滤功能的View的界面支持。

为了实现数据过滤的功能,在数据显示层,也有相应的支持。比如ListView和GridView,设置了setFilterText函数,通过该函数可以一方面进行数据的过滤,另一方面显示一个PopupWindow,提示用户输入了那种过滤条件。AutoCompleteTextView当用户在文本框输入文字时,自动进行过滤,并弹出列表显示过滤数据。

六、实战

MainActivity如下:

package cc.testfilterable;import java.util.ArrayList;import java.util.HashMap;import android.os.Bundle;import android.widget.ListView;import android.app.Activity;import android.content.Context;/** * Demo描述: * 利用Filter过滤数据 * 可用于AutoCompleteTextView筛选数据等功能 *  * 备注说明: * 该Demo只表述原理,代码逻辑较简单,有一些小的bug. * 完整的应用请参见以下资料. *  * 参考资料: * 1 http://gundumw100.iteye.com/blog/1446507 * 2 http://blog.csdn.net/ssstudio/article/details/7579089 * 3 http://blog.csdn.net/jiahui524/article/details/7802033 *  */public class MainActivity extends Activity {  private Context mContext;    private ListView mListView;    private ListViewAdapter mListViewAdapter;    private ArrayList<String> mArrayList;    private HashMap<String, String> mHashMap;  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.main);    init();  }  private void init(){    mContext=this;    mListView=(ListView) findViewById(R.id.listView);    mArrayList=new ArrayList<String>();    mArrayList.add("张三1");    mArrayList.add("李四1");    mArrayList.add("王五1");    mArrayList.add("张三2");    mArrayList.add("李四2");    mArrayList.add("王五2");    mArrayList.add("张三3");    mArrayList.add("李四3");    mArrayList.add("王五3");    mArrayList.add("张三4");    mArrayList.add("李四4");    mArrayList.add("王五4");    mListViewAdapter=new ListViewAdapter(mContext, mArrayList);    //过滤数据    //过滤出姓名里面包含"张"的数据    mListViewAdapter.getFilter().filter("张");    mListView.setAdapter(mListViewAdapter);  }}

ListViewAdapter如下:

package cc.testfilterable;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.Filter;import android.widget.TextView;public class ListViewAdapter extends BaseAdapter {  private NameFilter mNameFilter;  private List<String> mArrayList;  private List<String> mFilteredArrayList;  private LayoutInflater mLayoutInflater;  public ListViewAdapter(Context context,List<String> arrayList) {    mArrayList = arrayList;    mLayoutInflater=LayoutInflater.from(context);    mFilteredArrayList=new ArrayList<String>();  }  @Override  public int getCount() {    if (mArrayList == null) {      return 0;    } else {      return (mArrayList.size());    }  }  @Override  public Object getItem(int position) {    if (mArrayList == null) {      return null;    } else {      return mArrayList.get(position);    }  }  @Override  public long getItemId(int position) {    return position;  }  public Filter getFilter() {         if (mNameFilter == null) {               mNameFilter = new NameFilter();           }          return mNameFilter;      }    @Override  public View getView(int position, View convertView, ViewGroup parent) {    View itemView = null;    itemView = convertView;    ViewHolder viewHolder = null;    if (itemView == null) {      itemView = mLayoutInflater.inflate(R.layout.listviewitem, null);      viewHolder = new ViewHolder();      viewHolder.textView = (TextView) itemView.findViewById(R.id.textView);      itemView.setTag(viewHolder);    } else {      viewHolder = (ViewHolder) itemView.getTag();    }    if (mArrayList != null) {      if (viewHolder.textView != null) {        viewHolder.textView.setText((mArrayList.get(position)));      }    }    convertView = itemView;    return convertView;  }  private class ViewHolder {    TextView textView;  }  //过滤数据  class NameFilter extends Filter {    //执行筛选    @Override    protected FilterResults performFiltering(CharSequence charSequence) {      FilterResults filterResults = new FilterResults();      for (Iterator<String> iterator = mArrayList.iterator(); iterator.hasNext();) {        String name = iterator.next();        System.out.println("---> name=" + name);        if (name.contains(charSequence)) {          mFilteredArrayList.add(name);        }      }      filterResults.values = mFilteredArrayList;      return filterResults;    }    //筛选结果    @Override    protected void publishResults(CharSequence arg0, FilterResults results) {      mArrayList = (List<String>) results.values;      if (results.count > 0) {        notifyDataSetChanged();      } else {        notifyDataSetInvalidated();      }    }}}
<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"    >    <ListView        android:id="@+id/listView"        android:layout_width="fill_parent"        android:layout_height="fill_parent"     /></RelativeLayout>
<?xml version="1.0" encoding="utf-8"?><LinearLayout     xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="wrap_content"     >    <TextView        android:id="@+id/textView"       android:layout_width="wrap_content"       android:layout_height="50dip"       android:gravity="center"    />    </LinearLayout>
0 0
原创粉丝点击