如何在 RealmRecyclerViewAdapter 中实现可过滤
Posted
技术标签:
【中文标题】如何在 RealmRecyclerViewAdapter 中实现可过滤【英文标题】:how to implement filterable in RealmRecyclerViewAdapter 【发布时间】:2017-03-30 13:04:10 【问题描述】:我正在使用 RealmRecyclerViewAdapter。我的问题是实现一个不起作用的Filterable
。这是代码:
private class AirportAdapter extends RealmRecyclerViewAdapter<AirportR,RecyclerView.ViewHolder> implements Filterable
Context context;
OrderedRealmCollection<AirportR>listAirports;
public AirportAdapter(Context activity, OrderedRealmCollection<AirportR>airports)
super(activity,airports, true);
this.context = activity;
this.listAirports = airports;
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.airport_show, parent,false);
AirportClass holder = new AirportClass(view);
return holder;
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
AirportR airportR = listAirports.get(position);
AirportClass mHolder = (AirportClass)holder;
mHolder.country.setText(airportR.getIsoCountry());
mHolder.name.setText(airportR.getName());
public Filter getFilter()
AirportFilter filter = new AirportFilter(this, listAirports);
return filter;
private class AirportFilter extends Filter
private final AirportAdapter adapter;
OrderedRealmCollection<AirportR>originalList;
OrderedRealmCollection<AirportR>filteredList;
private AirportFilter(AirportAdapter adapter, OrderedRealmCollection<AirportR> originalList)
super();
this.adapter = adapter;
this.originalList = originalList;
@Override
protected FilterResults performFiltering(CharSequence constraint)
filteredList.clear();
final FilterResults results = new FilterResults();
if (constraint.length() == 0)
filteredList.addAll(originalList);
else
final String filterPattern = constraint.toString().toLowerCase().trim();
for (final AirportR airportR : originalList)
if (airportR.getName().toLowerCase().contains(filterPattern))
filteredList.add(airportR);
results.values = filteredList;
results.count = filteredList.size();
return results;
@Override
protected void publishResults(CharSequence constraint, FilterResults results)
adapter.listAirports.addAll((OrderedRealmCollection<AirportR>) results.values);
adapter.notifyDataSetChanged();
private class AirportClass extends RecyclerView.ViewHolder
TextView name, country;
ImageView image;
public AirportClass(View itemView)
super(itemView);
name = (TextView)itemView.findViewById(R.id.name);
country = (TextView)itemView.findViewById(R.id.country);
image = (ImageView)itemView.findViewById(R.id.imageView);
然后我返回错误:
java.lang.UnsupportedOperationException: This method is not supported by RealmResults.
at io.realm.RealmResults.addAll(RealmResults.java:710)
at com.example.matteo.downloadairports.fragment.ListAirportFragment$AirportAdapter$AirportFilter.publishResults
过滤并更新适配器后如何保存结果?
谢谢
【问题讨论】:
【参考方案1】:将过滤移至publishResults
并使用 UI 线程 Realm 的查询来评估新结果。
private class AirportAdapter
extends RealmRecyclerViewAdapter<AirportR, RecyclerView.ViewHolder>
implements Filterable
Realm realm;
public AirportAdapter(Context context, Realm realm, OrderedRealmCollection<AirportR> airports)
super(context, airports, true);
this.realm = realm;
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.airport_show, parent, false);
AirportClass holder = new AirportClass(view);
return holder;
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
AirportR airportR = getData().get(position);
AirportClass mHolder = (AirportClass) holder;
mHolder.bind(airportR);
public void filterResults(String text)
text = text == null ? null : text.toLowerCase().trim();
RealmQuery<AirportR> query = realm.where(AirportR.class);
if(!(text == null || "".equals(text)))
query.contains("fieldToQueryBy", text, Case.INSENSITIVE) // TODO: change field
updateData(query.findAllAsync());
public Filter getFilter()
AirportFilter filter = new AirportFilter(this);
return filter;
private class AirportFilter
extends Filter
private final AirportAdapter adapter;
private AirportFilter(AirportAdapter adapter)
super();
this.adapter = adapter;
@Override
protected FilterResults performFiltering(CharSequence constraint)
return new FilterResults();
@Override
protected void publishResults(CharSequence constraint, FilterResults results)
adapter.filterResults(constraint.toString());
private class AirportClass
extends RecyclerView.ViewHolder
TextView name, country;
ImageView image;
public AirportClass(View itemView)
super(itemView);
name = (TextView) itemView.findViewById(R.id.name);
country = (TextView) itemView.findViewById(R.id.country);
image = (ImageView) itemView.findViewById(R.id.imageView);
public void bind(AirportR airportR)
country.setText(airportR.getIsoCountry());
name.setText(airportR.getName());
【讨论】:
很高兴听到我可以简化您使用 Realm 的方式:p @EpicPandaForce - 你能给我看看 updateData(listAirports);如何在过滤器前后更新列表视图项? @user2269164 它是来自github.com/realm/realm-android-adapters的RealmRecyclerViewAdapter方法 @EpicPandaForce - 任何为列表视图实现的代码? @pentarex 复制粘贴错误。甚至不应该在那里。【参考方案2】:在您的适配器中添加它可能会对您有所帮助
fun filterResults(text: String?, realm: Realm)
var text = text
text = text?.toLowerCase()?.trim it <= ' '
val query = realm.where(YourObject::class.java)
if (!(text == null || "" == text))
query.contains("username", text, Case.INSENSITIVE).or().contains("username2", text, Case.INSENSITIVE)
updateData(query.findAllAsync()) // or findAll()
【讨论】:
以上是关于如何在 RealmRecyclerViewAdapter 中实现可过滤的主要内容,如果未能解决你的问题,请参考以下文章
如何在异步任务中调用意图?或者如何在 onPostExecute 中开始新的活动?