zoukankan      html  css  js  c++  java
  • Android 数据过滤器:Filter

    类图:

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

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

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

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

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    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主线程根据新的数据绘制界面:

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    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:

    [html] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    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.   
    7.     <SearchView  
    8.         android:id="@+id/searchView1"  
    9.         android:layout_width="wrap_content"  
    10.         android:layout_height="wrap_content" >  
    11.     </SearchView>  
    12.   
    13.     <ListView  
    14.         android:id="@+id/listView1"  
    15.         android:layout_width="match_parent"  
    16.         android:layout_height="wrap_content" >  
    17.     </ListView>  
    18.   
    19. </LinearLayout>  

    类文件MainActivity.java:

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

    效果图:

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

    修改SearchView的监听函数如下:

    [java] view plain copy
     
     print?在CODE上查看代码片派生到我的代码片
    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接口,定义自己的过滤器。

  • 相关阅读:
    栈和队列_leetcode23
    Android 广播
    Android Service
    Logcat monkey命令
    设计模式-观察者模式
    Android之Fragment优点
    Android架构: MVC 新浪微博
    Android消息处理机制(Handler、Looper、MessageQueue与Message)
    Android Annotations Eclipse 配置 (3)
    Android Annotations(2)
  • 原文地址:https://www.cnblogs.com/Herzog3/p/5473267.html
Copyright © 2011-2022 走看看