Grüße, lieber Harazhiteli! Dieser Beitrag veranlasste mich, einen Artikel zu schreiben (oder besser gesagt, das Gefühl eines starken lokalen Temperaturanstiegs in der Umgebung ... hmm, unterer Rücken, der normalerweise auftritt, wenn sich jemand im Internet irrt).
Beginnen wir von vorne. Ich stimme voll und ganz zu, dass "zwischen dem Lebenszyklus der Aktivität und der Arbeit von RecyclerView etwas gemeinsam ist" - dies ist "etwas" - die Notwendigkeit zu verstehen, was wir tun und warum. Und lesen Sie die Dokumentation. Und das Versäumnis, diese beiden Notwendigkeiten zu erfüllen, wie der Traum von der Vernunft, führt zu Monstern. Nur hier, mit der Art und Weise, wie der vorherige Autor anbietet, diese Monster zu bekämpfen, stimme ich überhaupt nicht zu.
Betrachten Sie 2 Bedingungen.
Bedingung Nr. Zeiten
Wenn Sie einen Hörer irgendwo auflegen, sollten Sie ihn an einem anderen Ort trennen. Normalerweise tun sie dies in symmetrischen Funktionen - an onViewAttachedToWindow
anhängen, an onViewAttachedToWindow
entfernen. Wir hängen in onBindViewHolder
... Wir hängen nicht in onBindViewHolder
. Dieser Aufruf ist nicht symmetrisch, er kann abhängig von verschiedenen Bedingungen mehrmals aufgerufen werden. Sie müssen Ihr Leben nicht komplizieren.
Wenn Sie, wie der Autor des Originalartikels, den Gedanken haben: "Aber es gibt Fälle, in denen ... im Listener die Position des Elements in der Liste berücksichtigt werden muss, auf das in der Methode onBindViewHolder () zugegriffen werden kann und die in onViewAttachedToWindow () fehlt" , fahren Sie dies dachte nach. Sie können dies nicht tun. Auch wenn du es wirklich willst. Wie in der Dokumentation angegeben , wird diese Methode nicht aufgerufen, wenn sich nur die Position des Elements geändert hat, nicht jedoch sein Inhalt. Daher besteht die Gefahr, dass in unserem Listener die falsche Position angezeigt wird. Verwenden Sie getAdapterPosition
.
Bedingung Nummer zwei
RecyclerView
ist eine ziemlich komplizierte Sache. Sie müssen Ihr Leben nicht noch komplizierter machen. Wenn Sie nicht an der Leistungsoptimierung beteiligt sind, sollte es für Sie keine Rolle spielen, ob sich dieses Element im allgemeinen Pool befindet oder nicht.
Ergebnis
Unter diesen beiden Bedingungen ist es unwahrscheinlich, dass Sie das Rad in Form eines viewWasRecycled
Flags neu erfinden viewWasRecycled
.
Was ist los?
Was kann mit einem Element in RecyclerView
im Allgemeinen passieren? Denken Sie zunächst daran, dass es zwei „Repositorys“ gibt - Cache und Pool. Ein Element gelangt in den Cache, wenn es die Grenzen des Bildschirms überschritten hat, kann aber jederzeit wieder zurückkehren - ohne dieses Element erneut zu verknüpfen (d. H. Die onBindViewHolder
Methode wird nicht aufgerufen). Wenn der Cache voll ist oder aus einem anderen Grund, hat RecyclerView
entschieden, dass wir dieses Element in naher Zukunft nicht benötigen, es wird in den Pool onViewRecycled
(hier wird onViewRecycled
aufgerufen). Das aus dem Pool wiederhergestellte Element wird erneut verknüpft (da sich seine Position höchstwahrscheinlich geändert hat), und wir erhalten einen Aufruf von onBindViewHolder
. Wenn das Element den Pool onCreateViewHolder
, onBindViewHolder
das neue Element den gesamten Zyklus - onCreateViewHolder
, onBindViewHolder
, onViewAttachedToWindow
.
Insgesamt haben wir 3 Möglichkeiten für die Entwicklung von Veranstaltungen:
- vorher gab es kein Element: wir schaffen, wir hängen an, wir hängen an;
- Der Gegenstand befand sich im Pool: binden, anhängen;
- Das Element befand sich im Cache: Einfach anhängen.
Wo und wie?
Was und in welchen Phasen ist mit einem Element besser zu tun?
onCreateViewHolder
. Erstellen Sie, hmm, ViewHolder
. Es ist nicht erforderlich, einen Listener zu binden, ihn mit Inhalten zu füllen usw. Bestimmen Sie einfach, welchen Typ wir benötigen, und erstellen Sie ihn.onBindViewHolder
. Wir führen die eigentliche Inhaltsbindung durch - Text, Bilder. Der position
kann nur in der Methode selbst verwendet werden. Wir speichern ihn nicht, wir senden ihn nicht an die Closures. Denken Sie daran, dass diese Methode erneut aufgerufen wird, wenn sich die Daten geändert haben (und nicht, wenn sich nur die Position geändert hat). Ich würde hier auch keinen Zuhörer aufhängen - aus Gründen der Symmetrie.onViewAttachedToWindow
. Das Element wird nun auf dem Bildschirm angezeigt und der Benutzer kann damit interagieren - ein guter Moment, um einen Listener anzuhängen. Denken Sie daran, dass wenn wir die Position eines Elements darin benötigen, wir es über getAdapterPosition
.onViewDetachedFromWindow
. Das Element wird nicht auf dem Bildschirm angezeigt. Der Benutzer kann nicht mit ihm interagieren. Entfernen Sie den Listener.onViewRecycled
. Artikel wird an gesendet Hölle Pool Hier können Sie schwere Ressourcen freigeben (z. B. zwischengespeicherte Bilder). Wenn das Element wiederverwendet wird - dann höchstwahrscheinlich für eine andere Position.
Das scheint alles zu sein. Ich hoffe, ich habe nichts vergessen oder etwas durcheinander gebracht, aber wenn überhaupt, steck deine Nase, sei nicht schüchtern.