RecyclerView onCreateViewHolder多次调用致应用卡顿问题求助
RecyclerView嵌套NestedScrollView时频繁触发onCreateViewHolder导致卡顿
我的RecyclerView嵌套在NestedScrollView内的复杂ViewGroup中,整体属于BottomSheet,层级结构为CoordinatorLayout -> FrameLayout -> NestedScrollView -> LinearLayout,RecyclerView上下还有其他视图。填充RecyclerView时,每个可见视图都会触发onCreateViewHolder;快速滚动时该方法也会频繁调用,导致应用卡顿。相关代码与布局如下:
适配器相关代码
private val adapter = Adapter() enum class ViewItemType(val type: Int) { DEPARTURE_ITEM(1) } abstract class AdapterItem(val type: ViewItemType) class DepartureItem( val d: Departure, ) : AdapterItem(ViewItemType.DEPARTURE_ITEM) private open inner class ItemViewHolder(root: ViewGroup): RecyclerView.ViewHolder(root) private inner class DepartureViewHolder(val root: ViewGroup): ItemViewHolder(root){ val tripIcon = root.findViewById<ImageView>(R.id.trip_icon) val tripNumber = root.findText(R.id.trip_number) val tripDirection = root.findText(R.id.trip_direction) val tripDeparture = root.findText(R.id.trip_departure) fun bind(item: DepartureItem, onClick: ()->Unit) { root.setGone() with(item.d) { root.onClick { onClick.invoke() } tripNumber.text = busNumber tripDirection.text = direction } root.setVisible() } } private inner class Adapter : RecyclerView.Adapter<ItemViewHolder>(){ var items = emptyList<DepartureItem>() override fun getItemCount() = items.size override fun getItemViewType(position: Int): Int { return items[position].type.type } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { App.log("DepartureList: onCreateViewHolder: creating item") return when(viewType){ ViewItemType.DEPARTURE_ITEM.type -> { DepartureViewHolder(( CustomResources.inflateLayout( a.layoutInflater, R.layout.departure_board_item, parent, false) as ViewGroup )) } else -> { DepartureViewHolder(( CustomResources.inflateLayout( a.layoutInflater, R.layout.departure_board_item, parent, false) as ViewGroup )) } } } override fun onBindViewHolder(vh: ItemViewHolder, position: Int) { val r = items[position] when(r.type){ ViewItemType.DEPARTURE_ITEM -> { (vh as? DepartureViewHolder)?.bind( r as DepartureItem, onClick = { onDepartureClicked.invoke(r.d) } ) } } } } private fun refreshContent(board: List<Departure>, firstLoading: Boolean = false){ if (firstLoading) progress.setProgress(true) cal.timeInMillis = System.currentTimeMillis() currMinutes = cal.get(Calendar.HOUR_OF_DAY)*60+cal.get(Calendar.MINUTE) currSeconds = cal.get(Calendar.HOUR_OF_DAY)*3600+cal.get(Calendar.MINUTE)*60+cal.get(Calendar.SECOND) val filtered = board.filter{computeMinutesToNow(currMinutes, it)>=0} val sl = filtered.sortedBy { it.realtimeDepartureInMins } fillerView.setVisibleNotGone(sl.isEmpty()) adapter.items = sl.map { DepartureItem(it) } adapter.notifyDataSetChanged() if (firstLoading) progress.setProgress(false) }
RecyclerView 初始化代码
list = findViewById<RecyclerView>(R.id.list).also { rv -> rv.isNestedScrollingEnabled = false rv.adapter = adapter rv.layoutManager = LinearLayoutManager(a) }
布局代码
<RelativeLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:clipToPadding="false" android:clipChildren="false"> <View android:id="@+id/fillerView" android:layout_width="match_parent" android:layout_height="80dp" android:visibility="gone"/> <androidx.recyclerview.widget.RecyclerView android:id="@+id/list" android:paddingTop="8dp" android:paddingBottom="8dp" android:clipToPadding="false" android:clipChildren="false" android:layout_width="match_parent" android:layout_height="match_parent"/> <components.LoadingIndicator android:id="@+id/progress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" /> </RelativeLayout>
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

