首页 > 解决方案 > How to update android RecyclerView items after search filter?

问题描述

I am trying to filter a RecyclerView using Android Filterable class.

I've followed this tutorial Android RecyclerView adding Search Filter to get this task done.

The project runs without errors, I displayed the result array in log and I'm getting correct results but nothing changes in UI.

Here is my adapter code :

  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);

    }
}

}

Here is the function to get data from my external storage

  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;
}

And this is the function to listen to text input changes

   @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;
}

I hope you guys can help me to solve this problem.

标签: javaandroidandroid-recyclerviewsearchviewandroid-filterable

解决方案


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


推荐阅读