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

问题:当后台没有提供模糊查询接口,我们又要进行本地数据模糊查询时,不管是用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("");



(各位看官,有问题记得点评哦,希望能帮到大家)
  • 8
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值