У меня есть переработка со сложной макетом. Это вертикальный список, в котором каждый элемент содержит вложенную переработку с GridlayoutManager. Внутренний список может иметь до 40 предметов. Кроме того, элементы внешнего списка могут содержать другие вложенные списки, но для краткости давайте сосредоточимся на основной структуре: < /p>
Внешняя вертикальная переработка < /li>
Каждый элемент содержит внутреннюю переработку с макетом сетки (до 40 элементов на внутренний список) < /li>
< /ul>
Итак далеко, я применил несколько оптимизаций для повышения производительности прокрутки: < /p>
включенные стабильные идентификаторы < /li>
Установите фиксированный размер для Recyclerview < /li>
Поделился один и тот же recycledviewpool во всех внутренних списках < /li>
< /ul>
В конце вопроса я предоставил код Образец воспроизведения моей настройки, чтобы вы могли скопировать вставить ее и запустить, если хотите. Когда список сначала появляется на экране, внешний переработка раздувает свой первый элемент. Из -за размера внутренней сетки элементы сетки полностью видны только один внешний предмет. Как и ожидалось, это раздувает 40 внутренних предметов. После этого первоначального задержки прокрутка становится совершенно плавной, потому что RecycledViewPool заполняется, уменьшая чрезмерную инфляцию. P> Я попытался использовать начальный preceTectemCount , как предложено в документации Android:
https://developer.android.com/topic/per ... outManager = GridLayoutManager(itemView.context, 4).apply {
recycleChildrenOnDetach = true
isItemPrefetchEnabled = true
initialPrefetchItemCount = 40
}
Однако это сделало прокрутку еще хуже . Из журналов я заметил, что происходят дополнительную нежелательную инфляцию. /li>
Не подходит ли предварительная аттестация для моего варианта использования? < /li>
Начальный prefetchitemcount? < /li>
Есть ли другие способы решить эту проблему и обеспечить плавную прокрутку? Будьте очень ценят!class InnerAdapter : ListAdapter(InnerDiffCallback()) {
init {
setHasStableIds(true)
}
companion object {
const val TYPE_ONE = 1
const val TYPE_TWO = 2
const val TYPE_THREE = 3
const val TYPE_FOUR = 4
}
override fun getItemId(position: Int) = getItem(position).id
override fun getItemViewType(position: Int) = when (getItem(position)) {
is InnerItemTypeOne -> TYPE_ONE
is InnerItemTypeTwo -> TYPE_TWO
is InnerItemTypeThree -> TYPE_THREE
is InnerItemTypeFour -> TYPE_FOUR
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = when (viewType) {
TYPE_ONE -> {
Log.d("inner-inflate-debug", "Inflated: InnerViewHolderTypeOne")
InnerViewHolderTypeOne(
LayoutInflater.from(parent.context).inflate(
R.layout.list_item_inner_one,
parent,
false
)
)
}
TYPE_TWO -> {
Log.d("inner-inflate-debug", "Inflated: InnerViewHolderTypeTwo")
InnerViewHolderTypeTwo(
LayoutInflater.from(parent.context)
.inflate(R.layout.list_item_inner_two, parent, false)
)
}
TYPE_THREE -> {
Log.d("inner-inflate-debug", "Inflated: InnerViewHolderTypeThree")
InnerViewHolderTypeThree(
LayoutInflater.from(parent.context)
.inflate(R.layout.list_item_inner_three, parent, false)
)
}
TYPE_FOUR -> {
Log.d("inner-inflate-debug", "Inflated: InnerViewHolderTypeFour")
InnerViewHolderTypeFour(
LayoutInflater.from(parent.context)
.inflate(R.layout.list_item_inner_four, parent, false)
)
}
else -> throw IllegalArgumentException("Invalid view type")
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val item = getItem(position)
when (holder) {
is InnerViewHolderTypeOne -> holder.bind(item as InnerItemTypeOne)
is InnerViewHolderTypeTwo -> holder.bind(item as InnerItemTypeTwo)
is InnerViewHolderTypeThree -> holder.bind(item as InnerItemTypeThree)
is InnerViewHolderTypeFour -> holder.bind(item as InnerItemTypeFour)
}
}
}
class InnerViewHolderTypeOne(view: View) : RecyclerView.ViewHolder(view) {
private val textView: MaterialTextView = view.findViewById(R.id.textView)
fun bind(item: InnerItemTypeOne) {
textView.text = "${item.id}"
}
}
class InnerViewHolderTypeTwo(view: View) : RecyclerView.ViewHolder(view) {
private val textView: MaterialTextView = view.findViewById(R.id.textView)
fun bind(item: InnerItemTypeTwo) {
textView.text = "${item.id}"
}
}
class InnerViewHolderTypeThree(view: View) : RecyclerView.ViewHolder(view) {
private val textView: MaterialTextView = view.findViewById(R.id.textView)
fun bind(item: InnerItemTypeThree) {
textView.text = "${item.id}"
}
}
class InnerViewHolderTypeFour(view: View) : RecyclerView.ViewHolder(view) {
private val textView: MaterialTextView = view.findViewById(R.id.textView)
fun bind(item: InnerItemTypeFour) {
textView.text = "${item.id}"
}
}
class InnerDiffCallback : DiffUtil.ItemCallback() {
override fun areItemsTheSame(oldItem: InnerItem, newItem: InnerItem) =
oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: InnerItem, newItem: InnerItem) =
oldItem == newItem
}
< /code>
Внешний адаптер < /p>
class OuterAdapter(
private val innerItemViewPool: RecyclerView.RecycledViewPool
) : ListAdapter(OuterDiffCallback()) {
init {
setHasStableIds(true)
}
override fun getItemId(position: Int) = getItem(position).id
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OuterViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.list_item_outer, parent, false)
return OuterViewHolder(view, innerItemViewPool)
}
override fun onBindViewHolder(holder: OuterViewHolder, position: Int) {
holder.bind(getItem(position))
}
}
< /code>
Модели: < /p>
class OuterViewHolder(
view: View,
innerItemViewPool: RecyclerView.RecycledViewPool
) : RecyclerView.ViewHolder(view) {
private val textView: TextView = view.findViewById(R.id.outerTextView)
private val innerRecyclerView: RecyclerView = view.findViewById(R.id.innerRecyclerView)
private val adapter = InnerAdapter()
init {
innerRecyclerView.layoutManager = GridLayoutManager(itemView.context, 4).apply {
recycleChildrenOnDetach = true
isItemPrefetchEnabled = true
initialPrefetchItemCount = 40
}
innerRecyclerView.adapter = adapter
innerRecyclerView.setRecycledViewPool(innerItemViewPool)
}
fun bind(outerItem: OuterItem) {
textView.text = outerItem.text
adapter.submitList(outerItem.innerItems)
}
}
class OuterDiffCallback : DiffUtil.ItemCallback() {
override fun areItemsTheSame(oldItem: OuterItem, newItem: OuterItem) = oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: OuterItem, newItem: OuterItem) = oldItem == newItem
}
< /code>
Модели < /p>
sealed interface InnerItem {
val id: Long
}
data class InnerItemTypeFour(override val id: Long) : InnerItem
data class InnerItemTypeOne(override val id: Long) : InnerItem
data class InnerItemTypeThree(override val id: Long) : InnerItem
data class InnerItemTypeTwo(override val id: Long) : InnerItem
data class OuterItem(val id: Long, val text: String, val innerItems: List)
< /code>
Activity: < /p>
class MainActivity : AppCompatActivity() {
private val innerItemViewPool = RecyclerView.RecycledViewPool().apply {
setMaxRecycledViews(InnerAdapter.TYPE_ONE, 20)
setMaxRecycledViews(InnerAdapter.TYPE_TWO, 20)
setMaxRecycledViews(InnerAdapter.TYPE_THREE, 20)
setMaxRecycledViews(InnerAdapter.TYPE_FOUR, 20)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_main)
setInsets()
val items = makeItems()
val adapter = OuterAdapter(innerItemViewPool)
val rv = findViewById(R.id.recycler)
rv.layoutManager = LinearLayoutManager(this)
rv.adapter = adapter
rv.setHasFixedSize(true)
adapter.submitList(items)
}
private fun makeItems(): MutableList {
val items = mutableListOf()
for (i in 0..99) {
val innerItems = mutableListOf()
for (j in 0..39) {
val id = (i + 1).toString() + (j + 1).toString()
val innerItem = when (j % 4) {
0 -> InnerItemTypeOne(id.toLong())
1 -> InnerItemTypeTwo(id.toLong())
2 -> InnerItemTypeThree(id.toLong())
3 -> InnerItemTypeFour(id.toLong())
else -> throw RuntimeException()
}
innerItems.add(innerItem)
}
val outerItem = OuterItem(i.toLong(), "Hey, I'm item #$i", innerItems)
items.add(outerItem)
}
return items
}
private fun setInsets() {
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
}
}
< /code>
xml Mayouts: < /p>
activity_main.xml
list_item_inner_four.xml
list_item_inner_one.xml
list_item_inner_three.xml
list_item_inner_two.xml
list_item_outer.xml
Подробнее здесь: https://stackoverflow.com/questions/794 ... lling-in-r
Не можете получить начальный preceTectemCount для работы, или как я могу оптимизировать прокрутку в Recyclerview? ⇐ Android
Форум для тех, кто программирует под Android
1740161856
Anonymous
У меня есть переработка со сложной макетом. Это вертикальный список, в котором каждый элемент содержит вложенную переработку с GridlayoutManager. Внутренний список может иметь до 40 предметов. Кроме того, элементы внешнего списка могут содержать другие вложенные списки, но для краткости давайте сосредоточимся на основной структуре: < /p>
Внешняя вертикальная переработка < /li>
Каждый элемент содержит внутреннюю переработку с макетом сетки (до 40 элементов на внутренний список) < /li>
< /ul>
Итак далеко, я применил несколько оптимизаций для повышения производительности прокрутки: < /p>
включенные стабильные идентификаторы < /li>
Установите фиксированный размер для Recyclerview < /li>
Поделился один и тот же recycledviewpool во всех внутренних списках < /li>
< /ul>
В конце вопроса я предоставил код Образец воспроизведения моей настройки, чтобы вы могли скопировать вставить ее и запустить, если хотите. Когда список сначала появляется на экране, внешний переработка раздувает свой первый элемент. Из -за размера внутренней сетки элементы сетки полностью видны только один внешний предмет. Как и ожидалось, это раздувает 40 внутренних предметов. После этого первоначального задержки прокрутка становится совершенно плавной, потому что RecycledViewPool заполняется, уменьшая чрезмерную инфляцию. P> Я попытался использовать начальный preceTectemCount , как предложено в документации Android:
https://developer.android.com/topic/performance/vitals/render#recyclerview_nestest_recyclerviewsобразнойinnerRecyclerView.layoutManager = GridLayoutManager(itemView.context, 4).apply {
recycleChildrenOnDetach = true
isItemPrefetchEnabled = true
initialPrefetchItemCount = 40
}
Однако это сделало прокрутку [b] еще хуже [/b]. Из журналов я заметил, что происходят дополнительную нежелательную инфляцию. /li>
Не подходит ли предварительная аттестация для моего варианта использования? < /li>
Начальный prefetchitemcount? < /li>
Есть ли другие способы решить эту проблему и обеспечить плавную прокрутку? Будьте очень ценят!class InnerAdapter : ListAdapter(InnerDiffCallback()) {
init {
setHasStableIds(true)
}
companion object {
const val TYPE_ONE = 1
const val TYPE_TWO = 2
const val TYPE_THREE = 3
const val TYPE_FOUR = 4
}
override fun getItemId(position: Int) = getItem(position).id
override fun getItemViewType(position: Int) = when (getItem(position)) {
is InnerItemTypeOne -> TYPE_ONE
is InnerItemTypeTwo -> TYPE_TWO
is InnerItemTypeThree -> TYPE_THREE
is InnerItemTypeFour -> TYPE_FOUR
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = when (viewType) {
TYPE_ONE -> {
Log.d("inner-inflate-debug", "Inflated: InnerViewHolderTypeOne")
InnerViewHolderTypeOne(
LayoutInflater.from(parent.context).inflate(
R.layout.list_item_inner_one,
parent,
false
)
)
}
TYPE_TWO -> {
Log.d("inner-inflate-debug", "Inflated: InnerViewHolderTypeTwo")
InnerViewHolderTypeTwo(
LayoutInflater.from(parent.context)
.inflate(R.layout.list_item_inner_two, parent, false)
)
}
TYPE_THREE -> {
Log.d("inner-inflate-debug", "Inflated: InnerViewHolderTypeThree")
InnerViewHolderTypeThree(
LayoutInflater.from(parent.context)
.inflate(R.layout.list_item_inner_three, parent, false)
)
}
TYPE_FOUR -> {
Log.d("inner-inflate-debug", "Inflated: InnerViewHolderTypeFour")
InnerViewHolderTypeFour(
LayoutInflater.from(parent.context)
.inflate(R.layout.list_item_inner_four, parent, false)
)
}
else -> throw IllegalArgumentException("Invalid view type")
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val item = getItem(position)
when (holder) {
is InnerViewHolderTypeOne -> holder.bind(item as InnerItemTypeOne)
is InnerViewHolderTypeTwo -> holder.bind(item as InnerItemTypeTwo)
is InnerViewHolderTypeThree -> holder.bind(item as InnerItemTypeThree)
is InnerViewHolderTypeFour -> holder.bind(item as InnerItemTypeFour)
}
}
}
class InnerViewHolderTypeOne(view: View) : RecyclerView.ViewHolder(view) {
private val textView: MaterialTextView = view.findViewById(R.id.textView)
fun bind(item: InnerItemTypeOne) {
textView.text = "${item.id}"
}
}
class InnerViewHolderTypeTwo(view: View) : RecyclerView.ViewHolder(view) {
private val textView: MaterialTextView = view.findViewById(R.id.textView)
fun bind(item: InnerItemTypeTwo) {
textView.text = "${item.id}"
}
}
class InnerViewHolderTypeThree(view: View) : RecyclerView.ViewHolder(view) {
private val textView: MaterialTextView = view.findViewById(R.id.textView)
fun bind(item: InnerItemTypeThree) {
textView.text = "${item.id}"
}
}
class InnerViewHolderTypeFour(view: View) : RecyclerView.ViewHolder(view) {
private val textView: MaterialTextView = view.findViewById(R.id.textView)
fun bind(item: InnerItemTypeFour) {
textView.text = "${item.id}"
}
}
class InnerDiffCallback : DiffUtil.ItemCallback() {
override fun areItemsTheSame(oldItem: InnerItem, newItem: InnerItem) =
oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: InnerItem, newItem: InnerItem) =
oldItem == newItem
}
< /code>
Внешний адаптер < /p>
class OuterAdapter(
private val innerItemViewPool: RecyclerView.RecycledViewPool
) : ListAdapter(OuterDiffCallback()) {
init {
setHasStableIds(true)
}
override fun getItemId(position: Int) = getItem(position).id
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OuterViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.list_item_outer, parent, false)
return OuterViewHolder(view, innerItemViewPool)
}
override fun onBindViewHolder(holder: OuterViewHolder, position: Int) {
holder.bind(getItem(position))
}
}
< /code>
Модели: < /p>
class OuterViewHolder(
view: View,
innerItemViewPool: RecyclerView.RecycledViewPool
) : RecyclerView.ViewHolder(view) {
private val textView: TextView = view.findViewById(R.id.outerTextView)
private val innerRecyclerView: RecyclerView = view.findViewById(R.id.innerRecyclerView)
private val adapter = InnerAdapter()
init {
innerRecyclerView.layoutManager = GridLayoutManager(itemView.context, 4).apply {
recycleChildrenOnDetach = true
isItemPrefetchEnabled = true
initialPrefetchItemCount = 40
}
innerRecyclerView.adapter = adapter
innerRecyclerView.setRecycledViewPool(innerItemViewPool)
}
fun bind(outerItem: OuterItem) {
textView.text = outerItem.text
adapter.submitList(outerItem.innerItems)
}
}
class OuterDiffCallback : DiffUtil.ItemCallback() {
override fun areItemsTheSame(oldItem: OuterItem, newItem: OuterItem) = oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: OuterItem, newItem: OuterItem) = oldItem == newItem
}
< /code>
Модели < /p>
sealed interface InnerItem {
val id: Long
}
data class InnerItemTypeFour(override val id: Long) : InnerItem
data class InnerItemTypeOne(override val id: Long) : InnerItem
data class InnerItemTypeThree(override val id: Long) : InnerItem
data class InnerItemTypeTwo(override val id: Long) : InnerItem
data class OuterItem(val id: Long, val text: String, val innerItems: List)
< /code>
Activity: < /p>
class MainActivity : AppCompatActivity() {
private val innerItemViewPool = RecyclerView.RecycledViewPool().apply {
setMaxRecycledViews(InnerAdapter.TYPE_ONE, 20)
setMaxRecycledViews(InnerAdapter.TYPE_TWO, 20)
setMaxRecycledViews(InnerAdapter.TYPE_THREE, 20)
setMaxRecycledViews(InnerAdapter.TYPE_FOUR, 20)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_main)
setInsets()
val items = makeItems()
val adapter = OuterAdapter(innerItemViewPool)
val rv = findViewById(R.id.recycler)
rv.layoutManager = LinearLayoutManager(this)
rv.adapter = adapter
rv.setHasFixedSize(true)
adapter.submitList(items)
}
private fun makeItems(): MutableList {
val items = mutableListOf()
for (i in 0..99) {
val innerItems = mutableListOf()
for (j in 0..39) {
val id = (i + 1).toString() + (j + 1).toString()
val innerItem = when (j % 4) {
0 -> InnerItemTypeOne(id.toLong())
1 -> InnerItemTypeTwo(id.toLong())
2 -> InnerItemTypeThree(id.toLong())
3 -> InnerItemTypeFour(id.toLong())
else -> throw RuntimeException()
}
innerItems.add(innerItem)
}
val outerItem = OuterItem(i.toLong(), "Hey, I'm item #$i", innerItems)
items.add(outerItem)
}
return items
}
private fun setInsets() {
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
}
}
< /code>
xml Mayouts: < /p>
activity_main.xml
list_item_inner_four.xml
list_item_inner_one.xml
list_item_inner_three.xml
list_item_inner_two.xml
list_item_outer.xml
Подробнее здесь: [url]https://stackoverflow.com/questions/79458305/cant-get-initialprefetchitemcount-to-work-or-how-can-i-optimize-scrolling-in-r[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия