Estoy usando una implementación simple de RecyclerView
tomado del sitio web de Android usando a StaggeredGridLayoutManager
y sigo recibiendo este error que bloquea mi aplicación:
java.lang.IllegalArgumentException: Scrapped or attached views may not be recycled. isScrap:false isAttached:true
at android.support.v7.widget.RecyclerView$Recycler.recycleViewHolderInternal(RecyclerView.java:3501)
at android.support.v7.widget.RecyclerView$LayoutManager.scrapOrRecycleView(RecyclerView.java:5355)
at android.support.v7.widget.RecyclerView$LayoutManager.detachAndScrapAttachedViews(RecyclerView.java:5340)
at android.support.v7.widget.StaggeredGridLayoutManager.onLayoutChildren(StaggeredGridLayoutManager.java:572)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:1918)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:2155)
at android.view.View.layout(View.java:14008)
at android.view.ViewGroup.layout(ViewGroup.java:4373)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1021)
at android.view.View.layout(View.java:14008)
at android.view.ViewGroup.layout(ViewGroup.java:4373)
at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
at android.view.View.layout(View.java:14008)
at android.view.ViewGroup.layout(ViewGroup.java:4373)
at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
at android.view.View.layout(View.java:14008)
at android.view.ViewGroup.layout(ViewGroup.java:4373)
at android.support.v7.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:502)
at android.view.View.layout(View.java:14008)
at android.view.ViewGroup.layout(ViewGroup.java:4373)
at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
at android.view.View.layout(View.java:14008)
at android.view.ViewGroup.layout(ViewGroup.java:4373)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1663)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1521)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
at android.view.View.layout(View.java:14008)
at android.view.ViewGroup.layout(ViewGroup.java:4373)
at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
at android.view.View.layout(View.java:14008)
at android.view.ViewGroup.layout(ViewGroup.java:4373)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1892)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1711)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
at android.view.Choreographer.doCallbacks(Choreographer.java:562)
at android.view.Choreographer.doFrame(Choreographer.java:532)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
Con simple, literalmente quiero decir que es la misma implementación tomada de esta página en su sitio web , la única diferencia es que el diseño de mi elemento de cuadrícula es un ImageView
par de TextView
s, por lo que no me molestaré en volver a publicar mi código.
¿Alguien más recibe este error y sabe cómo solucionarlo?
android
android-recyclerview
StackOverflowMaster
fuente
fuente
Respuestas:
Este error se produce si en su XML ha
android:animateLayoutChanges
establecido en verdadero y llamanotifyDataSetChanged()
al adaptador de RecyclerView en el código Java.Por lo tanto, evite usar
android:animateLayoutChanges
con RecyclerViews.fuente
RecyclerView
utilizaDefaultItemAnimator
por defecto.También tuve que lidiar con este accidente y, en mi caso, no tuvo nada que ver
android:animateLayoutChanges
.El
RecyclerView
edificio que estábamos construyendo tenía más de un tipo de vistas y algunas teníanEditText
s en ellas. Después de un tiempo, identificamos el problema como relacionado con el enfoque. Este error ocurre mientras se reciclan correosEditText
electrónicos y uno de ellos está enfocado.Naturalmente, intentamos borrar el enfoque cuando se vinculan nuevos datos a una vista reciclada, pero eso no funcionó hasta que
android:focusableInTouchMode="true"
se configuróRecycleView
. En realidad, ese es el único cambio que se necesitó al final para que este problema desapareciera.fuente
android:focusableInTouchMode="true"
porque sucede solo a veces en algunos dispositivos (rara vez) y supongo que no se relaciona con mi problema, pero el seguimiento de la pila para el bloqueo es casi el mismo.android:focusableInTouchMode="true"
me ayudó en absoluto. Así que limpié el enfoque en laonViewDetachedFromWindow
devolución de llamada.public void onViewDetachedFromWindow(@NonNull RecyclerView.ViewHolder holder) { if (holder instanceof ItemViewHolder) { ItemViewHolder item = (ItemViewHolder) holder; if (item.editText.isFocused()) item.editText.clearFocus(); } }
Eliminé la
android:animateLayoutChanges
propiedad de diseño y el problema se resolvió.fuente
android:animateLayoutChanges
en mi RV.Entre las razones por las que cualquiera puede enfrentar este problema, verifique si ha establecido el atributo
android:animateLayoutChanges="true"
en RecyclerView. Esto hará que el reciclaje y la reinstalación de los elementos de RecyclerView fallen. Elimínelo y asigne el atributo al contenedor principal de RecyclerView, como LinearLayout / RelativeLayout y debería ver que el problema desaparece.fuente
Me tomó dos días pero no pude evitar esto, al final, tuve que deshabilitar la captación previa de elementos.
Al configurar el administrador de diseño, simplemente puede llamar
mGridLayoutManager.setItemPrefetchEnabled(false);
Hizo que el error desapareciera para mí. Espero que sea útil para alguien.
fuente
Mientras usaba encabezados adhesivos slimfit, encontré este error. Fue causado por establecer una primera posición incorrecta. Tengo la respuesta aqui
solo asegúrese de pasar el valor correcto para mSectionFirstPosition
fuente
item
aquiMe encontré con este problema esta mañana, pero no estoy enfrentando la misma razón que se mencionó anteriormente.
A través de la depuración, encontré que la vista del elemento en mi ViewHolder tiene
mParent
y no es nula, que en caso normal no debería ser ninguna (eso es lo que dice el registro, "la vista adjunta no se puede reciclar", creo que significa que si la vista secundaria ya está adjunto a un padre, de alguna manera causaría fallas al reciclar).Pero no adjunté la vista infantil cada vez de forma manual. Y descubrí que está hecho cuando trato de inflar la vista infantil en mi ViewHolder, algo como:
Y el último parámetro
attachToRoot
debería ser falso.Después de cambiarlo a
false
, solucioné mi problema.Por cierto, solo veo que este bloqueo ocurrió cuando actualizo mi biblioteca de soporte a la última versión 25.0.0. Antes usaba la versión 23.4.0 y no veo que ocurra este problema. Supongo que debería haber algo cambiado en la última biblioteca de soporte.
Espero que esto ayude.
fuente
También encontré el mismo error al desplazarme por
RecyclerView
: luego eliminé elanimateLayoutChanges="true"
archivo de diseño para queRecyclerView
todo funcionara.fuente
En mi caso, sucedió porque tuve una
Transition
ejecución al intentar cambiar el tamaño de RecyclerView porque el teclado del software estaba a punto de mostrarse.Lo arreglé excluyendo el RecyclerView del
Transition
usandoTransition.excludeTarget(R.id.recyclerview, true);
fuente
Hay varias razones por las que se llama a esta excepción. En mi caso, se debió a la ejecución de animaciones, por eso las vistas aún están adjuntas y no se pudieron eliminar a la vista. Solo cuando la animación haya terminado, la vista podría eliminarse y reciclarse.
Hay dos tipos de animación que podrían afectar el reciclaje de la vista del reciclador.
1) es el
RecyclerView.ItemAnimator
- este no debería ser el problema. Esto debería ser bastante seguro de usar, ya que verifica las vistas adjuntas y desechadas y maneja el reciclaje correctamente.2)
android:animateLayoutChanges="true"
oTransitionManager.beginDelayedTransition()
TransitionManager.go (), etc. - Estas animaciones se ejecutan por sí solas y se apoderan de los elementos para animar. Esto da como resultado que las vistas se obliguen a adjuntar hasta que finalice la animación. La vista del reciclaje no tiene ningún conocimiento de estas animaciones ya que está fuera de su alcance. Por lo tanto, esrecyclerview
posible que intenten reciclar un elemento pensando que podría reciclarse correctamente, pero el problema es que estas API todavía se aferran a las vistas hasta que finaliza la animación.Si está utilizando
android:animateLayoutChanges="true"
oTransitionManager.beginDelayedTransition()
o TransitionManager.go (), etc., simplemente elimine elRecyclerView
y sus hijos de la animación.Simplemente puede hacer esto tomando el
Transition
y llamandoNota:
Tenga en cuenta que es importante utilizar
Transition.excludeChildren()
para excluir a todos losRecyclerview
niños de la animación y no solo a ellosRecyclerview
mismos.fuente
Transition.excludeChildren
. Crea una instancia de un objeto de transición como:,val transition = AutoTransition()
invocaexcludeChildren(recyclerView, true)
este objeto y se lo pasa abeginDelayedTransaction() as the second parameter
.Yo también recibía este error cada vez que tenía animateLayoutChanges = "true" en el archivo de diseño para RecyclerView. Elimina este atributo y el error desaparecerá.
fuente
Si bien en mi caso fue la eliminación
animateOnLayoutChange
de RecyclerView lo que solucionó el bloqueo, todavía necesitaba la capacidad de animar los cambios de diseño dentro de viewHolder. Para que esto funcione,LinearLayout' in the view holder needs the
animateOnLayoutChange 'a verdadero, pero necesitaba hacerlonotifyItemChanged
con el adaptador. Esto permitió que se iniciaran ambas animaciones de layoutTransition (para expandir y contraer viewHolder) y también evita la excepción desechada. Entonces, sí, evite poner animateOnLayoutChange en recylcerView y use los diversos métodos de notificación para habilitar las animaciones predeterminadas en los cambios de tamaño de la vista.fuente
Soluciono este problema quitando
parent.addView()
enonCreateViewHolder
Este es mi codigo
Función en
android.support.v7.widget.RecyclerViewRecycler.recyclerViewHolderinternal()
comprobar si mi botón ya tiene un padre o no. Que si agregamos el botón al padre, también se asignaráRecyclerView
a sumParent
variable.fuente
Vi que esto me sucedió cuando usé un objeto personalizado en
ViewHolder
elRecyclerView
adaptador.Para solucionar el problema, borré el objeto personalizado que en mi caso era un temporizador en
onViewRecycled(ViewHolder holder)
el adaptador de la siguiente manera:Esto solucionó el error.
fuente
fuente
1 、
remove
: eliminar datos de la lista.2 、
notifyDataSetChanged
: notificarDataSetChanged ();3 、
notifyItemRemoved
: muestra la animación.4 、
notifyItemRangeChanged
: rango de tamaño de vista y vuelva a dibujar elviewHolders(onBindViewHolder methods)
fuente
notifyItemRemoved
al eliminarfooter
y la aplicación se bloquea, cámbielo anotifyDataSetChanged
y ahora funciona bien. graciasEn mi caso, usé el
TransitionManager.beginDelayedTransition()
antes de agregar una vista en la parte superior de la vista de reciclaje. Quité elTransitionManager.beginDelayedTransition()
y no choqué.fuente
Resolví este problema llamando
en el constructor del adaptador y anulando
getItemId
en el adaptador:fuente
Eliminar
android:animateLayoutChanges="true"
de la vista de reciclaje o configurarandroid:animateLayoutChanges="false"
fuente
yo suelo
com.squareup.picasso.RequestCreator
para redimensionar dinámicamente el tamaño de ImageView después de descargar la imagen de Internet, y guarda el ancho y alto redimensionados para preservar el tamaño de la vista. Obtuve esta excepción porque guardé
LayoutParams
en aMap
, y en mi onBindViewHolder, la recuperé y la configuré directamente en miImageView
. Soluciono esto mediante el usoImmutablePair<Integer, Integer>
para almacenar solo el tamaño de ImageView en lugar de muchos otros estados, y uso el siguiente código para restaurarlo.fuente
Para mí, el mismo error fue causado por LayoutTransition en un ViewGroup de nivel superior.
fuente
Permítanme agregar otra posible solución para este tipo de problema, por favor. Tuve el mismo problema con la biblioteca superSlim para encabezados pegajosos en
RecyclerView
. SolíaMatrixCursor
configurar los datos enRecyclerViewCursorAdapter
. El motivo de este problema es que las columnas de ID son iguales a0
para todos los encabezados. Espero que eso ayude a alguien a ahorrar un par de días de depuración.fuente
En mi caso, el problema se debió a la implementación incorrecta de este método
public long getItemId(int position)
(anulado delRecyclerView.Adapter
método).El código anterior obtendrá dos ID diferentes para el mismo elemento (en mi caso, es el elemento del pie de página), después de corregir la implementación, el problema desapareció.
fuente
Solución alternativa si el motivo de la excepción es lo que itemView tiene como padre. En el código, donde ha notificadoItemRemoved (posición), elimine itemView de RecyclerView:
fuente
Un caso peculiar que me sucedió fue que tenía un miembro de vista en el adaptador y era perezoso instanciar una vista que no es necesario hacer con la vista de reciclaje.
También va en contra de los principios de reciclado de vistas que, en este caso, almacenan una referencia a la vista. Doy un ejemplo rápido a continuación:
fuente
esta excepción no es causa de
o
esta última respuesta correcta es simplemente porque estableció un LayoutParams INCORRECTO .
el nombre LP está bien. el nameLP2 ocurre el crash .bug está aquí.
Intento todas las respuestas de esta página. Créeme.
fuente
Tenía este problema porque sobreescribo
equals()
yhashcode()
métodoViewHolder
deRecyclerView
.ViewHolder mediante el cálculo de la igualdad de datos y código hash, entonces la lógica de reciclaje no funcionaba y choqué, me quito la sobrescritura y fija.fuente