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

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();
            }
        }
    }

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

 @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            //noinspection unchecked
            mObjects = (List<T>) results.values;
            if (results.count > 0) {
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }

数据过滤就这样完成了。


下面给出例子。

布局文件filter_activity.xml:

<?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>
类文件MainActivity.java:
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;
	}
}
效果图:

如图所示,弹出了一个浮动框,这是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接口,定义自己的过滤器。





  • 8
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值