Reputation: 53
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!
Upvotes: 1
Views: 103
Reputation: 364
Hi @Duy Pls use this method.. rv.getRecycledViewPool().setMaxRecycledViews(0, 0); it may be helpful.. see this link for method description..
Upvotes: 1