android - 子回收器 View 的预取 View 不起作用

标签 android kotlin android-recyclerview linearlayoutmanager

我有垂直 RecyclerView 和子(嵌套)水平 RecyclerView。 对于第二个回收器,我使用布局管理器:

LinearLayoutManager(itemView.context, LinearLayoutManager.HORIZONTAL, false).apply {
                    isItemPrefetchEnabled = true
                    initialPrefetchItemCount = 4
                }

但嵌套回收器只构建前两个可见项。

完整代码:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val recycler = findViewById<RecyclerView>(R.id.recycler)

        recycler.layoutManager = LinearLayoutManager(this)
        recycler.adapter = MainAdapter(buildElements())
    }

    private fun buildElements(): List<Parent> {
        return (0..2).map { pCount -> createParent(pCount) }
    }

    private fun createParent(index: Int): Parent {
        return Parent(text = "$index",
            list = (0..30).map { Child("item $it") }
        )
    }
}

主适配器

class MainAdapter(private val list: List<Parent>) : RecyclerView.Adapter<MainAdapter.CustomHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomHolder {
        val inflater = LayoutInflater.from(parent.context)
        return CustomHolder(inflater.inflate(R.layout.item, parent, false))
    }

    override fun getItemCount(): Int = list.size

    override fun onBindViewHolder(holder: CustomHolder, position: Int) {
        holder.bind(list[position])
    }

    class CustomHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        private val recycler = itemView.findViewById<RecyclerView>(R.id.recyclerView)
        private val title = itemView.findViewById<TextView>(R.id.title)

        init {
            recycler.layoutManager =
                LinearLayoutManager(itemView.context, LinearLayoutManager.HORIZONTAL, false).apply {
                    isItemPrefetchEnabled = true
                    initialPrefetchItemCount = 4
                }
        }

        fun bind(data: Parent) {
            title.text = data.text
            recycler.adapter = ChildAdapter(data.list)
        }
    }
}

主要回收元素

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             android:layout_width="match_parent"
             android:layout_height="wrap_content">

    <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="16dp"/>

    <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_marginTop="16dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
</FrameLayout>

子适配器

class ChildAdapter(private val list: List<Child>) : RecyclerView.Adapter<ChildAdapter.ChildHolder>() {

    companion object {
        private val TAG = ChildAdapter::class.java.simpleName
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChildHolder {
        val inflater = LayoutInflater.from(parent.context)
        return ChildHolder(inflater.inflate(R.layout.child, parent, false))
    }

    override fun getItemCount(): Int = list.size

    override fun onBindViewHolder(holder: ChildHolder, position: Int) {
        holder.bind(list[position])
    }

    class ChildHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        private val title = itemView.findViewById<TextView>(R.id.childText)
        fun bind(data: Child) {
            title.text = data.text
            Log.d(TAG, "bind child element: ${data.text}")
        }
    }
}

和子元素:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="275dp"
        android:padding="8dp"
        android:layout_height="100dp">

    <TextView
            android:id="@+id/childText"
            android:layout_width="wrap_content"
            android:layout_gravity="center"
            android:layout_height="wrap_content"/>
</FrameLayout>

在日志中只能看到这个:

D/ChildAdapter: bind child element: item 0
D/ChildAdapter: bind child element: item 1
D/ChildAdapter: bind child element: item 0
D/ChildAdapter: bind child element: item 1
D/ChildAdapter: bind child element: item 0
D/ChildAdapter: bind child element: item 1

日志意味着只构建了第一个和第二个元素,但我还想预构建第三个和第四个元素。

我也尝试使用 this , 但它也不起作用

最佳答案

预取仅适用于滚动,不适用于第一个初始项目创建。

最后我使用自定义布局管理器覆盖 getExtraLayoutSpace 并返回 100000我的解决方案有潜在危险,但我使用了它,因为我知道项目数不能超过 10 项。

关于android - 子回收器 View 的预取 View 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55473768/

相关文章:

android - RecyclerView 和 DiffUtil - 并发噩梦

java - Android 应用程序中的切换按钮

kotlin - 函数中Unit-return的目的是什么

kotlin - 为什么编译器建议将密封的子类转换为对象?

android - 加载大量图片时,Recyclerview 加载时间过长

android - OnItemClickListener 与 OnItemTouchListener

android - Exoplayer - 如何检查 MP4 视频是否有音频?

android - OkHttp 忽略日志记录拦截器

android - 每行有多个 radio 的 ListView

list - 在列表中找到2个元素并返回true kotlin?