Ich habe Probleme beim Verstehen setHasFixedSize()
. Ich weiß, dass es zur Optimierung verwendet wird, wenn sich die Größe von RecyclerView
aus den Dokumenten nicht ändert.
Was bedeutet das aber? In den meisten Fällen hat ein ListView
fast immer eine feste Größe. In welchen Fällen wäre es keine feste Größe? Bedeutet dies, dass die tatsächliche Fläche, die es auf dem Bildschirm einnimmt, mit dem Inhalt wächst?
android
android-5.0-lollipop
android-recyclerview
SIr Codealot
quelle
quelle
Antworten:
Eine sehr vereinfachte Version von RecyclerView hat:
Dieser Link beschreibt, warum Anrufe
requestLayout
teuer sein können. Grundsätzlich kann sich beim Einfügen, Verschieben oder Entfernen von Elementen die Größe (Breite und Höhe) von RecyclerView ändern, und wiederum kann sich die Größe jeder anderen Ansicht in der Ansichtshierarchie ändern. Dies ist besonders problematisch, wenn Elemente häufig hinzugefügt oder entfernt werden.Vermeiden Sie unnötige Layoutdurchläufe, indem Sie
setHasFixedSize
auf true setzen, wenn Sie den Inhalt des Adapters ändern, ohne dessen Höhe oder Breite zu ändern.Update: Die JavaDoc wurde aktualisiert, um besser zu beschreiben , was die Methode tatsächlich der Fall ist.
quelle
requestLayout
nach Aktualisierung des dataSet aufzurufen oder nicht.Kann bestätigen,
setHasFixedSize
bezieht sich auf die RecyclerView selbst und nicht auf die Größe jedes daran angepassten Elements.Sie können jetzt
android:layout_height="wrap_content"
eine RecyclerView verwenden, mit der unter anderem ein CollapsingToolbarLayout erkennt , dass es nicht kollabieren sollte, wenn die RecyclerView leer ist. Dies funktioniert nur, wenn Sie essetHasFixedSize(false)
in RecylcerView verwenden.Wenn Sie
setHasFixedSize(true)
RecyclerView verwenden, funktioniert dieses Verhalten, um zu verhindern, dass das CollapsingToolbarLayout zusammenbricht, nicht, obwohl das RecyclerView tatsächlich leer ist.Wenn dies
setHasFixedSize
mit der Größe der Elemente zusammenhängt, sollte dies keine Auswirkungen haben, wenn die RecyclerView keine Elemente enthält.quelle
setHasFixedSize(true)
, damit sie beim Hinzufügen neuer Elemente erweitert werden.hasFixedSize: set to true if adapter changes cannot affect the size of the RecyclerView.
Auch wenn sich die Größe des Elements ändert, können Sie dies auf true setzen.Die ListView hatte eine ähnlich benannte Funktion, die meiner Meinung nach Informationen über die Größe der einzelnen Listenelementhöhen widerspiegelte. In der Dokumentation zu RecyclerView wird ziemlich deutlich angegeben, dass es sich auf die Größe des RecyclerView selbst bezieht, nicht auf die Größe seiner Elemente.
Aus dem RecyclerView-Quellkommentar über der setHasFixedSize () -Methode:
quelle
Wen wir setzen
setHasFixedSize(true)
auf ,RecyclerView
dass Mittel Recycler eine feste Größe ist und nicht durch den Adapter Inhalt betroffen. In diesem FallonLayout
wird der Recycler nicht aufgerufen, wenn die Daten des Adapters aktualisiert werden (es gibt jedoch eine Ausnahme).Gehen wir zum Beispiel:
RecyclerView
hat eineRecyclerViewDataObserver
( Standardimplementierung in dieser Datei finden ) mit mehreren Methoden, die wichtigste ist:Diese Methode wird aufgerufen, wenn wir
setHasFixedSize(true)
die Daten eines Adapters über Folgendes festlegen und aktualisieren :notifyItemRangeChanged, notifyItemRangeInserted, notifyItemRangeRemoved or notifyItemRangeMoved
. In diesem Fall gibt es keine Anrufe beim RecycleronLayout
, aber AnruferequestLayout
beim Aktualisieren von Kindern.Wenn wir jedoch
setHasFixedSize(true)
die Daten eines Adapters über einstellen und aktualisieren,notifyItemChanged
wirdonChange
die Standardeinstellung des Recyclers aufgerufenRecyclerViewDataObserver
und keine aufgerufentriggerUpdateProcessor
. In diesem Fall wird der RecycleronLayout
immer dann aufgerufen, wenn wirsetHasFixedSize
true
oder einstellenfalse
.So überprüfen Sie selbst:
Benutzerdefiniert erstellen
RecyclerView
und überschreiben:Stellen Sie die Größe des Recyclers auf
match_parent
(in xml). Versuchen Sie, die Daten des Adapters mitreplaceData
undreplaceOne
mit der EinstellungsetHasFixedSize(true)
und dann zu aktualisierenfalse
.Und überprüfen Sie Ihr Protokoll.
Mein Log:
Zusammenfassen:
Wenn wir die Adapterdaten so einstellen
setHasFixedSize(true)
und aktualisieren, dass ein Beobachter auf eine andere Weise als durch Aufrufen benachrichtigt wirdnotifyDataSetChanged
, haben Sie eine gewisse Leistung, da dies keine Aufrufe der Recycler-onLayout
Methode sind.quelle
Wenn wir ein
RecyclerView
mitmatch_parent
als Höhe / Breite haben , sollten wir hinzufügen,setHasFixedSize(true)
da die Größe desRecyclerView
selbst das Einfügen oder Löschen von Elementen nicht ändert.setHasFixedSize sollte falsch sein , wenn wir einen RecyclerView mit haben
wrap_content
als Höhe / Breite , da jedes Element durch den Adapter eingeführt könnte die Größe der ÄnderungRecycler
auf den eingefügten Elementen abhängig / gelöscht, so wird die Größe desRecycler
anders sein wird jedes Mal , wenn wir hinzufügen / löschen Artikel.Um klarer zu sein, wenn wir verwenden
Wir können benutzen
my_recycler_view.setHasFixedSize(true)
Wir sollten verwenden
my_recycler_view.setHasFixedSize(false)
, dies gilt, wenn wir auchwrap_content
als Breite verwendenquelle
setHasFixedSize (true) bedeutet, dass RecyclerView untergeordnete Elemente (Elemente) mit fester Breite und Höhe hat. Auf diese Weise kann RecyclerView besser optimieren, indem die genaue Höhe und Breite der gesamten Liste anhand Ihres Adapters ermittelt wird.
quelle
Dies wirkt sich auf die Animationen der Recycling-Ansicht aus, wenn dies der Fall ist
false
. Die Animationen zum Einfügen und Entfernen werden nicht angezeigt. Stellen Sie daher sicher, dasstrue
Sie eine Animation für die Recyclingansicht hinzugefügt haben.quelle
Wenn die Größe der RecyclerView (die RecyclerView selbst)
... hängt nicht vom Adapterinhalt ab:
... hängt vom Adapterinhalt ab:
quelle