RecyclerView stürzt ab, wenn "verschrottete oder angehängte Ansichten möglicherweise nicht recycelt werden"

Ich verwende eine einfache Implementierung von RecyclerView die von der Android-Website mit einem StaggeredGridLayoutManager und ich bekomme immer diesen Fehler, der meine App abstürzt:

 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) 

Mit einfachen, ich buchstäblich bedeutet, dass es die gleiche Implementierung von dieser Seite auf ihrer Website genommen ist , ist der einzige Unterschied, dass mein Raster Element das Layout ist ein ImageView und ein paar TextView s, so dass ich nicht die Mühe, meinen Code neu zu berechnen.

  • Verwenden von Groovy auf Android
  • Warum gibt es insertOrThrow aber kein updateOrThrow oder deleteOrThrow?
  • Wie füge ich Scrollbars zu einem LinearLayout in Android hinzu?
  • Android AsyncTask testet mit Android Test Framework
  • Libgdx Setup UI gibt 2 unerwartete Fehler im neuen GWT-Projekt
  • Android, AsyncTask, Status überprüfen?
  • Wer sonst noch diesen Fehler bekommt und weiß, wie man damit umgeht?

  • Google Maps v2 Set Zoom Ebene
  • Android: Verwenden Sie das Netzwerk in einem Dienst
  • Android Studio 2.0 Warten auf Debugger
  • Aktivität mit Fragmenten wird nicht geändert, wenn die Tastatur geöffnet wird
  • ActionBarSherlock Spinner nicht auswählbar in ActionBar - Theme related
  • Android - MultipartEntity und Abhängigkeiten
  • 17 Solutions collect form web for “RecyclerView stürzt ab, wenn "verschrottete oder angehängte Ansichten möglicherweise nicht recycelt werden"”

    Dieser Fehler wird verursacht, wenn Sie in Ihrem XML android:animateLayoutChanges auf true gesetzt haben und Sie notifyDataSetChanged() auf dem RecyclerView-Adapter im Java-Code aufrufen.

    Also, vermeiden Sie einfach mit android:animateLayoutChanges mit RecyclerViews.

    Ich musste auch mit diesem Crash umgehen und in meinem Fall hatte es nichts mit android:animateLayoutChanges zu tun android:animateLayoutChanges .

    Die RecyclerView wir EditText hatte mehr als eine Art von Ansichten darin und einige hatten EditText s in ihnen. Nach einer Weile haben wir das Problem auf fokussiert Dieser Fehler passiert beim Recycling von EditText s und einer von ihnen ist fokussiert.

    Natürlich haben wir versucht, den Fokus zu klären, wenn neue Daten an eine recycelte Ansicht gebunden werden, aber das hat nicht funktioniert bis android:focusableInTouchMode="true" ist auf RecycleView . Eigentlich ist das die einzige Veränderung, die am Ende für diese Frage benötigt wurde, um wegzugehen.

    Ich habe die "android: animateLayoutChanges" von der Layout-Eigenschaft entfernt und das Problem wurde behoben.

    Bei der Verwendung von Slimfit Sticky Header habe ich diesen Fehler festgestellt. Es wurde wegen der falschen ersten Position verursacht. Hier habe ich die antwort

     public void onBindViewHolder(MainViewHolder holder, int position) { final View itemView = holder.itemView; final LayoutManager.LayoutParams params = LayoutManager.LayoutParams.from(itemView.getLayoutParams()); params.setSlm(LinearSLM.ID); params.width = ViewGroup.LayoutParams.MATCH_PARENT; params.setFirstPosition(item.mSectionFirstPosition); itemView.setLayoutParams(params); } 

    Stellen Sie einfach sicher, dass Sie den richtigen Wert für mSectionFirstPosition übergeben

    Ich traf dieses Problem heute morgen, aber ich bin nicht vor dem gleichen Grund wie oben erwähnt.

    Über Debug fand ich, dass die Item-Ansicht in meinem ViewHolder mParent hat und es ist nicht null, was im Normalfall sollte es keine sein (das ist, was das Log sagt, "angehängte Ansicht kann nicht recycelt werden", denke ich das bedeutet, dass wenn das Kind Ansicht ist bereits an einem Elternteil angebracht, es würde einige, wie Ursache Versagen, wenn recyclering.)

    Aber ich habe das Kind nicht jedes Mal manuell angefügt. Und ich habe festgestellt, dass es getan ist, wenn ich versuche, die Kinderansicht in meinem ViewHolder aufzublasen, so etwas wie:

     layoutInflater.inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) 

    Und der letzte Parameter attachToRoot sollte falsch sein.

    Nachdem ich es false geändert habe, habe ich mein Problem behoben.

    Übrigens, ich sehe nur diesen Crash passiert, wenn ich meine Support-Bibliothek auf die neueste Version 25.0.0 aktualisieren. Bevor ich die Version 23.4.0 verwende und ich sehe dieses Problem nicht. Ich denke, es sollte etwas in der neuesten Support-Bibliothek geändert werden.

    Ich hoffe das hilft.

    Ich löse dieses Problem durch das Entfernen von parent.addView() in onCreateViewHolder

    Das ist mein Code

     public MyViewHolder onCreateViewwHolder(ViewGroup parent, int viewType) { Button addButton = new Button(context); //parent.addView(addButton); return new MyViewHolder(addButton); } 

    Funktion bei android.support.v7.widget.RecyclerViewRecycler.recyclerViewHolderinternal() prüfe, ob mein Button bereits ein Elternteil hat oder nicht. Welches, wenn wir Knopf zum Elternteil hinzufügen, wird es auch RecyclerView zu seiner mParent Variable zuweisen.

    Unter den Gründen, die jeder dieses Problem stellen kann, überprüfen Sie, ob Sie das Attribut android:animateLayoutChanges="true" zum RecyclerView. Dies führt dazu, dass das Recycling und die Wiederherstellung der RecyclerView-Elemente fehlschlägt. Entfernen Sie es und ordnen Sie das Attribut dem RecyclerView-übergeordneten Container zu, z. B. ein LinearLayout / RelativeLayout, und Sie sollten das Problem sehen.

    Ich sah das für mich passieren, wenn ich ein benutzerdefiniertes Objekt im ViewHolder für den RecyclerView Adapter verwendete.

    Um das Problem zu beheben, löschte ich das benutzerdefinierte Objekt, das in meinem Fall ein Timer im onViewRecycled(ViewHolder holder) für den Adapter wie unten war:

      public void onViewRecycled(ViewHolder holder) { if(holder instanceof EntityViewHolder) { if(((EntityViewHolder)holder).timer != null) { ((EntityViewHolder) holder).timer.cancel(); } } super.onViewRecycled(holder); } 

    Das hat den Fehler behoben.

      /** * Informs the recycler whether this item can be recycled. Views which are not * recyclable will not be reused for other items until setIsRecyclable() is * later set to true. Calls to setIsRecyclable() should always be paired (one * call to setIsRecyclabe(false) should always be matched with a later call to * setIsRecyclable(true)). Pairs of calls may be nested, as the state is internally * reference-counted. * * @param recyclable Whether this item is available to be recycled. Default value * is true. * * @see #isRecyclable() */ public final void setIsRecyclable(boolean recyclable) { mIsRecyclableCount = recyclable ? mIsRecyclableCount - 1 : mIsRecyclableCount + 1; if (mIsRecyclableCount < 0) { mIsRecyclableCount = 0; if (DEBUG) { throw new RuntimeException("isRecyclable decremented below 0: " + "unmatched pair of setIsRecyable() calls for " + this); } Log.e(VIEW_LOG_TAG, "isRecyclable decremented below 0: " + "unmatched pair of setIsRecyable() calls for " + this); } else if (!recyclable && mIsRecyclableCount == 1) { mFlags |= FLAG_NOT_RECYCLABLE; } else if (recyclable && mIsRecyclableCount == 0) { mFl`enter code here`ags &= ~FLAG_NOT_RECYCLABLE; } if (DEBUG) { Log.d(TAG, "setIsRecyclable val:" + recyclable + ":" + this); } } 

    1, remove : Daten aus der Liste entfernen

    2, notifyDataSetChanged : notifyDataSetChanged ();

    3, notifyItemRemoved : Animation notifyItemRemoved

    4, notifyItemRangeChanged : range view size und viewHolders(onBindViewHolder methods) the viewHolders(onBindViewHolder methods)

    Ich habe dieses Problem gelöst

     setHasStableIds(true); 

    Im Adapter-Konstruktor und getItemId im Adapter:

     @Override public long getItemId(int position) { return position; } 

    Ich benutze com.squareup.picasso.RequestCreator

     public void into(android.widget.ImageView target, Callback callback) 

    Um die Größe von ImageView nach dem Download-Bild aus dem Internet dynamisch zu verändern und die verkleinerte Breite und Höhe zu speichern, um die Ansichtsgröße zu bewahren. Ich habe diese Ausnahme bekommen, weil ich LayoutParams in einer Map gespeichert LayoutParams , und in meinem onBindViewHolder habe ich es abgerufen und direkt auf meine ImageView . Ich repariere dies durch die Verwendung von ImmutablePair<Integer, Integer> um nur die Größe von ImageView zu speichern, anstatt viele andere Zustände, und verwenden Sie den folgenden Code, um sie wiederherzustellen.

     ViewGroup.LayoutParams params = image.getLayoutParams(); params.width = widthAndHeight.getLeft(); params.height = widthAndHeight.getRight(); image.setLayoutParams(params); 

    Für mich der gleiche Bug mit verursacht durch eine LayoutTransition auf einer höheren Ebene ViewGroup.

    Lassen Sie mich eine weitere mögliche Korrektur für diese Art von Problem hinzufügen, bitte. Ich hatte das gleiche Problem mit superSlim Bibliothek für klebrige Header in RecyclerView . Ich habe MatrixCursor , um Daten auf RecyclerViewCursorAdapter . Der Grund für dieses Problem war ID Spalten entspricht 0 für alle Header. Hoffe, das würde jemandem helfen, paar Tage des Debuggens zu retten.

    In meinem Fall war das Problem wegen der fehlerhaften Implementierung dieser Methode public long getItemId(int position) (override from RecyclerView.Adapter Methode).

    Der alte Code bekommt zwei verschiedene IDs für das gleiche Element (in meinem Fall ist es die Fußzeile), nach der Festsetzung der Implementierung ist das Problem gegangen.

    In meinem Fall habe ich die TransitionManager.beginDelayedTransition() bevor ich eine Ansicht über die recyclerView hinzufüge. Ich habe den TransitionManager.beginDelayedTransition() und keinen Absturz entfernt.

    Ein eigenartiger Fall, der für mich auftrat, war, dass ich ein View Member im Adapter hatte und ich war faul Instanziierung einer Ansicht, die es nicht nötig ist, mit der Recyclingansicht zu tun.

    Es geht auch gegen die Recycling-Ansichten Prinzipien, die als Ihre Speicherung einen Verweis auf die Ansicht in diesem Fall. Ich gebe ein kurzes Beispiel unten:

     // typically we would do this in a grid view adapter: View v; // ... if(v = null){ v = LayoutInflater.inflate ...; } // Now with recycle view there is NO need to store a reference to View and lazy instantiate. So get rid of your View v member 
    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.