当滚动到最后一个项目时,我可以无限滚动RecyclerView
并从API加载更多项目,但是经过几次滚动后,我的RecyclerView
开始滞后于添加新项目并获得
Skipped 197 frames! The application may be doing too much work on its main thread.
在日志中。我找不到导致延迟的原因。
以下是我的方法
val onLoadMore = object : IOnLoadMore {
override fun onLoadMore() {
if (!adapter.loadingMore) {
adapter.addLoadingItem()
requestSimple()
}
}
}
fun requestSimple() {
disposable = MyApplication.apiService.offerSearchWithPromo(
defaultSharedPreferences.getString(Config.PREF_LANG, Config.RU), request!!)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
adapter.removeLoadingItem()
adapter.items.addAll(it.offers.data)
if (it.promotions.data.size > 0) adapter.items.add(it.promotions.data)
adapter.notifyItemRangeInserted(adapter.items.size - it.offers.data.size - 1, it.offers.data.size)
adapter.meta = it.offers.meta
tv_found.text = resources.getString(R.string.found) + " " + adapter.meta?.pagination?.total.toString()
if (it.offers.data.size == 15) adapter.setOnLoadMoreListener(onLoadMore)
else adapter.removeListener()
request!!.page++
}, {
showError(it.message.toString())
})
}
这是我的适配器
class AdrResRvDynamic(var context: Context, nestedScrollView: NestedScrollView? = null, var items: MutableList<Any?>) : RVAdrMutableNullable<Any?, RecyclerView.ViewHolder>(items) {
var isLoading: Boolean = false
var meta: ObjMeta? = null
private var mIOnLoadMore: IOnLoadMore? = null
private val VIEW_TYPE_AUTO_SIMPLE = 0
private val VIEW_TYPE_AUTO_VIP = 1
private val VIEW_TYPE_AUTO_SUGGESTED = 2
private var VIEW_TYPE_LOADING = 99
var loadingMore: Boolean = false
var curr = ""
init {
curr = context.defaultSharedPreferences.getString(Config.PREF_CURRENCY, Config.UZS)
setHasStableIds(true)
nestedScrollView?.setOnScrollChangeListener { v: NestedScrollView, scrollX: Int, scrollY: Int, oldScrollX: Int, oldScrollY: Int ->
if (v.getChildAt(v.childCount - 1) != null) {
isLoading = if (scrollY >= v.getChildAt(v.childCount - 1).measuredHeight - v.measuredHeight && scrollY > oldScrollY) {
if (mIOnLoadMore != null) mIOnLoadMore!!.onLoadMore()
true
} else false
}
}
}
fun setOnLoadMoreListener(mIOnLoadMore: IOnLoadMore) {
this.mIOnLoadMore = mIOnLoadMore
}
fun removeListener() {
this.mIOnLoadMore = null
}
override fun getItemViewType(position: Int): Int {
return when {
items[position] == null -> VIEW_TYPE_LOADING
items[position]!!::class.simpleName == "ObjAuto" -> VIEW_TYPE_AUTO_SIMPLE
items[position]!!::class.simpleName == "ObjAutoVip" -> VIEW_TYPE_AUTO_VIP
items[position] is List<*> -> VIEW_TYPE_AUTO_SUGGESTED
else -> VIEW_TYPE_LOADING
}
}
@Suppress("UNCHECKED_CAST")
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val obj = items[position]
when (holder) {
is ItemViewAutoCard -> holder.bind(obj!! as ObjAuto)
is ItemViewAutoCardSUGGESTED -> holder.bind(obj!! as List<ObjAuto>)
is ItemViewAutoCardVIP -> holder.bind(obj!! as ObjAutoVip)
is ItemViewLoadingMore -> {
// holder.itemView.find<ProgressBar>(R.id.progressBar1).isIndeterminate = true
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
VIEW_TYPE_AUTO_SIMPLE -> ItemViewAutoCard(context, LayoutInflater.from(parent.context).inflate(R.layout.li_auto_card, parent, false))
VIEW_TYPE_AUTO_VIP -> ItemViewAutoCardVIP(context, LayoutInflater.from(parent.context).inflate(R.layout.li_auto_card_vip, parent, false))
VIEW_TYPE_AUTO_SUGGESTED -> ItemViewAutoCardSUGGESTED(context, LayoutInflater.from(parent.context).inflate(R.layout.li_auto_card_suggested, parent, false))
else -> ItemViewLoadingMore(LayoutInflater.from(parent.context).inflate(R.layout.progress_bar_load_more, parent, false))
}
}
override fun getItemCount(): Int {
return items.size
}
fun removeLoadingItem() {
loadingMore = false
if (items.size == 0) return
items.removeAt(items.size - 1)
notifyItemRemoved(items.size)
}
fun addLoadingItem() {
loadingMore = true
items.add(null)
notifyItemInserted(items.size - 1)
}
override fun onViewRecycled(holder: RecyclerView.ViewHolder) {
super.onViewRecycled(holder)
}
}
PS:我已经注释掉了ItemViews内部的所有逻辑,因此onBind()
方法没有任何反应,我只是显示空布局,但是在多次加载之后,回收站仍然变得滞后。
答案 0 :(得分:0)
回答我自己的问题,问题是将RecyclerView
放在NestedScrollView
内。我需要它是因为RecyclerView
上方有一个需要滚动的视图。我已将其删除,并将其作为第一项放在我的RecyclerView
中。发生的是,RecyclerView
中的项目由于高度不断扩大而没有被回收。
判决:切勿将RecyclerView
放在NestedScrollView
内