Android Listview搜索过滤器(首次搜索后列表为空)

时间:2017-12-05 04:09:56

标签: android listview filter android-filterable

我正在使用filterable进行搜索过滤。当我按关键字搜索时,我设法得到搜索结果,但在第一次搜索后列表视图为空。我希望它在用户输入为空时显示所有数据。

这是我编辑过的代码。现在我无法获得任何搜索结果。知道哪个部分还有错吗?

  public class ProductListAdapter extends BaseAdapter implements Filterable {


    private Context context;
    private int layout;
    private ArrayList<Booth> productList= new ArrayList<>();
    private ArrayList<Booth> tempList = new ArrayList<>();
    private ValueFilter mFilter = new ValueFilter();


    public ProductListAdapter(Context context, int layout, ArrayList<Booth> productList) {
        this.context = context;
        this.layout = layout;
        this.productList = productList;
        this.tempList = productList;


    }

    @Override
    public int getCount() {

        return tempList.size();
    }

    public void addItems(ArrayList<Booth> items) {
        productList.addAll(items);
        tempList.addAll(items);
        notifyDataSetChanged();
    }

    @Override
    public Object getItem(int position) {

        return tempList.get(position);
    }

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

    @Override
    public View getView(
            int position, View view, ViewGroup viewGroup) {
        Typeface face_02 = Typeface.createFromAsset(context.getAssets(), "customfont/grb.otf");
        ViewHolder holder = new ViewHolder();

        if (view == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(layout, null);
            holder.Boothname = (TextView) view.findViewById(R.id.Boothname);
            holder.Rating = (TextView) view.findViewById(R.id.Rating);

            view.setTag(holder);
        } else {
            holder = (ViewHolder) view.getTag();
        }
        Booth product = productList.get(position);


        holder.Boothname.setText(product.getBoothName());
        holder.Rating.setText(product.getRating());
        holder.Rating.setTypeface(face_02);
        holder.Boothname.setTypeface(face_02);

        return view;
    }

    @Override
    public Filter getFilter() {
        return mFilter;
    }

    private class ValueFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults();

            if (constraint != null && constraint.length() > 0) {
                ArrayList<Booth> filterList = new ArrayList<Booth>();
                constraint = constraint.toString().toLowerCase();

                for (int i = 0; i < productList.size(); i++) {
                    if ((productList.get(i).getBoothName().toLowerCase())
                            .contains(constraint.toString().toLowerCase())) {

                        Booth boothdata = new Booth(productList.get(i)
                                .getBoothName(), productList.get(i)
                                .getRating());

                        filterList.add(boothdata);
                    }
                }
                results.count = filterList.size();
                results.values = filterList;


            } else {
                results.count = productList.size();
                results.values = productList;
            }
            return results;

        }

        @Override
        protected void publishResults(CharSequence constraint,
                                      FilterResults results) {
            tempList = (ArrayList<Booth>) results.values;
            notifyDataSetChanged();
        }
    }
        class ViewHolder {
            TextView Boothname, Rating;

        }
}

2 个答案:

答案 0 :(得分:1)

是的,你得到了这个错误。为什么?因为在搜索之后,有时候,您的productList会丢失其产品。那么,如何解决呢?您应该filter data仅进行过滤,您将使用filter data而不是productList进行搜索,如下所示:

filterList = new List<Product>()// do clone here when you set new data to your list.
// then in the performFiltering(), use filterList instead.
for (int i = 0; i < filterList.size(); i++) {
                if ((filterList.get(i).getBoothName().toLowerCase())
                        .startsWith(constraint.toString().toLowerCase())) {

                    Booth boothdata = new Booth(filterList.get(i)
                            .getBoothName(), filterList.get(i)
                            .getRating());

                    filterList.add(boothdata);
                }
            }

这是你应该做的。

    @Override
    protected void publishResults(CharSequence constraint,
                                  FilterResults results) {
        productList = (ArrayList<Booth>) results.values; // if you use templist here, there's no change in getView
        notifyDataSetChanged();
    }

答案 1 :(得分:1)

这是因为您在用户搜索任何内容时更新原始列表。您必须使用保存临时数据的tempList并用于显示搜索结果,它还用于最初显示列表。而ProductList包含原始列表和它用于与搜索字符串进行比较。

初始化变量

private List<Booth> productList=new ArrayList<>(); //you have already done this,this contains original list
private List<Booth> tempList=new ArrayList<>(); //add this one is to show search result

添加数据的方法应如下所示:

public void addItems(List<Booth> items) {
        productList.addAll(items);
        tempList.addAll(items);
        notifyDataSetChanged();
}

删除数据的方法应如下所示:

  public void removeItems(){
        productList.clear();
        tempList.clear();
    }

getItem和getCount方法应该是这样的:

  @Override
    public int getCount() {
        return tempList.size();
    }
    @Override
    public Booth getItem(int position) {
        return tempList.get(position);
}

ValueFilter应该是这样的:

        private class ValueFilter extends Filter {

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {

            FilterResults results = new FilterResults();

            if (constraint != null && constraint.length() > 0) {
                //filter list as a local variable
                ArrayList<Booth> filterList = new ArrayList<Booth>();
                constraint = constraint.toString().toLowerCase();

                for (int i = 0; i < productList.size(); i++) {
                      if ((productList.get(i).getBoothName().toLowerCase())
                            .startsWith(constraint.toString().toLowerCase())) {

                        Booth boothdata = new Booth(productList.get(i)
                                .getBoothName(), productList .get(i)
                                .getRating());

                        filterList.add(boothdata);
                    }
                }
                results.count = filterList.size();
                results.values = filterList;
                Log.e("VALUES", results.values.toString());
            } else {

                results.count = productList.size();
                results.values = productList;
            }
return results;
            }

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