Recyclerview变得沉重

时间:2019-02-07 12:46:10

标签: android android-recyclerview recycler-adapter android-nestedscrollview

当滚动到最后一个项目时,我可以无限滚动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()方法没有任何反应,我只是显示空布局,但是在多次加载之后,回收站仍然变得滞后。

1 个答案:

答案 0 :(得分:0)

回答我自己的问题,问题是将RecyclerView放在NestedScrollView内。我需要它是因为RecyclerView上方有一个需要滚动的视图。我已将其删除,并将其作为第一项放在我的RecyclerView中。发生的是,RecyclerView中的项目由于高度不断扩大而没有被回收。

判决:切勿将RecyclerView放在NestedScrollView