类图:

通常可以将SearchView和ListView结合,实现数据的搜索和过滤。

1.监听SearchView,SearchView.setOnQueryTextListener(OnQueryTextListener listener);

2.开启ListView的过滤功能,listView.setTextFilterEnabled(true)。必须开启,否则不会过滤;

3..当SearchView接收到输入事件后,调用ListView.setFilterText(filterText)方法,该方法会通过Adapter得到Filter,然后调用Filter.filter(filterText):

  1. public void setFilterText(String filterText) {
  2. // TODO: Should we check for acceptFilter()?
  3. if (mTextFilterEnabled && !TextUtils.isEmpty(filterText)) {
  4. createTextFilter(false);
  5. // This is going to call our listener onTextChanged, but we might not
  6. // be ready to bring up a window yet
  7. mTextFilter.setText(filterText);
  8. mTextFilter.setSelection(filterText.length());
  9. if (mAdapter instanceof Filterable) {
  10. // if mPopup is non-null, then onTextChanged will do the filtering
  11. if (mPopup == null) {
  12. Filter f = ((Filterable) mAdapter).getFilter();
  13. f.filter(filterText);
  14. }
  15. // Set filtered to true so we will display the filter window when our main
  16. // window is ready
  17. mFiltered = true;
  18. mDataSetObserver.clearSavedState();
  19. }
  20. }
  21. }

4.Filter.filter(filterText)方法最终会调用Filter.performFiltering(filterText)和Filter.publishResults(CharSequence filterText, FilterResults results)。performFiltering(filterText)方法完成过滤处理并且返回结果FilterResults,而publishResults(CharSequence filterText, FilterResults results)则根据返回的结果进行相应的处理。

5.Filter.publishResults(CharSequence filterText, FilterResults results)调用了BaseAdapter.notifyDataSetChanged()方法,该方法用于当Adapter的数据发生变化时,通知UI主线程根据新的数据绘制界面:

  1. @Override
  2. protected void publishResults(CharSequence constraint, FilterResults results) {
  3. //noinspection unchecked
  4. mObjects = (List<T>) results.values;
  5. if (results.count > 0) {
  6. notifyDataSetChanged();
  7. } else {
  8. notifyDataSetInvalidated();
  9. }
  10. }

数据过滤就这样完成了。

下面给出例子。

布局文件filter_activity.xml:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical" >
  6. <SearchView
  7. android:id="@+id/searchView1"
  8. android:layout_width="wrap_content"
  9. android:layout_height="wrap_content" >
  10. </SearchView>
  11. <ListView
  12. android:id="@+id/listView1"
  13. android:layout_width="match_parent"
  14. android:layout_height="wrap_content" >
  15. </ListView>
  16. </LinearLayout>

类文件MainActivity.java:

  1. package com.zzj.ui.filterdemo;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.widget.ArrayAdapter;
  5. import android.widget.ListView;
  6. import android.widget.SearchView;
  7. import android.widget.SearchView.OnQueryTextListener;
  8. import com.zzj.ui.R;
  9. public class MainActivity extends Activity implements OnQueryTextListener {
  10. private ListView listView;
  11. @Override
  12. protected void onCreate(Bundle savedInstanceState) {
  13. super.onCreate(savedInstanceState);
  14. setContentView(R.layout.filter_activity);
  15. SearchView searchView = (SearchView) findViewById(R.id.searchView1);
  16. searchView.setOnQueryTextListener(this);
  17. searchView.setSubmitButtonEnabled(false);
  18. searchView.setIconifiedByDefault(false);
  19. listView = (ListView) findViewById(R.id.listView1);
  20. ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
  21. android.R.layout.simple_list_item_1, new String[] { "Bei jing",
  22. "Shang hai", "Chang sha", "Chang chun", "Nan jing",
  23. "Dong jing", "Ji nan", "Qing dao", "Xiang tan",
  24. "Zhu zhou", "Heng yang" });
  25. listView.setAdapter(adapter);
  26. // 开启过滤功能
  27. listView.setTextFilterEnabled(true);
  28. }
  29. @Override
  30. public boolean onQueryTextSubmit(String query) {
  31. return false;
  32. }
  33. @Override
  34. public boolean onQueryTextChange(String newText) {
  35. if (newText == null || newText.length() == 0) {
  36. listView.clearTextFilter();
  37. } else {
  38. listView.setFilterText(newText);
  39. }
  40. return true;
  41. }
  42. }

效果图:

如图所示,弹出了一个浮动框,这是listView.setFilterText(filterText)弹出来的。如果不想要这个浮动框,可以先获取Filter,然后调用Filter.filter(filterText)。

修改SearchView的监听函数如下:

  1. @Override
  2. public boolean onQueryTextChange(String newText) {
  3. ListAdapter adapter = listView.getAdapter();
  4. if (adapter instanceof Filterable) {
  5. Filter filter = ((Filterable) adapter).getFilter();
  6. if (newText == null || newText.length() == 0) {
  7. filter.filter(null);
  8. } else {
  9. filter.filter(newText);
  10. }
  11. }
  12. return true;
  13. }

