一、何谓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均为抽象方法,需要继承者自己重写。 CursorFilter类就是Filter类的继承。CursorFilter在performFiltering中并没有直接进行数据的过滤,而是加入了CursorFilterClient成员,将过滤的操作转让给了CursorFilterClient,实际上CursorAdpater就是继承了CursorFilterClient接口,也就是说过滤操作实际上是在CursorAdapter中执行的。 四、Filterable接口 常用的Adapter基本上都继承了Filterable接口,如CursorAdapter,ArrayAdapter,SimpleAdapter等。该接口只有一个函数,名为getFilter,通过该函数可以通过Adaper获取Filter,然后通过该Filter进行过滤。 在CursorAdapter中,可以更改过滤的流程,有两种方式: 1、通过重写CursorAdapter的runQueryOnBackgroundThread函数,在函数中根据过滤约束字符串,重新查找生成新的Cursor。Adapter会适时将旧的Cursor进行替换。 2、通过调用setFilterQueryProvider函数,提供一个FilterQueryProvider,该对象含有runQuery方法,作用同runQueryOnBackgroundThread方法相同。 使用那种方法取决于您是不是重载CursorAdapter,以及您的过滤动作需要在Adpter中实现还是在主程序中实现。 五、数据过滤功能的View的界面支持。 为了实现数据过滤的功能,在数据显示层,也有相应的支持。比如ListView和GridView,设置了setFilterText函数,通过该函数可以一方面进行数据的过滤,另一方面显示一个PopupWindow,提示用户输入了那种过滤条件。AutoCompleteTextView当用户在文本框输入文字时,自动进行过滤,并弹出列表显示过滤数据。

六、实战

知道了Android的过滤机制,我们就以AutoCompleteTextView为例,通过输入文本筛选数据库中的数据。

1、首先写ContentProvider
由于代码量比较多,只写出对外的接口。

        
  1. publicstaticfinalclassLocationimplementsBaseColumns{
  2. publicstaticfinalUriCONTENT_URI=Uri.withAppendedPath(AUTHORITY_URI,"location");
  3. publicstaticfinalStringCONTENT_TYPE="vnd.android.cursor.dir/weather_location";
  4. publicstaticfinalStringCONTENT_ITEM_TYPE="vnd.android.cursor.item/weather_location";
  5. publicstaticfinalStringCONTENT_DIRECTORY="location";
  6. publicstaticfinalStringLOCATION_NAME="location_name";
  7. publicstaticfinalStringLONGITUDE="longitude";
  8. publicstaticfinalStringALTITUDE="altitude";
  9. }

2、写CursorAdapter

        
  1. privatestaticclassLocationAdapterextendsCursorAdapter{
  2. privateLayoutInflatermInflater;
  3. privateContextmContext;
  4. privateCursormCursor;
  5. publicLocationAdapter(Contextcontext,Cursorc){
  6. super(context,c);
  7. mContext=context;
  8. mInflater=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  9. }
  10. @Override
  11. publicvoidbindView(Viewview,Contextcontext,Cursorcursor){
  12. TextViewtextView=(TextView)view;
  13. Stringlocation=cursor.getString(cursor.getColumnIndex(Location.LOCATION_NAME));
  14. textView.setText(location);
  15. }
  16. @Override
  17. publicViewnewView(Contextcontext,Cursorcursor,ViewGroupparent){
  18. returnmInflater.inflate(android.R.layout.simple_dropdown_item_1line,null);
  19. }
  20. @Override
  21. publicCursorrunQueryOnBackgroundThread(CharSequenceconstraint){
  22. Stringselection=Location.LOCATION_NAME+"LIKE'%"+constraint+"%'";
  23. returnmContext.getContentResolver().query(Location.CONTENT_URI
  24. ,null,selection,null,null);
  25. }
  26. /**一定要重写该方法,否则AutoCompleteTextView选中某一项后,文本框显示的不是所要的文本*/
  27. @Override
  28. publicCharSequenceconvertToString(Cursorcursor){
  29. returncursor.getString(cursor.getColumnIndex(Location.LOCATION_NAME));
  30. }
  31. }
3、AutoCompleteTextView与Adapter关联。
        
  1. privatevoidinitialTextView(){
  2. mTextView=newAutoCompleteTextView(mContext);
  3. mTextView.setThreshold(0);
  4. Cursorcursor=mContext.getContentResolver().query(Location.CONTENT_URI
  5. ,null,null,null,null);
  6. LocationAdapteradapter=newLocationAdapter(mContext,cursor);
  7. mTextView.setAdapter(adapter);
  8. }
需要提醒的是:AutoCompleteTextView内部的数据筛选并没用采用异步筛选的方式,而是直接调用了Filter内部的performFiltering,所以尽量不要在筛选的函数内做太费时间的事情,否则就乎出现不流畅的情况。

Enjoy it!

本文出自 “winux” 博客,谢绝转载!

更多相关文章

  1. Android(安卓)Debug Bridge(adb, Android调试桥) 与 Log
  2. 用Fiddler抓取Android、Iphone网络数据包
  3. Android硬编码——音频编码、视频编码及音视频混合
  4. Android之TextView属性列表
  5. Android中的adapter
  6. [Android]发布Sqlite数据库
  7. android进程间共享简单数据
  8. 自己封装的Android(安卓)sqlite-helper.jar包使用方法
  9. mybatisplus的坑 insert标签insert into select无参数问题的解决

随机推荐

  1. ANDROID轻量级JSON序列化和反序列化[转]
  2. android技术牛人的博客
  3. android 按钮Button单击背景切换
  4. android 特效资源
  5. android @+id 含义
  6. Android ViewPager动画第三方库(MagicView
  7. Android分区详解:boot, system, recovery,
  8. android pdf 类库
  9. Android 获取当前设备的IP地址
  10. android studio实现打电话