android - studio - ¿Que es mejor? notifyDataSetChanged o notifyItemChanged en bucle?
recyclerview view holder (3)
Definitivamente llamaría a
notifyDataSetChanged()
si todos los elementos de datos ya no son válidos.
Cuando llama a
notifyItemChanged(mPos)
, es equivalente a una llamada a
notifyItemRangeChanged(mPos, 1)
, y cada vez que se llama, también se llama a
requestLayout()
.
Por otro lado, cuando llama a
notifyDataSetChanged()
o
notifyItemRangeChanged(0, mList.size())
, solo hay una llamada para
requestLayout()
.
Su pregunta ahora debería ser, ¿qué es mejor, una llamada a
notifyDataSetChanged()
o
notifyItemRangeChanged(0, mList.size())
?
Para eso no tengo una respuesta.
Entonces tengo una actividad con
RecyclerView
y quiero cambiar
TextView
de cada elemento en
RecyclerView
presionando el botón que tiene
onClickListener()
en la actividad.
Me pregunto qué es mejor en términos de rendimiento:
-
Utilice
notifyDataSetChanged
unos. -
Use el bucle con una condición como int i es menor que
List.size()
donde senotifyItemChanged
varias veces.
En ambos casos, creo una variable booleana en
RecyclerView
Adapter que es utilizado por
onBindViewHolder
para saber cómo actualizar el elemento.
Por defecto es falso y después de hacer clic en el botón se vuelve verdadero, por lo que
onBindViewHolder
actualiza el elemento de manera diferente.
También me gustaría saber si este enfoque es adecuado en absoluto.
Me di cuenta de que
notifyItemChanged(mPos)
desencadena
onBindVieHolder
para la posición correspondiente, incluso si actualmente no es visible.
Para mí, llamarlo en un bucle para todos los elementos fue más costoso que
notifyDatasetChanged
que
notifyDatasetChanged
dibujar solo los visibles.
Así que tenga cuidado con grandes conjuntos de datos.
Si simplemente está actualizando una parte de la vista, use
notifyItemRangeChanged()
o
notifyItemChanged()
lugar de
notifiyDataSetChanged()
.
La diferencia aquí tiene que ver con
los cambios estructurales
frente a los
cambios de elementos
.
Esto está en los desarrolladores de Android
RecyclerView.Adapter
documentación del
RecyclerView.Adapter
encuentra
here
.
Aquí hay otro dato sobre las diferencias entre los dos tipos de cambios:
Hay dos clases diferentes de eventos de cambio de datos, cambios de elementos y cambios estructurales. Los cambios de elementos son cuando un solo elemento tiene sus datos actualizados pero no se han producido cambios de posición. Los cambios estructurales son cuando los elementos se insertan, eliminan o mueven dentro del conjunto de datos.
Esto está tomado de la página mencionada anteriormente,
Si está escribiendo un adaptador, siempre será más eficiente usar los eventos de cambio más específicos si puede. Confíe en notifyDataSetChanged () como último recurso.
Entonces, solo para aclarar, use
notifyDataSetChanged()
como
último recurso
y, en su lugar, pregúntese si puede realizar uno de estos métodos y si puede usarlo en su lugar:
notifyItemChanged(int)
notifyItemInserted(int)
notifyItemRemoved(int)
notifyItemRangeChanged(int, int)
notifyItemRangeInserted(int, int)
notifyItemRangeRemoved(int, int)
lo cual tiene sentido porque
notifyDataSetChanged()
intentará redibujar todo basándose en los datos y no hará suposiciones previas, mientras que los otros métodos solo buscarán cambios.
Eso significa que el adaptador tiene que hacer mucho más trabajo que no es necesario.
Esto es lo que
notifyDataSetChanged()
hace:
Este evento no especifica qué ha cambiado el conjunto de datos, lo que obliga a los observadores a suponer que todos los elementos y la estructura existentes pueden dejar de ser válidos. LayoutManagers se verá obligado a volver a vincular y retransmitir completamente todas las vistas visibles.
Esto también tiene sentido usar el enfoque incremental o de rango, ya que está cambiando el texto, debe ir a buscar cada texto nuevo y cuando lo haga, debe decirle al adaptador que lo cambió.
Ahora, si hace clic en un botón y obtiene todos los nuevos valores de texto, y crea una nueva lista o algo así, llame a
notifyDataSetChanged()
.