使用这种方法不需要开启ListView的过滤功能。效果如下:

上面使用的是ArrayAdapter的过滤功能,我们也可以继承BaseAdapter,然后实现Filterable接口,定义自己的过滤器。

Android 数据过滤器:Filter的更多相关文章

  1. Android数据过滤器:Filter

    类图: 通常可以将SearchView和ListView结合,实现数据的搜索和过滤. 1.监听SearchView,SearchView.setOnQueryTextListener(OnQueryT ...

  2. ABP(现代ASP.NET样板开发框架)系列之13、ABP领域层——数据过滤器(Data filters)

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之13.ABP领域层——数据过滤器(Data filters) ABP是“ASP.NET Boilerplate P ...

  3. ABP理论学习之数据过滤器

    返回总目录 本篇目录 介绍 预定义过滤器 关闭过滤器 开启过滤器 设置过滤器参数 定义自定义过滤器 其他ORM 介绍 软删除模式通常用于不会真正从数据库删除一个实体而是仅仅将它标记为"已删除 ...

  4. Angularjs在控制器(controller.js)的js代码中使用过滤器($filter)格式化日期/时间实例

    Angularjs内置的过滤器(filter)为我们的数据信息格式化提供了比较强大的功能,比如:格式化时间,日期.格式化数字精度.语言本地化.格式化货币等等.但这些过滤器一般都是在VIEW中使用的,比 ...

  5. java Servlet中的过滤器Filter

    web.xml中元素执行的顺序listener->filter->struts拦截器->servlet. 1.过滤器的概念 Java中的Filter 并不是一个标准的Servlet ...

  6. Servlet中的过滤器Filter用法

    1.过滤器的概念 Java中的Filter 并不是一个标准的Servlet ,它不能处理用户请求,也不能对客户端生成响应. 主要用于对HttpServletRequest 进行预处理,也可以对Http ...

  7. Servlet中的过滤器Filter详解

    加载执行顺序 context-param->listener->filter->servlet web.xml中元素执行的顺序listener->filter->stru ...

  8. AngularJS的过滤器$filter

    过滤器(filter)主要用于数据的格式上,通过某个规则,把值处理后返回结果.例如获得数据集,可排序后再返回. ng内置的共有九种过滤器: currency 货币 使用currency可以将数字格式化 ...

  9. ASP.NET没有魔法——ASP.NET MVC 过滤器(Filter)

    上一篇文章介绍了使用Authorize特性实现了ASP.NET MVC中针对Controller或者Action的授权功能,实际上这个特性是MVC功能的一部分,被称为过滤器(Filter),它是一种面 ...

随机推荐

  1. maven之(六)setting.xml的配置文件详解

    setting.xml配置文件 maven的配置文件settings.xml存在于两个地方: 1.安装的地方:${M2_HOME}/conf/settings.xml 2.用户的目录:${user.h ...

  2. readonly属性在各浏览器中的区别

    有个项目需求是正常显示时为只读,不可修改: 点击修改按钮后,可修改表单元素. 首先想到的是readonly属性,其用于规定输入字段为只读,不能修改.在javascript中消除readonly值,可将 ...

  3. jQuery基础教程第四版练习答案

    第二章 1. $('#selected-plays>li>ul>li').nextAll().addBack().addClass('special'); 2. $('table') ...

  4. 相对协议-关于src里//开头的知识

    "相对协议",也就是链接以 // 开头,前面去掉了 http: 或 https: 字样, 这样做的好处是浏览器能够根据你的网站所采用的协议来自动加载 CDN 上托管的文件!

  5. OBIEE接受外部参数

    样例: http://192.168.0.99/analytics/saw.dll?Go&Path=/shared/goxiangyibiaopan/SBDW_GSYDL_ZZT&Ac ...

  6. WPS Office 二次开发简易教程。

    http://bbs.wps.cn/forum.php?mod=viewthread&tid=22004642

  7. Mysq 5.7l服务无法启动,没有报告任何错误

    昨天系统崩溃了,然后重装了Mysql 5.7 安装步骤和遇到问题及解决方案. 去官网下载Mysql 5.7的解压包(zip),解压到你要安装的目录. 我的安装目录是:D:\Java\Mysql 安装步 ...

  8. netty初探(2)

    上一篇 netty(1) 一.TCP/IP 流式传输 在上文演示了2进制流式传输引起的TCP拆包问题,这里继续演示文本型的传输问题,文本型的可以有以下几种策略 1.1 以特殊字符表示结尾 HTTP协议 ...

  9. iOS错误之-Presenting view controllers on detached view controllers is discouraged

    遇到这个警告后找了一下网络资源,基本上只说通过 [self.view.window.rootViewController presentViewController:controller animat ...

  10. clone远程代码及push

    clone远程代码1. git bash进入 git文件夹2. 从远程直接clone: git clone root@109.110.100.56:/usr/src/git-2.1.2/data/gi ...