您的位置:首页 > 其它

[置顶] 当SearchView搜索的listView使用自定义适配器时,自定义setFilterText()方法(模糊查询筛选)

2017-07-24 16:13 911 查看
问题:当后台没有提供模糊查询接口,我们又要进行本地数据模糊查询时,不管是用SearchView,还是用EidtText自定义的搜索框,都要用到setFilterText()方法来过滤。那么问题来了,setFilterText()方法只能在你使用ArrayAdapter的时候才有效果,如果ArrayAdapter不满足效果,那么只有自定义BaseAdapter,并且自定义数据过滤器Filter

上一张效果图:



适配器代码如下(记住要实现Filterable接口):

package com.jiumichuangzhi.tablegameuser.adapter;
import android.content.Context;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;

import com.jiumichuangzhi.tablegameuser.R;
import com.jiumichuangzhi.tablegameuser.obj.ProvinceAndCitys;
import com.jiumichuangzhi.tablegameuser.obj.ProvinceAndCitys.ResultMapBean.EntityBean.CitysBean;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/**
* Created by ASUS on 2017/7/20.
* @author songshufan
*/

public class CityListAdapter extends BaseAdapter implements Filterable{
private int resoureId;
private Context context;
private List<CitysBean> citysBeanList; //这个数据是会改变的,所以要有个变量来备份一下原始数据
private List<CitysBean> backcitysBeanList; //用来备份原始数据

MyFilter mFilter ;

public CityListAdapter(Context context , List<CitysBean> citysBeanList) {
this.context = context;
this.citysBeanList = citysBeanList;
backcitysBeanList = citysBeanList;
}

public CityListAdapter() {

}

@Override
public int getCount() {
return citysBeanList.size();
}

@Override
public Object getItem(int position) {
return null;
}

@Override
public long getItemId(int position) {
return 0;
}

//用来优化的viewholder内部类,优化控件findviewbyid
class ViewHolder {
TextView cityName;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;

if (convertView==null){
convertView = LayoutInflater.from(context).inflate(R.layout.citys_list_item,null);
holder = new ViewHolder();
holder.cityName = (TextView) convertView.findViewById(R.id.city_name);
convertView.setTag(holder);

}else {
holder = (ViewHolder) convertView.getTag();
}

holder.cityName.setText(citysBeanList.get(position).getCityName());

return convertView;
}

@Override
public Filter getFilter() {
if (mFilter ==null){
mFilter = new MyFilter();
}
return mFilter;
}
//我们需要定义一个过滤器的类来定义过滤规则
class MyFilter extends Filter{
//我们在performFiltering(CharSequence charSequence)这个方法中定义过滤规则
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
FilterResults result = new FilterResults();
List<CitysBean> list ;
if (TextUtils.isEmpty(charSequence)){//当过滤的关键字为空的时候,我们则显示所有的数据
list  = backcitysBeanList;
}else {//否则把符合条件的数据对象添加到集合中
list = new ArrayList<>();
for (CitysBean citysBean:backcitysBeanList){
if (citysBean.getCityName().contains(charSequence)){ //要匹配的item中的view
list.add(citysBean);
}

}
}
result.values = list; //将得到的集合保存到FilterResults的value变量中
result.count = list.size();//将集合的大小保存到FilterResults的count变量中

return result;
}
//在publishResults方法中告诉适配器更新界面
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
citysBeanList = (List<CitysBean>)filterResults.values;
if (filterResults.count>0){
notifyDataSetChanged();//通知数据发生了改变
}else {
notifyDataSetInvalidated();//通知数据失效
}
}
}
}
自定义Filter的优点是可以匹配Item中的你想筛选的任何view
重点这句代码,是定义对集合中对象的那些属性进行筛选

citysBean.getCityName().contains(charSequence)


你可能会遇到的小问题,可能有人跟我一样觉得模糊查询的提示不方便,不好看



去掉这个提示,代码如下:

//用户输入字符时激发该方法
@Override
public boolean onQueryTextChange(String newText) {
// TODO Auto-generated method stub
Log.e("onQueryTextChange","onQueryTextChange");
if(TextUtils.isEmpty(newText))
{
//清除ListView的过滤
mlistView.clearTextFilter();
cityListAdapter.getFilter().filter("");
}
else
{
Log.e("onQueryTextChange",newText);
//使用用户输入的内容对ListView的列表项进行过滤
//mlistView.setFilterText(newText);
cityListAdapter.getFilter().filter(newText);
}
return true;
}
把对listView的筛选换成
//mlistView.setFilterText(newText);
对适配器的筛选

cityListAdapter.getFilter().filter(newText);
记得要设置清除对适配器的还原,不然数据不会恢复显示哦

cityListAdapter.getFilter().filter("");


(各位看官,有问题记得点评哦,希望能帮到大家)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