如何在搜索过滤器后更新android RecyclerView项目?

时间:2019-03-18 16:15:19

标签: java android android-recyclerview searchview android-filterable

我正在尝试使用Android RecyclerView类过滤Filterable

我已按照本教程Android RecyclerView adding Search Filter 完成此任务。

项目运行没有错误,我在日志中显示了结果数组,并且得到了正确的结果。但是UI中没有任何变化。

这是我的适配器代码:

  public class CoffretPicturesAdapter extends RecyclerView.Adapter<CoffretPicturesAdapter.MyViewHolder> implements Filterable {

private Context mContext ;
private ArrayList<Picture> mData ;
private ArrayList<Picture> mDataFiltered;

public CoffretPicturesAdapter(Context mContext, ArrayList<Picture> mData) {
    this.mContext = mContext;
    this.mData = mData;
    this.mDataFiltered = mData;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view ;
    LayoutInflater mInflater = LayoutInflater.from(mContext);
    view = mInflater.inflate(R.layout.cardview_item_coffret,parent,false);
    return new MyViewHolder(view);
}

@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence charSequence) {
            String charString = charSequence.toString();
            if (charString.isEmpty()) {
                mDataFiltered = mData;
            } else {
                ArrayList<Picture> filteredList = new ArrayList<>();
                for (Picture row : mData) {

                    // name match condition. this might differ depending on your requirement
                    // here we are looking for name or phone number match
                    if (row.getTitle().toLowerCase().contains(charString.toLowerCase())) {
                        filteredList.add(row);
                    }
                }

                mDataFiltered = filteredList;
            }

            FilterResults filterResults = new FilterResults();
            filterResults.values = mDataFiltered;
            return filterResults;
        }

        @Override
        protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
            mDataFiltered = (ArrayList<Picture>) filterResults.values;
            notifyDataSetChanged();
        }
    };
}

@Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
    holder.coffret_title.setText(mData.get(position).getTitle());
    Picasso.with(mContext).load(mData.get(position).getUri()).placeholder(R.drawable.placeholder).resize(500,500).centerCrop().into(holder.coffret_thumbnail);
    holder.cardView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(mContext, "" + mData.get(position).getTitle(), Toast.LENGTH_SHORT).show();
            Intent intent = new Intent(mContext, SelectedPicPreviewActivity.class);
            intent.putExtra("image_url", mData.get(position).getUri().toString());
            mContext.startActivity(intent);

        }
    });
}

@Override
public int getItemCount() {
    return mData.size();
}

public static class MyViewHolder extends RecyclerView.ViewHolder {

    TextView coffret_title;
    ImageView coffret_thumbnail;
    LinearLayout cardView ;

    public MyViewHolder(View itemView) {
        super(itemView);

        coffret_title = (TextView) itemView.findViewById(R.id.coffret_title_id) ;
        coffret_thumbnail = (ImageView) itemView.findViewById(R.id.coffret_img_id);
        cardView = (LinearLayout) itemView.findViewById(R.id.cardview_id);

    }
}

}

这是从我的外部存储中获取数据的功能

  private ArrayList<Picture> getData() {
    ArrayList<Picture> results= new ArrayList<>();
    //TARGET FOLDER
    File picsFolder = new File(Environment.getExternalStorageDirectory() + "/coffretPics");

    Picture s;

    if (picsFolder.exists()) {
        //GET ALL FILES IN DOWNLOAD FOLDER
        File[] files = picsFolder.listFiles();

        //LOOP THRU THOSE FILES GETTING NAME AND URI
        for (int i = files.length - 1; i >= 0; i--) {
            File file = files[i];

            s = new Picture();
            s.setTitle(file.getName());
            s.setUri(Uri.fromFile(file));


            results.add(s);
        }
    }

    return results;
}

这是侦听文本输入更改的功能

   @Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main_menu, menu);

    // Associate searchable configuration with the SearchView
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    searchView = (SearchView) menu.findItem(R.id.action_search)
            .getActionView();
    searchView.setSearchableInfo(searchManager
            .getSearchableInfo(getComponentName()));
    searchView.setMaxWidth(Integer.MAX_VALUE);

    // listening to search query text change
    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            // filter recycler view when query submitted
            adapter.getFilter().filter(query);
            return false;
        }

        @Override
        public boolean onQueryTextChange(String query) {
            // filter recycler view when text is changed
            adapter.getFilter().filter(query);
            return false;
        }
    });
    return true;
}

希望大家能帮助我解决这个问题。

1 个答案:

答案 0 :(得分:1)

您的recyclerview无法使用过滤后的数据。
当您完成过滤并调用notifyDataSetChanged();时,它实际上使用onBindViewHolder方法将所有可见视图与新内容绑定在一起。
您可以看到,在onBindViewHolder中,您应该从mData中获取项目。