webentwicklung-frage-antwort-db.com.de

RecyclerView: Inkonsistenz festgestellt. Ungültige Artikelposition

Unsere Qualitätssicherung hat einen Fehler festgestellt: Beim Drehen des Android Gerät (Droid Turbo)) ist der folgende RecyclerView-bezogene Absturz aufgetreten:

Java.lang.IndexOutOfBoundsException: Inkonsistenz festgestellt. Ungültige Artikelposition 2 (Versatz: 2) .Zustand: 3

Für mich scheint es ein interner Fehler in RecyclerView zu sein, da ich mir keine Möglichkeit vorstellen kann, dass dies direkt durch unseren Code verursacht wird ...

Ist jemand auf dieses Problem gestoßen?

Was wäre die Lösung?

Eine brutale Problemumgehung könnte darin bestehen, die Ausnahme in diesem Fall abzufangen und die RecyclverView-Instanz von Grund auf neu zu erstellen, um einen beschädigten Zustand zu vermeiden.

Aber wenn möglich, möchte ich das Problem besser verstehen (und es möglicherweise an der Quelle beheben), anstatt es zu maskieren.

Der Fehler ist nicht einfach zu reproduzieren, aber es ist fatal, wenn es passiert.

Der vollständige Stack-Trace:

W/dalvikvm( 7546): threadid=1: thread exiting with uncaught exception (group=0x41987d40)
    E/AndroidRuntime( 7546): FATAL EXCEPTION: main
    E/AndroidRuntime( 7546): Process: com.oblong.mezzedroid, PID: 7546
    E/AndroidRuntime( 7546): Java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 2(offset:2).state:3
    E/AndroidRuntime( 7546):    at Android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.Java:3382)
    E/AndroidRuntime( 7546):    at Android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.Java:3340)
    E/AndroidRuntime( 7546):    at Android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.Java:1810)
    E/AndroidRuntime( 7546):    at Android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.Java:1306)
    E/AndroidRuntime( 7546):    at Android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.Java:1269)
    E/AndroidRuntime( 7546):    at Android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.Java:523)
    E/AndroidRuntime( 7546):    at org.liboid.recycler_view.RecyclerViewContainer$LiLinearLayoutManager.onLayoutChildren(RecyclerViewContainer.Java:179)
    E/AndroidRuntime( 7546):    at Android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.Java:1942)
    E/AndroidRuntime( 7546):    at Android.support.v7.widget.RecyclerView.onLayout(RecyclerView.Java:2237)
    E/AndroidRuntime( 7546):    at org.liboid.recycler_view.LiRecyclerView.onLayout(LiRecyclerView.Java:30)
    E/AndroidRuntime( 7546):    at Android.view.View.layout(View.Java:14946)
    E/AndroidRuntime( 7546):    at Android.view.ViewGroup.layout(ViewGroup.Java:4651)
    E/AndroidRuntime( 7546):    at Android.widget.FrameLayout.layoutChildren(FrameLayout.Java:453)
    E/AndroidRuntime( 7546):    at Android.widget.FrameLayout.onLayout(FrameLayout.Java:388)
    E/AndroidRuntime( 7546):    at Android.view.View.layout(View.Java:14946)
    E/AndroidRuntime( 7546):    at Android.view.ViewGroup.layout(ViewGroup.Java:4651)
    E/AndroidRuntime( 7546):    at Android.widget.FrameLayout.layoutChildren(FrameLayout.Java:453)
    E/AndroidRuntime( 7546):    at Android.widget.FrameLayout.onLayout(FrameLayout.Java:388)
    E/AndroidRuntime( 7546):    at Android.view.View.layout(View.Java:14946)
    E/AndroidRuntime( 7546):    at Android.view.ViewGroup.layout(ViewGroup.Java:4651)
    E/AndroidRuntime( 7546):    at Android.widget.LinearLayout.setChildFrame(LinearLayout.Java:1671)
    E/AndroidRuntime( 7546):    at Android.widget.LinearLayout.layoutVertical(LinearLayout.Java:1525)
    E/AndroidRuntime( 7546):    at Android.widget.LinearLayout.onLayout(LinearLayout.Java:1434)
    E/AndroidRuntime( 7546):    at com.oblong.mezzedroid.workspace.content.bins.BinsContainerLayout.onLayout(BinsContainerLayout.Java:22)
    E/AndroidRuntime( 7546):    at Android.view.View.layout(View.Java:14946)
    E/AndroidRuntime( 7546):    at Android.view.ViewGroup.layout(ViewGroup.Java:4651)
    E/AndroidRuntime( 7546):    at Android.widget.LinearLayout.setChildFrame(LinearLayout.Java:1671)
    E/AndroidRuntime( 7546):    at Android.widget.LinearLayout.layoutVertical(LinearLayout.Java:1525)
    E/AndroidRuntime( 7546):    at Android.widget.LinearLayout.onLayout(LinearLayout.Java:1434)
    E/AndroidRuntime( 7546):    at Android.view.View.layout(View.Java:14946)
    E/AndroidRuntime( 7546):    at Android.view.ViewGroup.layout(ViewGroup.Java:4651)
    E/AndroidRuntime( 7546):    at Android.widget.FrameLayout.layoutChildren(FrameLayout.Java:453)
    E/AndroidRuntime( 7546):    at Android.widget.FrameLayout.onLayout(FrameLayout.Java:388)
    E/AndroidRuntime( 7546):    at Android.view.View.layout(View.Java:14946)
    E/AndroidRuntime( 7546):    at Android.view.ViewGroup.layout(ViewGroup.Java:4651)
    E/AndroidRuntime( 7546):    at Android.widget.FrameLayout.layoutChildren(FrameLayout.Java:453)
    E/AndroidRuntime( 7546):    at Android.widget.FrameLayout.onLayout(FrameLayout.Java:388)
    E/AndroidRuntime( 7546):    at Android.view.View.layout(View.Java:14946)
    E/AndroidRuntime( 7546):    at Android.view.ViewGroup.layout(ViewGroup.Java:4651)
    E/AndroidRuntime( 7546):    at Android.widget.LinearLayout.setChildFrame(LinearLayout.Java:1671)
    E/AndroidRuntime( 7546):    at Android.widget.LinearLayout.layoutVertical(LinearLayout.Java:1525)
    E/AndroidRuntime( 7546):    at Android.widget.LinearLayout.onLayout(LinearLayout.Java:1434)
    E/AndroidRuntime( 7546):    at Android.view.View.layout(View.Java:14946)
    E/AndroidRuntime( 7546):    at Android.view.ViewGroup.layout(ViewGroup.Java:4651)
    E/AndroidRuntime( 7546):    at Android.widget.FrameLayout.layoutChildren(FrameLayout.Java:453)
    E/AndroidRuntime( 7546):    at Android.widget.FrameLayout.onLayout(FrameLayout.Java:388)
    E/AndroidRuntime( 7546):    at Android.view.View.layout(View.Java:14946)
    E/AndroidRuntime( 7546):    at Android.view.ViewGroup.layout(ViewGroup.Java:4651)
    E/AndroidRuntime( 7546):    at Android.widget.LinearLayout.setChildFrame(LinearLayout.Java:1671)
    E/AndroidRuntime( 7546):    at Android.widget.LinearLayout.layoutVertical(LinearLayout.Java:1525)
    E/AndroidRuntime( 7546):    at Android.widget.LinearLayout.onLayout(LinearLayout.Java:1434)
    E/AndroidRuntime( 7546):    at Android.view.View.layout(View.Java:14946)
    E/AndroidRuntime( 7546):    at Android.view.ViewGroup.layout(ViewGroup.Java:4651)
    E/AndroidRuntime( 7546):    at Android.widget.FrameLayout.layoutChildren(FrameLayout.Java:453)
    E/AndroidRuntime( 7546):    at Android.widget.FrameLayout.onLayout(FrameLayout.Java:388)
    E/AndroidRuntime( 7546):    at Android.view.View.layout(View.Java:14946)
    E/AndroidRuntime( 7546):    at Android.view.ViewGroup.layout(ViewGroup.Java:4651)
    E/AndroidRuntime( 7546):    at Android.view.ViewRootImpl.performLayout(ViewRootImpl.Java:2132)
    E/AndroidRuntime( 7546):    at Android.view.ViewRootImpl.performTraversals(ViewRootImpl.Java:1872)
    E/AndroidRuntime( 7546):    at andro
