我已经使用RecyclerView
和GridLayoutManager
实现了adpter
,其中包含具有不同高度的不同viewholders
的多种商品类型。
不幸的是,RecyclerView
在滚动时滞后。我观察到了这种行为:
我认为不同的高度是造成此问题的原因,并且我尝试了许多不同的方法。其中包括:
设置setHasStableIds(true)并在适配器中实现:
重写fun getItemId(position:Int):长{ 返回position.toLong()}
在onBindViewHolder
中什么都不做,仅依赖于xml布局中定义的视图持有者中的静态内容
LinearLayout
(等)。我将尝试为您提供代码的相关部分。
因此,首先,这是我屏幕上带有recyclerview的xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/customersRecyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="50dp"
android:paddingBottom="50dp"
android:layout_weight="1"
android:clipToPadding="false">
</android.support.v7.widget.RecyclerView>
</FrameLayout>
以下是用于创建适配器的代码:
var columns = if (isBigScreen && isLandscape) 6
else if (isBigScreen) 5
else if (isLandscape) 4
else 3
val gridLayoutManager = GridLayoutManager(context, columns, GridLayoutManager.VERTICAL, false)
mCustomersRecyclerview?.layoutManager = gridLayoutManager
mCustomersAdapter = CustomersAdapter(customersListItems, gridLayoutManager, columns)
mCustomersRecyclerview?.adapter = mCustomersAdapter
以及适配器构造函数:
constructor(items: ArrayList<ListItem> = ArrayList(), layoutManager: GridLayoutManager, spanSize: Int) {
mItems = items
mSpanSize = spanSize
mLayoutManager = layoutManager
setHasStableIds(true)
mLayoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
when (getItemViewType(position)) {
ItemType.HEADLINE_PRIMARY.index,
ItemType.HEADLINE_SECONDARY.index -> {
return spanSize
}
}
return 1
}
}
}
还有一个标题查看器的示例,它使用跨度来完全覆盖列表中的宽度:
onCreateViewHolder(...)的一部分
when (viewType) {
ItemType.HEADLINE_PRIMARY.index -> {
layoutView = prepareViewHolder(parent, R.layout.customers_list_item_headline_primary, false)
if (layoutView != null) {
viewholder = HeadlinePrimaryViewHolder(layoutView)
}
}
还有onBindViewHolder(...)
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val item = mItems.get(position)
if (holder is HeadlinePrimaryViewHolder && item is HeadlinePrimaryListItem) {
holder.bind(item)
以及观看者本身
class HeadlinePrimaryViewHolder: RecyclerView.ViewHolder {
private var mCustomersPrimaryHeadline: MTTextView? = null
constructor(view: View?) : super(view) {
mCustomersPrimaryHeadline = view as MTTextView
}
fun bind(itemPrimary: HeadlinePrimaryListItem) {
var headline: String = itemPrimary.headline
mCustomersPrimaryHeadline?.setText(headline)
}
}
(此查看器的XML是简单的文本视图,仅此而已)
它在何时平滑滚动。
除标题外,其他视口仅使用1列(1个跨度),外观不同,高度也如上所述。
对性能产生正面影响的唯一事情是使用相同的项目/视图,或者在整个列表中至少使用具有相同高度的项目。不论是否设置setHasFixedSize(true)
。我使用哪种物品类型都没有关系,只要它们一直向下具有相同的高度即可。
但这不是我的选择,因为我需要为定制商品设置不同高度的商品。