使用 EditText 过滤 ListView

Filter ListView with EditText

我正在尝试用 EditText 中的文本过滤 ListView,但我根本没有得到任何过滤器。 我正在关注这个答案:Answer。 我的适配器 class 扩展了 BaseAdapter 并实现了 Filterable,它看起来像这样:

public class ListBaseAdapter extends BaseAdapter implements Filterable {


    Context context;
    ArrayList<Bean> bean;
    ArrayList<Bean> beanFiltered;
    Typeface fonts1, fonts2;


    public ListBaseAdapter(Context context, ArrayList<Bean> bean) {

        this.context = context;
        this.bean = bean;
        this.beanFiltered = bean;
    }


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

    @Override
    public Object getItem(int position) {
        return bean.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        fonts1 = Typeface.createFromAsset(context.getAssets(),
                "fonts/Lato-Light.ttf");

        fonts2 = Typeface.createFromAsset(context.getAssets(),
                "fonts/Lato-Regular.ttf");

        ViewHolder viewHolder = null;

        if (convertView == null) {
            LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
            convertView = layoutInflater.inflate(R.layout.list, null);

            viewHolder = new ViewHolder();

            viewHolder.newsimage1 = convertView.findViewById(R.id.newsimage1);
            viewHolder.newsimage2 = convertView.findViewById(R.id.newsimage2);
            viewHolder.more = convertView.findViewById(R.id.more);
            viewHolder.newsname = convertView.findViewById(R.id.newsname);
            viewHolder.time = convertView.findViewById(R.id.time);
            viewHolder.news = convertView.findViewById(R.id.news);
            viewHolder.newssub = convertView.findViewById(R.id.newssub);
            viewHolder.intrest = convertView.findViewById(R.id.intrest);


            viewHolder.newsname.setTypeface(fonts1);
            viewHolder.time.setTypeface(fonts1);
            viewHolder.news.setTypeface(fonts2);
            viewHolder.newssub.setTypeface(fonts1);
            viewHolder.intrest.setTypeface(fonts1);

            convertView.setTag(viewHolder);


        } else {

            viewHolder = (ViewHolder) convertView.getTag();
        }


        final Bean bean = (Bean) getItem(position);

        viewHolder.newsimage1.setImageResource(bean.getNewsimage1());
        viewHolder.newsimage2.setImageResource(bean.getNewsimage2());
        viewHolder.more.setImageResource(bean.getMore());
        viewHolder.newsname.setText(bean.getNewsname());
        viewHolder.time.setText(bean.getTime());
        viewHolder.news.setText(bean.getNews());
        viewHolder.newssub.setText(bean.getNewssub());
        viewHolder.intrest.setText(bean.getIntrest());
        convertView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(context, ItemDetailActivity.class);
                intent.putExtra("text", bean.getNewssub());
                context.startActivity(intent);
            }
        });


        return convertView;
    }

    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults results = new FilterResults();
                if (constraint == null || constraint.length() == 0) {
                    //no constraint given, just return all the data. (no search)
                    results.count = bean.size();
                    results.values = bean;
                } else {//do the search
                    List<Bean> resultsData = new ArrayList<>();
                    String searchStr = constraint.toString();
                    for (Bean o : bean)
                        if (o.getNews().startsWith(searchStr)) resultsData.add(o);
                    results.count = resultsData.size();
                    results.values = resultsData;
                }
                return results;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                beanFiltered = (ArrayList<Bean>) results.values;
                notifyDataSetChanged();
            }
        };
    }

    private class ViewHolder {

        ImageView newsimage1;
        ImageView newsimage2;
        ImageView more;
        TextView newsname;
        TextView time;
        TextView news;
        TextView newssub;
        TextView intrest;


    }
}

然后在我的 activity, :

  searchParam.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                baseAdapter.getFilter().filter(charSequence);
            }

            @Override
            public void afterTextChanged(Editable editable) {

            }
        });

但我仍然没有得到任何过滤结果。我做错了什么

您的列表基于 bean 而不是 beanFiltered。这就是 notifyDataSetChanged 不起作用的原因。 getCount()getItem(int position) 始终在 bean 上工作。这就是过滤器不起作用的原因。请按以下更改:

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

@Override
public Object getItem(int position) {
    return beanFiltered.get(position);
}