228
KarolDepka

Ich hatte ein (möglicherweise) verwandtes Problem - das Eingeben einer neuen Instanz einer Aktivität mit einem RecyclerView, aber mit einem kleineren Adapter, löste diesen Absturz für mich aus.

RecyclerView.dispatchLayout() kann versuchen, Elemente aus dem Ausschuss zu ziehen, bevor mRecycler.clearOldPositions() aufgerufen wird. Die Folge ist, dass Elemente aus dem allgemeinen Pool abgerufen wurden, deren Positionen über der Adaptergröße lagen.

Glücklicherweise funktioniert dies nur, wenn PredictiveAnimations aktiviert ist. Daher bestand meine Lösung darin, GridLayoutManager zu unterklassifizieren (LinearLayoutManager weist dasselbe Problem auf und 'behebt') und supportsPredictiveItemAnimations() um false zurückzugeben:

/**
 * No Predictive Animations GridLayoutManager
 */
private static class NpaGridLayoutManager extends GridLayoutManager {
    /**
     * Disable predictive animations. There is a bug in RecyclerView which causes views that
     * are being reloaded to pull invalid ViewHolders from the internal recycler stack if the
     * adapter size has decreased since the ViewHolder was recycled.
     */
    @Override
    public boolean supportsPredictiveItemAnimations() {
        return false;
    }

