Recyclerview 变得沉重 - 跳帧

问题描述 投票:0回答:2

我有无限滚动

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()
方法中没有发生任何事情,我只是显示空布局,但在几次加载后,回收器仍然变得缓慢。

android android-recyclerview android-nestedscrollview
2个回答
4
投票

回答我自己的问题,问题是将

RecyclerView
放在
NestedScrollView
内。我需要它,因为上面有一个需要滚动的视图。我已将其删除并将其作为我的
RecyclerView
中的第一项。发生的情况是,
RecyclerView
中的物品没有被回收,因为它的高度只是在膨胀。

结论:切勿将

RecyclerView

放入

RecyclerView
    


0
投票

就我而言,问题是我试图在 recyclerview 项目绑定中设置货币金额的格式。

我通过在将数据传递到回收器视图之前格式化货币并将进程卸载到协程而不是主线程来修复它。

© www.soinside.com 2019 - 2024. All rights reserved.