子回收器视图的预取视图不起作用
Prefetching view for child recycler view is not working
我有垂直 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
和 return 100000
。 我的解决方案有潜在危险,但我使用它,因为我知道项目数不能超过 10 项。
我有垂直 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
和 return 100000
。 我的解决方案有潜在危险,但我使用它,因为我知道项目数不能超过 10 项。