filtrar - search items in recyclerview android
cómo implementar filtrable en RealmRecyclerViewAdapter (2)
Estoy usando bien RealmRecyclerViewAdapter.
Mi problema es implementar un
Filterable
que no funciona.
Este es el código:
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);
}
}
}
y devuelvo el error:
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
¿Cómo podría guardar el resultado después de filtrarlo y actualizar el adaptador?
Gracias
Mueva el filtro para
publishResults
y use las consultas del Reino del hilo de la interfaz de usuario para evaluar los nuevos resultados.
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());
}
}
}
en su adaptador agregue esto puede ayudarlo
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()
}