android - studio - RecyclerView conjunto de datos de cambio
recyclerview android (4)
Quiero implementar la funcionalidad de búsqueda para mi RecyclerView. En el texto modificado, quiero cambiar los datos que se muestran con este widget. Tal vez esta pregunta se haya formulado antes o sea simple, pero no sé cómo cambiar los datos que se mostrarán ...
My RecyclerView se define de la siguiente manera:
// 1. get a reference to recyclerView
mRecyclerView = (RecyclerView)findViewById(R.id.recyclerView);
// 2. set layoutManger
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
// 3. create an adapter
mAdapter = new ItemsAdapter(itemsData);
// 4. set adapter
mRecyclerView.setAdapter(mAdapter);
Y la información que estoy mostrando es algo así como:
ItemData itemsData[] = { new ItemData("Mary Richards"),
new ItemData("Tom Brown"),
new ItemData("Lucy London")
};
Entonces cuando quiero darle al adaptador otro conjunto de datos, otro conjunto (con un elemento, por ejemplo), ¿qué debo hacer?
Como ygit respondió, swapAdapter
es interesante cuando tienes que cambiar todo el contenido.
Pero, en mi FlexibleAdapter, puede actualizar los elementos con updateDataSet
. Incluso puede configurar el adaptador para llamar a notifyDataSetChanged
o tener animaciones de sincronización (habilitado por defecto). Eso, porque notifyDataSetChanged mata todas las animaciones, pero es bueno tenerlas para listas grandes.
Por favor, eche un vistazo a las páginas de descripción, demoApp y Wiki: https://github.com/davideas/FlexibleAdapter
Esta es mi respuesta, gracias a Ivan Skoric desde su sitio: http://blog.lovelyhq.com/creating-lists-with-recyclerview-in-android/
Creé un método adicional dentro de mi clase de adaptador:
public void updateList(List<Data> data) {
mData = data;
notifyDataSetChanged();
}
Luego, cada vez que cambian sus datos, simplemente llama a este método para pasar sus nuevos datos y su vista debería cambiar para reflejarlo.
Si tiene identificadores estables en su adaptador, puede obtener resultados bastante buenos (animaciones) si crea una nueva matriz que contiene los elementos filtrados y llama
recyclerView.swapAdapter(newAdapter, false);
El uso de swapAdapter insinúa que RecyclerView puede volver a usar los titulares de vista. (vs en setAdapter, tiene que reciclar todas las vistas y volver a crear porque no sabe que el nuevo adaptador tiene el mismo ViewHolder configurado con el adaptador anterior).
Un mejor enfoque sería encontrar qué elementos se eliminan y llamar a notifyItemRemoved(index)
. No te olvides de quitar el artículo. Esto permitirá que RecyclerView ejecute animaciones predictivas. Suponiendo que tiene un Adaptador que usa internamente una ArrayList, la implementación se vería así:
// adapter code
final List<ItemData> mItems = new ArrayList(); //contains your items
public void filterOut(String filter) {
final int size = mItems.size();
for(int i = size - 1; i>= 0; i--) {
if (mItems.get(i).test(filter) == false) {
mItems.remove(i);
notifyItemRemoved(i);
}
}
}
Funcionaría incluso mejor si puede notifyItemRemoved
lotes llamadas notifyItemRemoved
y usar notifyItemRangeRemoved
en notifyItemRangeRemoved
lugar. Se vería así: (no probado)
public void filterOut(String filter) {
final int size = mItems.size();
int batchCount = 0; // continuous # of items that are being removed
for(int i = size - 1; i>= 0; i--) {
if (mItems.get(i).test(filter) == false) {
mItems.remove(i);
batchCount ++;
} else if (batchCount != 0) { // dispatch batch
notifyItemRangeRemoved(i + 1, batchCount);
batchCount = 0;
}
}
// notify for remaining
if (batchCount != 0) { // dispatch remaining
notifyItemRangeRemoved(0, batchCount);
}
}
Necesita extender este código para agregar elementos que fueron filtrados previamente pero que ahora deberían estar visibles (por ejemplo, el usuario borra la consulta de filtro) pero creo que este debería dar la idea básica.
Tenga en cuenta que cada llamada a un elemento de notificación afecta a las siguientes (por eso estoy atravesando la lista desde el final para evitarla). Atravesar desde el final también ayuda a ArrayList a eliminar el rendimiento del método (menos elementos para cambiar).
Por ejemplo, si estaba recorriendo la lista desde el principio y elimina los dos primeros elementos. Usted debe llamar
notifyItemRangeRemoved(0, 2); // 2 items starting from index 0
o si los despacha uno por uno
notifyItemRemoved(0);
notifyItemRemoved(0);//because after the previous one is removed, this item is at position 0
Simplemente vuelva a inicializar su adaptador:
mAdapter = new ItemsAdapter(newItemsData);
o si solo necesita eliminar agregue algunos elementos específicos en lugar de una lista completa:
mAdapter.notifyItemInserted(position);
o
mAdapter.notifyItemRemoved(position);