CursorAdapter与CursorFilter机制

Android为ListView提供了Filter对象,对显示的条目进行过滤。最常见的用法就是Contact中,根据在输入框中输入姓名的字母显示过滤。当然android系统中默认提供的过滤功能非常有限,不支持号码或是其他信息过滤。我曾见过有人为了支持对号码的过滤,就将 Android提供的那套机制屏蔽掉,每当过滤事件发生时,手动起AsyncQueryHander去异步查询。当查询完毕时调用 CursorAdapter.changeCursor更新Cursor。虽然基本上做法没错,流程上也跟Android实现过滤的机制大体相同,但重复了制造轮子的过程,而原有的轮子,只需稍加修改足以满足新的需求。

  我们只需要重写public Cursor runQueryOnBackgroundThread(CharSequence constraint),或者实现接口FilterQueryProvider的对象,再将该对象setFilterQueryProvider给 CursorAdapter即可。

  下面分析下CursorAdapter与Filter的实现框架。

  先说下Filter:

  Filter与AsyncQueryHander实现基本类似,它包含两个Hander:RequestHandler和 ResultHandler,以及一个HandlerThread:名为Filter的线程。RequestHandler与Filter线程绑定,过滤请求都是通过 RequestHandler发送给Filter线程。当过滤产生后,通过mResultHandler将数据push给UI显示。

  CursorFilter继承Filter,它提供了CursorFilterClient接口,CursorAdapter实现 CursorFilterClient接口。CursorFilter会在过滤的某些点回调CursorFilterClient接口的对应函数,我们就是通过这些被回调的函数,改变Filter的行为,以实现自己的目的。这与我们熟知的Activity生命周期上的:onCreate->onResume->onPause……的做法类似。

  来看下这个重要的接口CursorFilterClient的定义

  interface CursorFilterClient {

  CharSequence convertToString(Cursor cursor);

  Cursor runQueryOnBackgroundThread(CharSequence constraint);

  Cursor getCursor();

  void changeCursor(Cursor cursor);

  runQueryOnBackgroundThread是运行在Filter线程中,返回的Cursor将传给ResultHandler,最后传给UI显示。所以上面的例子中,我们要添加对号码的查询,只需在这里自己组织下查询条件,包含对号码的查询,找数据库查询下,将查询结果返回即可。

  changeCursor在ResultHandler向UI送结果时被调用,通过它更新显示过滤后的数据。我们可以重载它,在过滤数据显示前,做点需要的事情(比如更新下SectionIndexer)。

  getCursor只是返回下Adapter中保存的Cursor,convertToString在CursorAdapter没有被用到,不管它了。

posted on 2012-02-21 01:39  ①块腹肌  阅读(1469)  评论(0编辑  收藏  举报

导航