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):

<span style="font-size:14px;">    public void setFilterText(String filterText) {  
            // TODO: Should we check for acceptFilter()?  
            if (mTextFilterEnabled && !TextUtils.isEmpty(filterText)) {  
                createTextFilter(false);  
                // This is going to call our listener onTextChanged, but we might not  
                // be ready to bring up a window yet  
                mTextFilter.setText(filterText);  
                mTextFilter.setSelection(filterText.length());  
                if (mAdapter instanceof Filterable) {  
                    // if mPopup is non-null, then onTextChanged will do the filtering  
                    if (mPopup == null) {  
                        Filter f = ((Filterable) mAdapter).getFilter();  
                        f.filter(filterText);  
                    }  
                    // Set filtered to true so we will display the filter window when our main  
                    // window is ready  
                    mFiltered = true;  
                    mDataSetObserver.clearSavedState();  
                }  
            }  
        }  </span>


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主线程根据新的数据绘制界面:

<span style="font-size:14px;">    @Override  
           protected void publishResults(CharSequence constraint, FilterResults results) {  
               //noinspection unchecked  
               mObjects = (List<T>) results.values;  
               if (results.count > 0) {  
                   notifyDataSetChanged();  
               } else {  
                   notifyDataSetInvalidated();  
               }  
           }  </span>


数据过滤就这样完成了。


下面给出例子。

布局文件filter_activity.xml:

<span style="font-size:14px;">    <?xml version="1.0" encoding="utf-8"?>  
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
        android:layout_width="match_parent"  
        android:layout_height="match_parent"  
        android:orientation="vertical" >  
      
        <SearchView  
            android:id="@+id/searchView1"  
            android:layout_width="wrap_content"  
            android:layout_height="wrap_content" >  
        </SearchView>  
      
        <ListView  
            android:id="@+id/listView1"  
            android:layout_width="match_parent"  
            android:layout_height="wrap_content" >  
        </ListView>  
      
    </LinearLayout>  </span>


类文件MainActivity.java:

<span style="font-size:14px;">    package com.zzj.ui.filterdemo;  
      
    import android.app.Activity;  
    import android.os.Bundle;  
    import android.widget.ArrayAdapter;  
    import android.widget.ListView;  
    import android.widget.SearchView;  
    import android.widget.SearchView.OnQueryTextListener;  
      
    import com.zzj.ui.R;  
      
    public class MainActivity extends Activity implements OnQueryTextListener {  
        private ListView listView;  
      
        @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
      
            setContentView(R.layout.filter_activity);  
      
            SearchView searchView = (SearchView) findViewById(R.id.searchView1);  
            searchView.setOnQueryTextListener(this);  
            searchView.setSubmitButtonEnabled(false);  
            searchView.setIconifiedByDefault(false);  
      
            listView = (ListView) findViewById(R.id.listView1);  
      
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,  
                    android.R.layout.simple_list_item_1, new String[] { "Bei jing",  
                            "Shang hai", "Chang sha", "Chang chun", "Nan jing",  
                            "Dong jing", "Ji nan", "Qing dao", "Xiang tan",  
                            "Zhu zhou", "Heng yang" });  
            listView.setAdapter(adapter);  
            // 开启过滤功能  
            listView.setTextFilterEnabled(true);  
        }  
      
        @Override  
        public boolean onQueryTextSubmit(String query) {  
            return false;  
        }  
      
        @Override  
        public boolean onQueryTextChange(String newText) {  
            if (newText == null || newText.length() == 0) {  
                listView.clearTextFilter();  
            } else {  
                listView.setFilterText(newText);  
            }  
            return true;  
        }  
    }  </span>


效果图:

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

修改SearchView的监听函数如下:

    @Override  
        public boolean onQueryTextChange(String newText) {  
            ListAdapter adapter = listView.getAdapter();  
            if (adapter instanceof Filterable) {  
                Filter filter = ((Filterable) adapter).getFilter();  
                if (newText == null || newText.length() == 0) {  
                    filter.filter(null);  
                } else {  
                    filter.filter(newText);  
                }  
            }  
            return true;  
        }  


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


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



from:http://blog.csdn.net/zhangzeyuaaa/article/details/40187789

关注公众号,分享干货,讨论技术


posted on   EvanLong  阅读(252)  评论(0编辑  收藏  举报

编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示