java - item - No se puede escribir un algoritmo para filtrar elementos en un RecyclerView basado en un largo guardado con cada elemento
searchable recyclerview (5)
Tengo varios artículos en un RecyclerView
y cada artículo tiene un valor long
guardado con él. Estoy usando FastAdapter como el adaptador para mi RecyclerView
.
Supongamos que hay 7 elementos en el RecyclerView
con los valores largos: 11122
, 12321
, -98811
, 8870
, -88009
, 3398
y -22113
.
Entonces, lo que quiero hacer es, quiero filtrar los elementos basados en los valores largos dados anteriormente usando esta lógica:
if (l <= 1000) {
// show items with long value <=1000
} else if (l > 1000) {
// show items with long value >1000
}
Intenté varias cosas, pero nada funcionó.
ACTUALIZACIÓN 1 : los elementos aquí son una especie de datos diferentes almacenados en CardView
y luego se muestran en RecyclerView
. Cada tarjeta contiene datos diferentes, uno de los cuales son los valores long
dados anteriormente. Quiero filtrar los datos basados en estos valores long
almacenados en cada tarjeta en función de la lógica dada anteriormente.
Ayúdeme con este problema y sugiera algún algoritmo o código con el que pueda lograrlo.
Incluso tu código básico allí funcionaría. Puede contar el número de elementos en ese rango y devolver el número en ese rango. Sugiero que intente hacer esto sin FastAdapter porque el concepto central de analizar los datos en base a un valor de filtro es perfectamente sólido. Puede iterar el ciclo y contarlos, y puede iterar el ciclo y devolver el enésimo elemento.
Con la cantidad de información dada, solo puedo suponer que l
es un valor de selector externo que controla los elementos que se mostrarán dentro de RecyclerView
. Comente a continuación si este no es el caso, intentaré corregir mi respuesta.
Recomiendo implementar un ViewAdapter
personalizado, enviando la lista de elementos y la variable de selector l
usando los métodos respectivos:
public class ItemsAdapter extends
RecyclerView.Adapter<ItemsAdapter.ItemViewHolder> {
private List<Long> mItemList;
private List<Long> mDisplayItems;
private boolean mAboveThousand = true;
public void setItemList(List<Long> list) {
mItemList = list;
updateDisplayItems();
}
public void setSelectionType(boolean aboveThousand) {
mAboveThousand = aboveThousand;
updateDisplayItems();
}
private updateDisplayItems() {
mDisplayItems.clear();
for(Long item: mItemList) {
if(/*check your contition*/) {
mDisplayItems.add(item);
}
}
notifyDataSetChanged(); //important
}
...
// Rest of implementation
}
Además, nunca he usado FastAdapter, pero supongo que debe haber algunos métodos para anular si amplía su clase.
Actualizar
Debido a que tiene problemas para comprender los conceptos básicos del uso de ViewAdapter
, recomendaría aprender e implementar un ViewAdapter
personalizado antes de usar cualquier biblioteca. Aquí hay un extenso tutorial sobre cómo implementar ViewAdapter
para RecyclerView.
Ahora, después de que haya implementado ViewAdapter, puede usar mi fragmento de código para filtrar las tarjetas. Básicamente, lo que hace el código es guardar una lista de todos los datos requeridos dentro de mItemList
, mientras que mDisplayList
es una lista que almacena los elementos que se mostrarán, que se actualiza cada vez mAboveThousand
, que almacena las preferencias del usuario por encima o por debajo de 1000, Está establecido. Ahora, esta mDisplayList
debe usar para inflar datos dentro de RecyclerView.
Si desea seguir usando FastAdapter, tiene una funcionalidad de filtro incorporada (vea el punto número 5 en el archivo README del proyecto . Tenga en cuenta que el método de filter
debe withFilterPredicate
después withFilterPredicate
y no antes, como se muestra allí).
EDITAR - después de que indicó que no le había entendido bien antes - aquí están mis instrucciones propuestas actualizadas:
Debe resolver las lógicas del conjunto que desea mostrar (usando las casillas de verificación en el cuadro de diálogo que mencionó en el comentario) y pasar esa información al filtro, por ejemplo:
boolean displayUnderThreshold = //put the logic here - true if you want <1000
fastAdapter.filter(Boolean.toString(displayUnderThreshold));
Y donde configura el adaptador (antes de que se llame a la línea anterior), tenga:
final long threshold = 1000;
fastAdapter.withFilterPredicate(new IItemAdapter.Predicate<GRModeClass>() {
@Override
public boolean filter(GRModeClass item, CharSequence constraint) {
boolean displayUnderThreshold = new Boolean(constraint.toString());
return (displayUnderThreshold ^ (item.l<threshold)); //false to remove from list
}
});
Respuesta anterior
Desde cuando pensé que quería filtrar los elementos de acuerdo con sus valores largos dems
, usando un indicador externo l
largo: En su código, suponiendo que su aplicación llega al if
mencionó en la pregunta cuando debería: eliminar el fastItemAdapter.clear();
y en lugar del bucle for
con el if
dentro escribe
fastItemAdapter.filter(Long.toString(l));
y en algún lugar antes de eso, preferiblemente donde establezca el adaptador (lo más probable en el onCreate
of MainActivity
) agregue lo siguiente:
final long threshold = 1000;
fastAdapter.withFilterPredicate(new IItemAdapter.Predicate<GRModeClass>() {
@Override
public boolean filter(GRModeClass item, CharSequence constraint) {
long indicator = new Long(constraint.toString());
return (item.ms<threshold && indicator>=threshold) || (item.ms>=threshold && indicator<threshold) ;
}
});
(Suponiendo aquí que GRModeClass
es la clase de su elemento y que el long ms
es el largo al que se refiere que debería determinar si)
Supongo que tu clase es como
public Class ListItem {
// .. Some other attributes
public long l;
}
Ahora espero que tenga alguna función a la que se llame cuando coloque un filtro en su RecyclerView
. Deje que el nombre de la función sea toggleFilter
.
public void toggleFilter(long l) {
if(l <= 1000) {
fastAdapter.withFilterPredicate(new IItemAdapter.Predicate<Item>() {
@Override
public boolean filter(ListItem item, CharSequence constraint) {
if(item.l <= 1000) return true;
else return false;
}
});
} else if (l > 1000) {
fastAdapter.withFilterPredicate(new IItemAdapter.Predicate<Item>() {
@Override
public boolean filter(ListItem item, CharSequence constraint) {
if(item.l > 1000) return true;
else return false;
}
});
}
// Finally call notifyDataSetChanged
fastAdapter.notifyDataSetChanged();
}
Puede filtrar mientras obtiene de firebase.
l <= 1000
firebaseDatabase.child(key).orderByChild("long_value_key_in_firebase").endAt(1000);
l> 1000
firebaseDatabase.child(key).orderByChild("long_value_key_in_firebase").startAt(1000);