【问题标题】:Android Listview search filter (list empty after first search)Android Listview 搜索过滤器(首次搜索后列表为空)
【发布时间】:2017-12-05 04:09:56
【问题描述】:

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

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

  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;

        }
}

【问题讨论】:

  • 您可以过滤ListView,甚至无需与适配器交互,方法是使用临时列表并使用addTextChangedListener 将原始列表中的项目排序到临时列表中以获取EditText。我在自定义 ListView 适配器上使用这种方式,效果很好。需要这个吗?分享包含 ListView 的 java 类。

标签: android listview filter android-filterable


【解决方案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();
            }
    }

【讨论】:

  • 我在上面编辑了我的代码,我可以知道哪一部分仍然是错误的吗?我现在无法获得任何搜索结果。谢谢。
  • 我已经更新了我的答案。看到它。不要将 filterList 作为全局变量在 performFiltering() 方法中作为局部变量。并在全局范围内获取另一个 tempList 变量来管理搜索列表。
  • 感谢您的快速响应,我现在尝试使用新代码,当我在搜索框中键入任何关键字时,列表视图仅显示列表中的第一个 obj。我在上面编辑了我的代码,介意帮我检查一下吗? :(
  • 试试这条线 if ((productList.get(i).getBoothName().toLowerCase()) .contains(constraint.toString().toLowerCase())) 而不是 if ((productList.get(i).getBoothName().toLowerCase()) .startsWith(constraint.toString().toLowerCase())) 我想它可能对你有帮助。
  • 嗨,我修复了它,只需将 publishResults 中的 tempList 交换为 productList。和 results.count = productList.size();结果.值=产品列表;改为 tempList。
【解决方案2】:

是的,您遇到了这个错误。为什么?因为在搜索之后,您的 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();
    }

【讨论】:

  • 您好,感谢您的回复。但是在我将 productlist 更改为 flterlist 后,listview 中的所有数据都丢失了。知道我做错了什么吗?
  • @TanKahseng 检查答案。
猜你喜欢
  • 2013-02-10
  • 2018-09-24
  • 1970-01-01
  • 2018-05-08
  • 2011-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多