搜索过滤器不起作用

Search Filter is not working

即使我在 EditText 中输入确切的 "key" 名称也没有任何反应,而它必须只在列表中显示该记录。

过滤不起作用,这是我的 JSON 的样子:

{
  "data": [
    {
      "id": "1",
      "name": "Era Locksmith",
      "key": "EraLoc2015"
    },
    {
      "id": "2",
      "name": "Mac Garage Door",
      "key": "MacGdr2015"
    }
  ]
}

我正在扩展 ArrayAdapter<....> 并实现 Filterable

CompanyListAdapter.java:

    public class CompanyListAdapter extends ArrayAdapter<Company> implements Filterable {

    private Context context;
    ArrayList<Company> products;
    SharedPreference sharedPreference;

    private ArrayList<Company> filteredCompanies;
    private CompanyFilter mFilter = new CompanyFilter();

    public CompanyListAdapter(Context context, ArrayList<Company> products) {
        super(context, R.layout.company_list_item, products);
        this.context = context;
        this.products = products;
        sharedPreference = new SharedPreference();
    }

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

    private class ViewHolder {
        TextView productNameTxt;
        TextView productKeyTxt;
        ImageView favoriteImg;
    }

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

    @Override
    public Company getItem(int position) {
        return products.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.company_list_item, null);
            holder = new ViewHolder();
            holder.productNameTxt = (TextView) convertView
                    .findViewById(R.id.txt_pdt_name);
            holder.productKeyTxt = (TextView) convertView
                    .findViewById(R.id.txt_pdt_price);
            holder.favoriteImg = (ImageView) convertView
                    .findViewById(R.id.imgbtn_favorite);

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        Company product = (Company) getItem(position);
        holder.productNameTxt.setText(product.getName());
        holder.productKeyTxt.setText(product.getPrice() + "");

        /*If a product exists in shared preferences then set heart_red drawable
         * and set a tag*/
        if (checkFavoriteItem(product)) {
            holder.favoriteImg.setImageResource(R.drawable.heart_red);
            holder.favoriteImg.setTag("red");
        } else {
            holder.favoriteImg.setImageResource(R.drawable.heart_grey);
            holder.favoriteImg.setTag("grey");
        }

        return convertView;
    }   

    /*Checks whether a particular product exists in SharedPreferences*/
    public boolean checkFavoriteItem(Company checkProduct) {
        boolean check = false;
        List<Company> favorites = sharedPreference.getFavorites(context);
        if (favorites != null) {
            for (Company product : favorites) {
                if (product.equals(checkProduct)) {
                    check = true;
                    break;
                }
            }
        }
        return check;
    }

    @Override
    public void add(Company product) {
        super.add(product);
        products.add(product);
        notifyDataSetChanged();
    }

    @Override
    public void remove(Company product) {
        super.remove(product);
        products.remove(product);
        notifyDataSetChanged();
    }

    private class CompanyFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {

            String filterString = constraint.toString().toLowerCase();
            FilterResults results = new FilterResults();

            final List<Company> list = products;

            int count = list.size();
            final ArrayList<Company> nlist = new ArrayList<Company>(count);

            Company filterableCompany;

            for (int i = 0; i < count; i++) {
                filterableCompany = list.get(i);
                if (filterableCompany.getKey().toLowerCase().contains(filterString)) {
                    nlist.add(filterableCompany);
                }
            }

            results.values = nlist;
            results.count = nlist.size();

            return results;
        }

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            filteredCompanies = (ArrayList<Company>) results.values;
            notifyDataSetChanged();
        }
    }

}

使用EditText接受"key"

CompanyListActivity.java:

EditText filterList = (EditText) view.findViewById(R.id.editKey);
        filterList.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                // TODO Auto-generated method stub
                productListAdapter.getFilter().filter(s.toString());
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
                    int after) {
                // TODO Auto-generated method stub

            }

            @Override
            public void afterTextChanged(Editable s) {
                // TODO Auto-generated method stub

            }
        });

我正在使用@Leigh

提供的代码

为什么不用implement Filterable? 尝试这样的事情:

使您的适配器 class 看起来像这样:

public class CompanyListAdapter extends ArrayAdapter<Company> implements Filterable {

    private List<Company> companies;
    private List<Company> filteredCompanies;
    private CompanyFilter mFilter = new CompanyFilter();

    private Context context;
    SharedPreference sharedPreference;

    public CompanyListAdapter(Context context, ArrayList<Company> products) {
        super(context, R.layout.company_list_item, products);
        this.context = context;
        this.products = products;
        this.filteredCompanies = products;
        sharedPreference = new SharedPreference();
    }

    @Override
    public int getCount() {
        return filteredCompanies == null 0 : filteredCompanies.size();
    }

    @Override
    public Company getItem(int position) {
        return filteredCompanies.get(position);
    }

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

接下来继续创建一个 CompanyFilter:

private class CompanyFilter extends Filter {
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {

        String filterString = constraint.toString().toLowerCase();
        FilterResults results = new FilterResults();

        final List<Company> list = companies;

        int count = list.size();
        final ArrayList<Company> nlist = new ArrayList<Company>(count);

        Company filterableCompany;

        for (int i = 0; i < count; i++) {
            filterableCompany = list.get(i);
            if (filterableCompany.getName().toLowerCase().contains(filterString)) {
                nlist.add(filterableCompany);
            }
        }

        results.values = nlist;
        results.count = nlist.size();

        return results;
    }

    @SuppressWarnings("unchecked")
    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        filteredCompanies = (ArrayList<Company>) results.values;
        notifyDataSetChanged();
    }
}

这样您就可以将过滤器应用于任意数量的字段。请注意,在我的示例中,我使用公司 class 的 getName() 来应用过滤器。

编辑: 要在 Activity / Fragment 中使用它进行搜索,您可以将 TextWatcher 添加到 EditText 并应用过滤器 onTextChanged。像这样:

txtSearch.addTextChangedListener(new TextWatcher() {

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        adapter.getFilter().filter(s.toString());
    }
});

您需要像这样实现您的适配器 Filterable

class CustomAdapter extends BaseAdapter implements Filterable {
    @Override
        public Filter getFilter() { ...}

试着看看这个答案:
List View Filter Android