    public NpaGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    public NpaGridLayoutManager(Context context, int spanCount) {
        super(context, spanCount);
    }

    public NpaGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {
        super(context, spanCount, orientation, reverseLayout);
    }
}
175
Kas Hunt

In meinem Fall (Löschen/Einfügen von Daten in meiner Datenstruktur) musste ich den Recycling-Pool löschen und dann den geänderten Datensatz benachrichtigen!

mRecyclerView.getRecycledViewPool().clear(); mAdapter.notifyDataSetChanged();

73
MatejC

Benutze notifyDataSetChanged() statt notifyItem... in diesem Fall.

38
khaintt

Ich löste dieses Problem, indem ich die mRecycler.setAdapter(itemsAdapter) verzögerte, bis alle Elemente mit mRecycler.addAll(items) zum Adapter hinzugefügt worden waren, und es funktionierte. Keine Ahnung, warum ich das getan habe, es war aus dem Code einer Bibliothek, in dem ich diese Zeilen in der "falschen Reihenfolge" durchgesehen habe damit? Ich bin nicht sicher, ob dies überhaupt eine gültige Antwort ist

11
Odaym

Ich hatte ein ähnliches Problem, aber nicht genau das gleiche. In meinem Fall habe ich an einem Punkt das Array gelöscht, das an die Recyclingübersicht übergeben wurde

mObjects.clear();

und nicht notifyDataSetChanged aufrufen, da ich nicht wollte, dass die recyclerview die Ansichten sofort löscht. Ich habe das mObjects-Array in AsyncTask neu gefüllt.

11
Aalap

Ich habe das gleiche Problem. Es trat auf, als ich schnell einen Bildlauf durchführte und API aufrief und Daten aktualisierte. Nachdem ich alle Dinge versucht hatte, um einen Absturz zu verhindern, fand ich eine Lösung.

mRecyclerView.stopScroll();

Es wird klappen.

7
Anand Savjani

