Android RecyclerView: notifyDataSetChanged () IllegalStateException
Ich versuche zu aktualisieren, die Elemente einer recycleview mit notifyDataSetChanged().
Dies ist mein onBindViewHolder () - Methode in der recycleview adapter.
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
//checkbox view listener
viewHolder.getCheckbox().setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//update list items
notifyDataSetChanged();
}
});
}
Was ich will zu tun ist, aktualisieren Sie die Liste posten, nachdem ich eine checkbox. Ich bekomme eine illegale Ausnahme jedoch: "Cannot call this method while RecyclerView is computing a layout or scrolling"
java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling
at android.support.v7.widget.RecyclerView.assertNotInLayoutOrScroll(RecyclerView.java:1462)
at android.support.v7.widget.RecyclerView$RecyclerViewDataObserver.onChanged(RecyclerView.java:2982)
at android.support.v7.widget.RecyclerView$AdapterDataObservable.notifyChanged(RecyclerView.java:7493)
at android.support.v7.widget.RecyclerView$Adapter.notifyDataSetChanged(RecyclerView.java:4338)
at com.app.myapp.screens.RecycleAdapter.onRowSelect(RecycleAdapter.java:111)
Ich auch notifyItemChanged(), gleiche Ausnahme. Irgendeine geheime Art und Weise zu aktualisieren, informieren Sie den adapter, dass etwas geändert?
InformationsquelleAutor der Frage Arthur | 2014-11-21
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sollten Sie die move-Methode 'setOnCheckedChangeListener()' ViewHolder die innere Klasse auf Ihrem adapter.
onBindViewHolder()
ist keine Methode, die die InitialisierungViewHolder
.Diese Methode ist der zweite Schritt der Aktualisierung jeder recycler Element.
Wenn Sie anrufen
notifyDataSetChanged()
,onBindViewHolder()
aufgerufen wird, wenn die Anzahl der jedes Element mal.Also, Wenn Sie
notifyDataSetChanged()
inonCheckChanged()
und initialisieren Sie das Kontrollkästchen inonBindViewHolder()
erhalten Sie IllegalStateException, weil der zirkulären Methode aufrufen.aktivieren Sie die checkbox -> onCheckedChanged() -> notifyDataSetChanged() -> onBindViewHolder() -> checkbox markieren -> onChecked...
Einfach, Sie können dieses Problem beheben, durch das setzen einer Flagge in-Adapter.
versuchen, diese,
InformationsquelleAutor der Antwort Moonsoo Jeong
Mit einem
Handler
für das hinzufügen von Elementen und den Aufrufnotify...()
aus diesemHandler
behoben das Problem für mich.InformationsquelleAutor der Antwort cybergen
Können Sie nur setzen Sie die früheren Hörer, bevor Sie änderungen vornehmen, und Sie werden nicht diese Ausnahme.
InformationsquelleAutor der Antwort JoniDS
Weiß ich nicht, aber ich hatte auch das gleiche problem. Ich löste dies durch die Verwendung
onClickListner
aufcheckbox
Versuchen, diese, dies kann helfen!
InformationsquelleAutor der Antwort jigar
InformationsquelleAutor der Antwort bruce
Fand eine einfache Lösung -
Hier erstellen wir ein runnable zu notifyItemChanged für eine position bei der recyclerview ist bereit, es zu handhaben.
InformationsquelleAutor der Antwort Rohan Kandwal
Wenn Sie die Meldung Error:
Einfach, Nur tun, was die Ursache der Ausnahme:
InformationsquelleAutor der Antwort Antoine Draune
Zuerst dachte ich, Moonsoo Antwort (die akzeptierte Antwort) würde nicht funktionieren für mich, denn ich kann nicht initialisiert werden meine
setOnCheckedChangeListener()
im ViewHolder-Konstruktor, weil ich zu binden, müssen Sie es jedes mal, so wird es eine aktualisierte position variabel. Aber es dauerte eine lange Zeit, um zu realisieren, was er sagte.Hier ist ein Beispiel für die "Kreis-Methode aufrufen," er redet:
Das einzige problem mit diesem ist, dass, wenn wir Sie brauchen zum initialisieren der Schalter ein-oder ausgeschaltet (vom letzten gespeicherten Zustand, zum Beispiel), es ruft die Zuhörer, die nennen könnte
nofityItemRangeChanged
fordertonBindViewHolder
wieder. Sie kann nicht rufenonBindViewHolder
wenn Sie bereits inonBindViewHolder
], weil Sie nichtnotifyItemRangeChanged
wenn Sie bereits in der Mitte der Benachrichtigung, dass der Artikel-Reihe hat sich geändert. Aber ich brauchte nur die Aktualisierung der Benutzeroberfläche, um zu zeigen oder zu deaktivieren, die nicht wollen, um tatsächlich etwas auslösen.Hier ist die Lösung, die ich gelernt, aus JoniDS Antwortdass die Endlosschleife. Solange wir legen den Hörer auf "null", bevor wir Überprüft, dann wird es die Aktualisierung der Benutzeroberfläche, ohne dass die Zuhörer, die Vermeidung der Endlosschleife. Dann können wir die Zuhörer nach.
JoniDS code:
Vollständige Lösung zu meinem Beispiel:
InformationsquelleAutor der Antwort Rock Lee
Ihre CheckBox-Element in wechselnden drawable, wenn Sie anrufen
notifyDataSetChanged();
also diese Ausnahme würde aufgetreten sein.Aufruf versuchen
notifyDataSetChanged();
im post von Ihrer Ansicht. Zum Beispiel:InformationsquelleAutor der Antwort Mohammad Reza Norouzi
Während Element gebunden wird, durch den layout-manager, ist es sehr wahrscheinlich, dass Sie der gecheckte Status des Kontrollkästchens, denen ist die Auslösung der Rückruf.
Dies ist natürlich nur eine Vermutung, weil Sie nicht veröffentlichen, das volle stack-trace.
Können Sie nicht ändern-adapter Inhalt, während RV Neuberechnung des Layouts. Sie können dies vermeiden, indem nicht aufrufen notifyDataSetChanged, wenn item ausgewählt ist-Zustand ist gleich dem Wert gesendet der Rückruf (das wird der Fall sein, wenn der Aufruf
checkbox.setChecked
ist die Auslösung der callback).InformationsquelleAutor der Antwort yigit
Verwenden onClickListner auf das Kontrollkästchen statt OnCheckedChangeListener, Es wird das problem lösen
InformationsquelleAutor der Antwort Krishan Kumar Mourya
Bevor
notifyDataSetChanged()
einfach überprüfen, ob mit dieser Methode:recyclerView.IsComputingLayout()
InformationsquelleAutor der Antwort Amir Hossein Ghasemi
Einfache Nutzung Post:
InformationsquelleAutor der Antwort Kai Wang
Lief ich in genau dieses Problem! Nach Moonsoo die Antwort nicht wirklich zu schwimmen, mein Boot, ich verwirrte Sie ein bisschen herum und fand eine Lösung, die für mich gearbeitet.
Erste, hier sind einige meiner code:
Sie werden bemerken, ich bin insbesondere die Benachrichtigung der adapter für die position, die ich ändern bin, anstatt den gesamten Datenbestand wie du tust. , Die being said, obwohl ich nicht garantieren kann, wird dies für Sie arbeiten, ich habe das problem gelöst, indem er meine
notifyItemChanged()
Aufruf in einen try/catch-block. Diese einfach gefangen die Ausnahme, aber immer noch erlaubt, meinen adapter zu registrieren, den Zustand zu ändern, und aktualisieren Sie die Anzeige!Hoffe, das jemand hilft!
EDIT: ich gebe zu, dies ist wahrscheinlich nicht die richtige/Reife Art, behandeln das Thema, aber da es scheint nicht zu sein, der verursacht keine Probleme, indem man die Ausnahme nicht behandelte, ich dachte, ich würde teilen, falls es gut genug für jemand anderes.
InformationsquelleAutor der Antwort Andrew
Dies geschieht, weil Sie wahrscheinlich die Einstellung der "Zuhörer" vor der Konfiguration der Wert für die Zeile, die macht der listener ausgelöst werden, wenn Sie " konfigurieren Sie den Wert für das Kontrollkästchen.
Was Sie tun müssen, ist:
InformationsquelleAutor der Antwort Alécio Carvalho
Warum nicht überprüfung der
RecyclerView.isComputingLayout()
Zustand wie folgt?InformationsquelleAutor der Antwort NcJie
InformationsquelleAutor der Antwort jayendrasinh vaghela
Für mich, ich hörte zu ändern, in der Bewertung der rating-bar, aber auf lange drücken der mehrere Klicks auf einmal app stürzt ab wegen dem Thema, dann eine klare Lösung, wenn ich wollte notifydatasetchange(); in bindviewholder behandelt es mit handler gegeben durch:
Hoffe, so wird es das Problem zu beheben.
InformationsquelleAutor der Antwort Ali Nawaz
Achtung! Diese Ausnahme wahrscheinlich Signale, die Sie aktualisieren, ist ein adapter nicht aus UI-thread! Zum Beispiel, füllen Sie adapter aus RxJava und vergaß hinzuzufügen
.observeOn(AndroidSchedulers.mainThread())
.Wenn Sie sicher sind, dass Sie nicht finden, eine Lösung auf Kotlin
(Dank an @bruce:
InformationsquelleAutor der Antwort CoolMind
verwenden DiffUtil statt um bessere Leistung zu erhalten
InformationsquelleAutor der Antwort Zafer Celaloglu