У меня проблемы с пониманием setHasFixedSize()
. Я знаю, что он используется для оптимизации, когда размер документа RecyclerView
не меняется, из документов.
Что это значит, хотя? В большинстве общих случаев ListView
почти всегда имеет фиксированный размер. В каких случаях это не будет фиксированный размер? Означает ли это, что реальная недвижимость, которую она занимает на экране, растет вместе с контентом?
android
android-5.0-lollipop
android-recyclerview
Си Кодалот
источник
источник
Ответы:
Очень упрощенная версия RecyclerView имеет:
Эта ссылка описывает, почему звонки
requestLayout
могут быть дорогими. По сути, всякий раз, когда элементы вставляются, перемещаются или удаляются, размер (ширина и высота) RecyclerView может изменяться, и, в свою очередь, может изменяться размер любого другого представления в иерархии представлений. Это особенно неприятно, если элементы часто добавляются или удаляются.Избегайте ненужных проходов макета, установив
setHasFixedSize
значение true, если при изменении содержимого адаптера не изменяется его высота или ширина.Обновление: JavaDoc был обновлен, чтобы лучше описать, что на самом деле делает метод.
источник
requestLayout
или нет после обновления набора данных.Подтверждение может
setHasFixedSize
относится к самому RecyclerView, а не к размеру каждого элемента, адаптированного к нему.Теперь вы можете использовать
android:layout_height="wrap_content"
RecyclerView, который, помимо прочего, позволяет CollapsingToolbarLayout знать, что он не должен разрушаться, когда RecyclerView пуст. Это работает только при использованииsetHasFixedSize(false)
на RecylcerView.Если вы используете
setHasFixedSize(true)
в RecyclerView, это поведение для предотвращения свертывания CollapsingToolbarLayout не работает, даже если RecyclerView действительно пустой.Если
setHasFixedSize
это связано с размером элементов, это не должно иметь никакого эффекта, если в RecyclerView нет элементов.источник
setHasFixedSize(true)
их, чтобы они расширялись при добавлении новых элементов.hasFixedSize: set to true if adapter changes cannot affect the size of the RecyclerView.
поэтому, даже если размер элемента изменится, вы все равно можете установить для него значение true.У ListView была похожая именованная функция, которая, я думаю, отражала информацию о размере отдельных элементов списка. Документация для RecyclerView довольно четко заявляет, что это относится к размеру самого RecyclerView, а не к размеру его элементов.
Из исходного комментария RecyclerView над методом setHasFixedSize ():
источник
Вэнь мы установили
setHasFixedSize(true)
наRecyclerView
это означает , что переработчик - х размер фиксирован и не зависит от содержимого адаптера. И в этом случаеonLayout
не вызывается на утилизацию, когда мы обновляем данные адаптера (но есть исключение).Давайте перейдем к примеру:
RecyclerView
имеетRecyclerViewDataObserver
( найти реализацию по умолчанию в этом файле ) с несколькими методами, главное важно:Этот метод вызывается , если мы устанавливаем
setHasFixedSize(true)
и обновлять данные закрепительных с помощью:notifyItemRangeChanged, notifyItemRangeInserted, notifyItemRangeRemoved or notifyItemRangeMoved
. В этом случае нет обращений к переработчикуonLayout
, но есть призывы кrequestLayout
обновлению childs.Но если мы установим
setHasFixedSize(true)
и обновим данные адаптера через,notifyItemChanged
тогда вызов поonChange
умолчанию утилизатораRecyclerViewDataObserver
и никаких вызововtriggerUpdateProcessor
. В этом случае утилитаonLayout
вызывается всякий раз, когда мы устанавливаемsetHasFixedSize
true
илиfalse
.Как проверить самостоятельно:
Создать кастом
RecyclerView
и переопределить:Установите размер утилизатора
match_parent
(в xml). Попробуйте обновить данные адаптера, используяreplaceData
иreplaceOne
с настройкой,setHasFixedSize(true)
а затемfalse
.И проверь свой журнал.
Мой журнал:
Подвести итог:
Если мы установим
setHasFixedSize(true)
и обновим данные адаптера, уведомив наблюдателя каким-либо иным способом, нежели вызовnotifyDataSetChanged
, то у вас возникнет некоторая производительность, поскольку вызовыonLayout
метода повторного вызова отсутствуют .источник
Если мы имеем
RecyclerView
с ,match_parent
как высота / ширина , мы должны добавить ,setHasFixedSize(true)
так как размерRecyclerView
сам по себе не изменяет вставки или удаления элементов в него.setHasFixedSize должно быть ложным , если мы имеем RecyclerView с ,
wrap_content
как высота / ширина , так как каждый элемент вставляется адаптер может изменить размер самого вRecycler
зависимости от элементов , вставленных / удален, поэтому размерRecycler
будет отличаться каждый раз , когда мы добавить / удалить Предметы.Чтобы быть более понятным, если мы используем
Мы можем использовать
my_recycler_view.setHasFixedSize(true)
Мы должны использовать
my_recycler_view.setHasFixedSize(false)
, это относится, если мы также используем вwrap_content
качестве шириныисточник
setHasFixedSize (true) означает, что RecyclerView имеет дочерние элементы (элементы), которые имеют фиксированную ширину и высоту. Это позволяет RecyclerView лучше оптимизировать, вычисляя точную высоту и ширину всего списка на основе вашего адаптера.
источник
Это влияет на анимацию просмотра реселлера, если это
false
.. анимации вставки и удаления не будут отображаться. так что убедитесь, чтоtrue
вы добавили анимацию для просмотра реселлера.источник
Если размер RecyclerView (сам RecyclerView)
... не зависит от содержимого адаптера:
... зависит от содержимого адаптера:
источник