Dieser Fehler tritt auf, wenn die Liste im Adapter beim Scrollen durch den Benutzer gelöscht wird, wodurch sich die Position des Elementhalters ändert, die Referenz zwischen der Liste und dem Element auf der Benutzeroberfläche verloren geht und bei der nächsten "notifyDataSetChanged" -Anforderung ein Fehler auftritt.

Fix:

Überprüfen Sie Ihre Aktualisierungslistenmethode. Wenn du so etwas machst

mainList.clear();
...
mainList.add() or mainList.addAll()
...
notifyDataSetChanged();

===> Error occur

Wie repariert man. Legen Sie ein neues Listenobjekt für die Pufferbearbeitung an und ordnen Sie es anschließend wieder der Hauptliste zu

List res = new ArrayList();
…..
res.add();  //add item or modify list
….
mainList = res;
notifyDataSetChanged();

Vielen Dank an Nhan Cao für diese großartige Hilfe :)

4
Ramesh Pokharel

Ich hatte das gleiche Problem mit recyclerView. Deshalb habe ich den Adapter direkt nach dem Löschen der Liste über eine Änderung des Datensatzes informiert.

mList.clear();
mAdapter.notifyDataSetChanged();

mList.addAll(newData);
mAdapter.notifyDataSetChanged();
4
Reza

Mein Problem verschwand, nachdem ich meine Adapter -Implementierung so geändert hatte, dass anstelle eines Verweises eine Kopie des items-Arrays verwendet wurde. Die setItems() -Methode wird jedes Mal aufgerufen, wenn wir neue Elemente im RecyclerView anzeigen müssen.

Anstatt von:

private class MyAdapter extends RecyclerView.Adapter<ItemHolder> {
     private List<MyItem> mItems;  

    (....)

    void setItems(List<MyItem> items) {
        mItems = items;
    }
}

Ich tat:

void setItems(List<MyItem> items) {
    mItems = new ArrayList<>(items);
}
4

Um dieses Problem zu beheben, rufen Sie einfach notifyDataSetChanged () mit leerer Liste auf, bevor Sie die Recycling-Ansicht aktualisieren.

Zum Beispiel

//Method for refresh recycle view

    if (!hcpArray.isEmpty())

hcpArray.clear (); // Die Liste für die Aktualisierungs-Recycling-Ansicht

adapter.notifyDataSetChanged();
3
EKN

Verwenden

notifyDataSetChanged()

stattdessen

notifyItemRangeInserted(0, YourArrayList.size())

in diesem Fall.

3
Pankaj Talaviya

Ich ändere Daten für das RecyclerView im Hintergrund Thread. Ich habe das gleiche Exception wie das OP. Ich habe dies nach dem Ändern der Daten hinzugefügt:

myRecyclerView.post(new Runnable() {
    @Override
    public void run() {
        myRecyclerAdapter.notifyDataSetChanged();
    }
});

Ich hoffe es hilft

3

Ich bin kürzlich mit den neuen Android Architecture Components auf diesen bösen Stack-Trace gestoßen. Im Wesentlichen habe ich in meinem ViewModel eine Liste von Elementen, die von meinem Fragment mithilfe von LiveData beobachtet werden Mit dem neuen Wert für die Daten aktualisiert das Fragment den Adapter, übergibt diese neuen Datenelemente und benachrichtigt den Adapter, dass Änderungen vorgenommen wurden.

Leider konnte ich bei der Übergabe der neuen Datenelemente an den Adapter nicht berücksichtigen, dass sowohl das ViewModel als auch der Adapter auf dieselbe Objektreferenz verweisen würden! Das heißt, wenn ich die Daten aktualisiere und postValue() im ViewModel aufrufe, gibt es ein sehr kleines Fenster, in dem die Daten aktualisiert und der Adapter noch nicht benachrichtigt werden kann!

Mein Fix bestand darin, eine neue Kopie der Elemente zu instanziieren, wenn sie an den Adapter übergeben wurden:

mList = new ArrayList<>(passedList);

