1

I facing laggy scrolling issue with complexity item. I trying to build a view like this image below. Many more item like this

I tried to #setHasStableIds #hasFixedSize #PreCacheLinearLayout #setItemViewCacheSize ... A lot of way but it still lagging. I know may be my item is too complexity but this is requirements :( If you have some ideas to resolve this problem, please help me! Thank so much <3

My adapter is multiple view type. Using Databinding, MVVM. This RecyclerView also below AppBarLayout in CoordinatorLayout.

RecyclerView:

            android:id="@+id/rvHome"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/colorGrayLight"
            android:clipToPadding="false"
            app:items="@{viewModel.listData}"
            android:nestedScrollingEnabled="true"
            android:orientation="vertical"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />

Binding Adapter:

        @BindingAdapter("items")
        fun<T> setItems(view: RecyclerView, model: ObservableArrayList<T>?) {
            model?.let {
                if(view.adapter is BaseRecyclerViewAdapter<*>){
                    (view.adapter as BaseRecyclerViewAdapter<T>).listItem  = it;
                }
            }
        }

Base Adapter:

abstract class BaseRecyclerViewAdapter<T>() :
    RecyclerView.Adapter<BindingViewHolder>() {

    var listItem: ObservableArrayList<T>? = null
        set(value) {
            value?.let {
                onSettingListItem(it);
            }
            field = value
            value?.let {
                it.addOnListChangedCallback(onListChangedCallback)
            }
            notifyDataSetChanged()
        }

    var presenter: Presenter? = null
    var decorator: Decorator? = null

    fun add(t:T){
        listItem?.let {
            it.add(t)
            notifyDataSetChanged()
        }
    }
    fun addAll(items:Collection<T>){
        Log.d("TAG","data $items")
        Log.d("TAG","data $listItem")
        listItem?.let {
            it.addAll(items)
            notifyDataSetChanged()
        }
    }
    open fun onSettingListItem(list: ObservableArrayList<T>) {

    }

    val onListChangedCallback = object : ObservableList.OnListChangedCallback<ObservableList<T>>() {
        override fun onChanged(sender: ObservableList<T>) {
            notifyDataSetChanged()
        }

        override fun onItemRangeChanged(
            sender: ObservableList<T>,
            positionStart: Int,
            itemCount: Int
        ) {
            notifyItemRangeChanged(positionStart, itemCount)
        }

        override fun onItemRangeInserted(
            sender: ObservableList<T>,
            positionStart: Int,
            itemCount: Int
        ) {
            notifyItemRangeInserted(positionStart, itemCount)
        }

        override fun onItemRangeMoved(
            sender: ObservableList<T>,
            fromPosition: Int,
            toPosition: Int,
            itemCount: Int
        ) {
            notifyItemMoved(fromPosition, toPosition)
        }

        override fun onItemRangeRemoved(
            sender: ObservableList<T>,
            positionStart: Int,
            itemCount: Int
        ) {
            notifyItemRangeRemoved(positionStart, itemCount)
        }
    }



    override fun onBindViewHolder(holder: BindingViewHolder, position: Int) {
        listItem?.let {
            val item = it[position]
            // set item variable
            holder.binding.setVariable(BR.viewModel, item)
        }
        holder.binding.setVariable(BR.presenter, presenter)
//        holder.binding.setVariable(BR.currentPos, position)
        holder.binding.executePendingBindings()
        if (decorator != null) {
            decorator!!.decorate(holder, position, getItemViewType(position))
        }
    }

    override fun getItemCount(): Int {
        listItem?.let {
            return it.size
        }
        return 0;
    }

    interface Presenter {
        fun onItemClick(view: View, item: Any, position: Int)
    }

    interface Decorator {
        fun decorate(holder: BindingViewHolder, position: Int, viewType: Int)
    }


}

Chirld Item (2):

<androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycler_view_trending_trip"
            style="@style/RecyclerHorizontalStyle"
            android:nestedScrollingEnabled="false"
            app:items="@{viewModel.data}"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
            />

And many code, but similar above. Thank you so much!

1 Answer 1

1

Hi @Duy Pls use this method.. rv.getRecycledViewPool().setMaxRecycledViews(0, 0); it may be helpful.. see this link for method description..

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks you! This is improved

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.