搜索过滤器后如何更新android RecyclerView项目?
Posted
技术标签:
【中文标题】搜索过滤器后如何更新android RecyclerView项目?【英文标题】:How to update android RecyclerView items after search filter? 【发布时间】:2019-08-09 01:51:03 【问题描述】:我正在尝试使用 android Filterable
类过滤 RecyclerView
。
我已按照本教程 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;
希望你们能帮我解决这个问题。
【问题讨论】:
使用Filterable
基本适配器,如this - 示例工作适配器是here - 与Filterable
类一样,过滤是通过调用adapter.getFilter().filter(...)
完成的
感谢先生的快速回复。但是您认为我的代码有什么问题?
我会试试你的解决方案。
谢谢你的时间,@ronginat 找到我在哪里犯了一个无意识的错误。
【参考方案1】:
您的 recyclerview 无法处理过滤后的数据。
当您完成过滤并调用notifyDataSetChanged();
时,它实际上使用onBindViewHolder
方法将所有可见视图与新内容绑定。
您可以看到,在 onBindViewHolder
中,您从 mData
获取项目,而您应该从 mDataFiltered
获取项目。
【讨论】:
就是这样。它现在很有魅力。谢谢先生。以上是关于搜索过滤器后如何更新android RecyclerView项目?的主要内容,如果未能解决你的问题,请参考以下文章
搜索后,p:dataTable 不会更新,除非调用了两次搜索或输入并清除了过滤器中的某些内容
如何在android中的简单列表视图上使用startsWith应用搜索过滤器
Android Honeycomb 中的 Bitmap#recycle() 实际上做了啥?