Mit diesem supereinfachen Fix können Sie sicherstellen, dass sich Ihre Adapterdaten erst unmittelbar vor der Benachrichtigung Ihres Adapters ändern.

2
Steve

In meinem Fall habe ich die Elemente aktualisiert und notifyDataSetChanged in einem Nicht-UI-Thread aufgerufen. Meistens funktionierte es, aber wenn viele Änderungen schnell vorkamen, stürzte es ab. Wenn ich stattdessen tat, im Grunde

activity.runOnUiThread(new Runnable() {
    @Override
    public void run() {
        changeData();
        notifyDataSetChanged();
    }
});

dann hörte es auf zu krachen.

2
Erhannis

Sie müssen Ihre Liste nur in OnPostExecute() löschen und nicht während Pull to Refresh

// Setup refresh listener which triggers new data loading
        swipeContainer.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {

                AsyncTask<String,Void,String> task = new get_listings();
                task.execute(); // clear listing inside onPostExecute

            }
        });

Ich habe festgestellt, dass dies passiert, wenn Sie während eines Ziehen zum Aktualisieren scrollen, da ich die Liste vor dem async task, was zu Java.lang.IndexOutOfBoundsException: Inconsistency detected.

        swipeContainer.setRefreshing(false);
        //TODO : This is very crucial , You need to clear before populating new items 
        listings.clear();

Auf diese Weise werden Sie nicht mit einer Inkonsistenz enden

2
Fahad

Ich habe mit der gleichen Situation konfrontiert. Sie haben Codes hinzugefügt, bevor Sie Ihre Sammlung gelöscht haben.

mRecyclerView.getRecycledViewPool().clear();

1
MagicDroidX

dieses Problem kann auftreten, wenn Sie versuchen, Ihre Liste zu löschen. Wenn Sie Ihre Datenliste insbesondere dann löschen möchten, wenn Sie Pull zum Aktualisieren verwenden, versuchen Sie, ein Boolesches Flag zu verwenden, initialisieren Sie es als false und löschen Sie Ihre dataList mit der OnRefresh-Methode als true if flag ist true, kurz bevor die neuen Daten hinzugefügt werden und danach false.

