Не можете получить начальный preceTectemCount для работы, или как я могу оптимизировать прокрутку в Recyclerview?Android

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Не можете получить начальный preceTectemCount для работы, или как я могу оптимизировать прокрутку в Recyclerview?

Сообщение 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/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
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»