Mam problem ze zrozumieniem setHasFixedSize()
. Wiem, że jest używany do optymalizacji, gdy rozmiar RecyclerView
się nie zmienia, z dokumentów.
Co to jednak oznacza? W większości przypadków ListView
prawie zawsze ma stały rozmiar. W jakich przypadkach nie byłby to stały rozmiar? Czy to oznacza, że rzeczywista nieruchomość, którą zajmuje na ekranie, rośnie wraz z zawartością?
android
android-5.0-lollipop
android-recyclerview
SIr Codealot
źródło
źródło
Odpowiedzi:
Bardzo uproszczona wersja RecyclerView posiada:
Ten link opisuje, dlaczego dzwonienie
requestLayout
może być drogie. Zasadniczo za każdym razem, gdy elementy są wstawiane, przenoszone lub usuwane, rozmiar (szerokość i wysokość) RecyclerView może ulec zmianie, a z kolei rozmiar dowolnego innego widoku w hierarchii widoków może się zmienić. Jest to szczególnie kłopotliwe, jeśli elementy są często dodawane lub usuwane.Unikaj niepotrzebnych przebiegów układu, ustawiając wartość
setHasFixedSize
true, gdy zmiana zawartości adaptera nie powoduje zmiany jego wysokości ani szerokości.Aktualizacja: JavaDoc został zaktualizowany, aby lepiej opisać, co faktycznie robi metoda.
źródło
requestLayout
lub nie po zaktualizowaniu dataSet.Potwierdza, że
setHasFixedSize
odnosi się do samego RecyclerView, a nie do rozmiaru każdego dostosowanego do niego elementu.Możesz teraz używać
android:layout_height="wrap_content"
w RecyclerView, co między innymi pozwala CollapsingToolbarLayout wiedzieć, że nie powinno się zwijać, gdy RecyclerView jest pusty. Działa to tylko wtedy, gdy używaszsetHasFixedSize(false)
w RecylcerView.Jeśli używasz
setHasFixedSize(true)
w RecyclerView, to zachowanie, aby zapobiec zwijaniu CollapsingToolbarLayout, nie działa, nawet jeśli RecyclerView jest rzeczywiście pusty.Jeśli
setHasFixedSize
był związany z rozmiarem elementów, nie powinien mieć żadnego wpływu, gdy RecyclerView nie ma żadnych elementów.źródło
setHasFixedSize(true)
aby rozszerzyć się po dodaniu nowych elementów.hasFixedSize: set to true if adapter changes cannot affect the size of the RecyclerView.
więc nawet jeśli rozmiar elementu się zmieni, nadal możesz ustawić to na true.ListView miał podobną nazwaną funkcję, która moim zdaniem odzwierciedlała informacje o rozmiarze poszczególnych wysokości elementów listy. Dokumentacja RecyclerView dość wyraźnie stwierdza, że odnosi się do rozmiaru samego RecyclerView, a nie do rozmiaru jego elementów.
Z komentarza źródła RecyclerView powyżej metody setHasFixedSize ():
źródło
Wen stawiamy
setHasFixedSize(true)
naRecyclerView
tym, że środki recyklingowa na wielkość jest stała i nie zależy od zawartości karty. I w tym przypadkuonLayout
nie jest wywoływany recykler, gdy aktualizujemy dane adaptera (ale jest wyjątek).Przejdźmy do przykładu:
RecyclerView
maRecyclerViewDataObserver
( znajdź domyślną implementację w tym pliku ) z kilkoma metodami, najważniejsze to:Metoda ta nazywana jest jeśli mamy ustawiony
setHasFixedSize(true)
i aktualizować dane za pośrednictwem adaptera:notifyItemRangeChanged, notifyItemRangeInserted, notifyItemRangeRemoved or notifyItemRangeMoved
. W tym przypadku nie ma wywołań do recykleraonLayout
, ale są wezwania dorequestLayout
aktualizacji child.Ale jeśli ustawimy
setHasFixedSize(true)
i zaktualizujemy dane adaptera za pośrednictwem,notifyItemChanged
zostanieonChange
wywołane domyślneRecyclerViewDataObserver
wywołanie recyklera i nie będzie wywołańtriggerUpdateProcessor
. W tym przypadku recykleronLayout
jest wywoływany za każdym razem, gdy ustawimysetHasFixedSize
true
lubfalse
.Jak sprawdzić samodzielnie:
Utwórz własne
RecyclerView
i zastąp:Ustaw rozmiar recyklera na
match_parent
(w xml). Spróbuj zaktualizować dane adaptera za pomocąreplaceData
ireplaceOne
z ustawieniem,setHasFixedSize(true)
a następniefalse
.I sprawdź swój dziennik.
Mój dziennik:
Podsumować:
Jeśli ustawimy
setHasFixedSize(true)
i zaktualizujemy dane adaptera, powiadamiając obserwatora w inny sposób niż wywołanienotifyDataSetChanged
, masz pewną wydajność, ponieważ nie ma wywołańonLayout
metody recyklera .źródło
Jeśli mamy
RecyclerView
zmatch_parent
jak wysokość / szerokość , dodajmysetHasFixedSize(true)
od rozmiaruRecyclerView
sobie nie zmienia wstawianie lub usuwanie elementów do niego.setHasFixedSize powinny być fałszywe, jeśli mamy RecyclerView z
wrap_content
jak wysokość / szerokość od każdy element wstawiony przez adapter może zmienić wielkośćRecycler
w zależności od elementów wstawionych / usunięte, więc wielkośćRecycler
będzie inna za każdym razem Dodaj / Usuń przedmiotów.Żeby było jaśniej, jeśli używamy
Możemy użyć
my_recycler_view.setHasFixedSize(true)
Powinniśmy użyć
my_recycler_view.setHasFixedSize(false)
, dotyczy to również użyciawrap_content
jako szerokościźródło
setHasFixedSize (true) oznacza, że RecyclerView ma elementy podrzędne (elementy), które mają stałą szerokość i wysokość. Pozwala to RecyclerView na lepszą optymalizację, określając dokładną wysokość i szerokość całej listy w oparciu o adapter.
źródło
Wpływa na animacje widoku recyklingu, jeśli tak jest
false
... animacje wstawiania i usuwania nie będą wyświetlane. więc upewnij się, że jest to natrue
wypadek, gdybyś dodał animację do widoku recyklingu.źródło
Jeśli rozmiar RecyclerView (sam RecyclerView)
... nie zależy od zawartości adaptera:
... zależy od zawartości adaptera:
źródło