ihr Code könnte so sein

 private boolean pullToRefreshFlag = false ;
 private ArrayList<your object> dataList ;
 private Adapter adapter ;

 public class myClass extend Fragment implements SwipeRefreshLayout.OnRefreshListener{

 private void requestUpdateList() {

     if (pullToRefresh) {
        dataList.clear
        pullToRefreshFlag = false;
     }

     dataList.addAll(your data);
     adapter.notifyDataSetChanged;


 @Override
 OnRefresh() {
 PullToRefreshFlag = true
 reqUpdateList() ; 
 }

}
1
Moaz H

Ich bin auf ein ähnliches Problem gestoßen und habe es gerade herausgefunden. Ich habe ein paar Beispiele für einen Testfall hart codiert, aber nicht sichergestellt, dass sie jeweils eine eindeutige ID zurückgaben, und das hat den folgenden Absturz für mich verursacht. Das Beheben der IDs hat das Problem behoben. Hoffe, dass dies jemand anderem hilft!

1
DocBot

In meinem Fall habe ich gerade die Zeile mit setHasStableIds(true); entfernt.

1
darkchaos

In meinem Fall habe ich versucht, den Inhalt meines Adapters in einem Hintergrundthread zu ändern, aber im Hauptthread/ui notify * aufgerufen.

Das ist nicht möglich! Der Grund, warum die Benachrichtigung zum Hauptthread gezwungen wird, ist, dass Sie in der Recyclingübersicht Ihren Sicherungsadapter im Hauptthread bearbeiten möchten, selbst auf demselben Aufrufstapel.

Um das Problem zu lösen, stellen Sie sicher, dass jeder Vorgang an Ihrem Adapter sowie jeder Benachrichtigungsaufruf auf dem i/main thread erfolgt!

Dies kann auch mit dem mehrfachen gleichzeitigen Einstellen des Adapters zusammenhängen. Ich hatte eine Callback-Methode, die 5-6 Mal gleichzeitig ausgelöst wurde, und ich stellte den Adapter in diesem Callback so ein, dass RecycledViewPool nicht mit all diesen Daten gleichzeitig umgehen konnte. Es ist eine fette Chance, aber Sie sollten es trotzdem überprüfen.

1
Mustafa Güven

Entfernen Sie einfach alle Ansichten Ihres Layout Managers, bevor Sie ihn benachrichtigen. mögen:

myLayoutmanager.removeAllViews();
1
BaBaX Ra

Das ist ein ziemlich böser Bug.

Um mit meinem Artikelklick fertig zu werden, habe ich eine Implementierung von RecyclerView.OnItemTouchListener Verwendet, die der Lösung in diese Frage ähnelt.

Nach mehrmaligem Aktualisieren der Datenquelle von RecyclerView und Klicken auf ein Element konnte diese Anwendung durch IndexOutOfBoundsException zum Absturz gebracht werden. Wenn ein Element angeklickt wird, sucht das RecyclerView intern nach der richtigen zugrunde liegenden Ansicht und gibt seine Position zurück. Beim Auschecken des Quellcodes sah ich, dass einige Tasks und Threads geplant waren. Um die Geschichte kurz zu fassen, es handelt sich im Grunde genommen nur um einen illegalen Zustand, in dem zwei Datenquellen vermischt und nicht synchronisiert werden und das Ganze verrückt wird.

Aufgrund dessen habe ich meine Implementierung des RecyclerView.OnItemTouchListener Entfernt und einfach den Klick auf das ViewHolder des Adapter selbst abgefangen:

public void onBindViewHolder (final BaseContentView holder, final int position) {

    holder.itemView.setOnClickListener(new OnClickListener() {

      @Override
      public void onClick (View view) {

        // do whatever you like here
      }
    });

}

Dies ist vielleicht nicht die beste Lösung, aber für den Moment noch ohne Absturz. Hoffentlich sparen Sie dadurch etwas Zeit :).

0
DroidBender

add_location.removeAllViews ();

            for (int i=0;i<arrayList.size();i++)
            {
                add_location.addView(new HolderDropoff(AddDropOffActivtity.this,add_location,arrayList,AddDropOffActivtity.this,this));
            }
            add_location.getAdapter().notifyDataSetChanged();
0
Manish Sharma

Lint gab mir einen Rat bezüglich Inkonsistenz: Ich schrieb (onBindViewHolder ()):

pholder.mRlayout.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        doStuff(position);
                    }
                });

welches ersetzt werden musste durch:

pholder.mRlayout.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        doStuff(pholder.getAdapterPosition());
                    }
                });

Führen Sie beide Codes in Ihrem Code aus und führen Sie dann Lint aus, um die vollständige Erklärung zu erhalten !!

0
Rodolphe Calvet

ich habe auch mal den fehler bekommen:

rsache: Ich habe versucht, eine Recycler-Ansicht von einer Async-Aufgabe zu aktualisieren, während gleichzeitig versucht wurde, alte gelöschte viewHolders abzurufen.

Code: Ich generiere Daten auf Knopfdruck, Logik wie folgt

  1. Löschen Sie die letzten Elemente in der Recycler-Ansicht
  2. Rufen Sie die asynchrone Task auf, um Daten zu generieren
  3. OnPostExecute Aktualisieren Sie die Ansicht Recycler und NotifyDataSetChanged

Problem: Immer wenn ich vor dem Generieren meiner Daten schnell scrolle, erhalte ich

Inkonsistenz festgestellt. Ungültige Position des View Holder-AdaptersViewHolder Java.lang.IndexOutOfBoundsException: Inkonsistenz festgestellt. Ungültige Artikelposition 20 (Versatz: 2) .Zustand: 3

Lösung: anstatt das RecyclerView vor dem Generieren meiner Daten zu löschen, lasse ich es stattdessen und ersetze es dann durch die neuen Daten, den Call NotifyDatasetChanged, wie unten gezeigt;

       @Override
        protected void onPostExecute(List<Objects> o) {
            super.onPostExecute(o);
            recyclerViewAdapter.setList(o);
            mProgressBar.setVisibility(View.GONE);
            mRecyclerView.setVisibility(View.VISIBLE);
        }
0
EdgeDev

Bei mir hat es nach dem Hinzufügen dieser Codezeile funktioniert:

mRecyclerView.setItemAnimator(null);
0
Fatih Gee

Das Problem trat bei mir auf, als ich nicht erkannt hatte, dass ich zweimal mit verschiedenen Threads gleichzeitig aufgerufen habe.

notifyDataSetChanged

eine von sqlite load function eine von after calling function

0
Beyaz

Ich habe das Problem behoben, indem ich nacheinander Elemente hinzufügte, wenn neue Daten eingingen. Ich benutze diese Funktion im Adapter.

public void add(Data item) {
        if(!params.contains(item){
           params.add(item);
           notifyItemInserted(getItemCount() - 1);
        }
    }
}
0
César Cobo

Entschuldigung Für eine späte, aber perfekte Lösung: Wenn Sie versuchen, einen bestimmten Artikel zu entfernen, rufen Sie notifydatasetchange () auf und holen Sie sich diesen Artikel in den Bindviewholder. Entfernen Sie diesen Artikel und fügen Sie ihn erneut zum letzten Eintrag der Liste hinzu Artikel. Grundsätzlich ist das Problem aufgetreten, wenn Sie versuchen, Artikel aus der Mitte zu entfernen. Wenn Sie ein Element aus dem letzten Index entfernen, gibt es kein Recycling mehr und auch Ihre Adpteranzahl ist hoch (dies ist ein kritischer Punktabsturz, kommen Sie hierher), und der Absturz wird durch das unten stehende Code-Snippet behoben.

 holder.itemLayout.setVisibility( View.GONE );//to hide temprory it show like you have removed item

        Model current = list.get( position );
        list.remove( current );
        list.add( list.size(), current );//add agine to last index
        if(position==list.size()-1){// remove from last index
             list.remove( position );
        }
0
Irfan Ullah

Ich hatte vorher das gleiche Problem. Endlich eine Problemumgehung dafür gefunden

Ich benachrichtige den Adapter, dass das Element entfernt wurde, und benachrichtige dann, dass sich der Datensatzbereich des Adapters geändert hat

 public void setData(List<Data> dataList) {
      if (this.dataList.size() > 0) {
          notifyItemRangeRemoved(0, dataList.size());
          this.dataList.clear();
      }
      this.dataList.addAll(dataList)
      notifyItemRangeChanged(0, dataList.size());

 }
0
Cheng

Dies ist die einzige Lösung, die bei mir funktioniert hat, obwohl ich viele der oben genannten Lösungen ausprobiert habe.

1.) Intilisation

CustomAdapter scrollStockAdapter = new CustomAdapter(mActivity, new ArrayList<StockListModel>());
list.setAdapter(scrollStockAdapter);
scrollStockAdapter.updateList(stockListModels);

2.) Schreiben Sie diese Methode in den Adapter

public void updateList(List<StockListModel> list) {
stockListModels.clear();
stockListModels.addAll(list);
notifyDataSetChanged();
}

stockListModels -> Diese Liste verwenden Sie im Adapter.

0
Ramkesh Yadav

Sehr späte Antwort, aber dies kann jemandem bei der Funktion helfen.

Stellen Sie sicher, dass Ihre onStop- oder onPause-Methoden keine Ihrer Listen löschen

0
just aguy

Ich fand diese Einstellung mRecycler.setLayoutFrozen (true); in der onRefresh-Methode des swipeContainer.

löste das Problem für mich.

swipeContainer.setOnRefreshListener(new   SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            orderlistRecycler.setLayoutFrozen(true);
            loadData(false);

        }
    });
0
Mark Sheekey