Reputation: 2809
I have A recyclerView
that have multiple recyclerView
with a dynamic inflation, the response I
am getting from the server is a list that contains objects each one contains a list and attributes for the
recyclerView
type (Vertical
or Horizontal
) LinearLayout.
everything works fine except that when the orienatation is Vertical the adapter wait to load all Views at once (stop recycling).
I have searched a lot to find a solution but nothing.
RecyclerView
inside HomeFragment
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.gt.gcook.ui.home.HomeFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="vertical"
android:nestedScrollingEnabled="false"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:listitem="@layout/home_single_item" />
</androidx.constraintlayout.widget.ConstraintLayout>
TextView
and RecyclerView
)<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/seeAllTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:layout_marginEnd="24dp"
android:text="See all"
android:textColor="@color/color_yellow"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/titleTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="32dp"
android:text="Catigories"
android:textColor="#707070"
android:textSize="22sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:nestedScrollingEnabled="false"
app:reverseLayout="false"
android:clipToPadding="false"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/titleTV" />
</androidx.constraintlayout.widget.ConstraintLayout>
onBindViewHolder
of Home RecyclerView
.override fun onBindViewHolder(holder: ViewHolder, position: Int) {
when (position) {
0 -> {
holder.itemView.titleTV.text = "Categories"
val mLayoutManager = LinearLayoutManager(holder.itemView.context)
mLayoutManager.orientation = RecyclerView.HORIZONTAL
holder.itemView.recyclerView.layoutManager = mLayoutManager
holder.itemView.recyclerView.adapter = HomeCategoryAdapter()
}
1 -> { //here is the problem when Orintation is vertical.
holder.itemView.titleTV.text = "Most rated recipes"
val mLayoutManager = GridLayoutManager(holder.itemView.context, 2)
mLayoutManager.orientation = RecyclerView.VERTICAL
holder.itemView.recyclerView.layoutManager = mLayoutManager
holder.itemView.recyclerView.adapter = MostRatedRecipeAdapter(clickListener)
}
else -> {
holder.itemView.titleTV.text = "Favourite"
val mLayoutManager = LinearLayoutManager(holder.itemView.context)
mLayoutManager.orientation = RecyclerView.HORIZONTAL
holder.itemView.recyclerView.layoutManager = mLayoutManager
holder.itemView.recyclerView.adapter = HomeCategoryAdapter()
}
}
}
Upvotes: 4
Views: 1756
Reputation: 1245
Since your inner RV
's height is set to wrap_content
there is no way to enable recycling for that case. When its horizontal, recycling is working because it's width
is match_parent
and screen width is fixed. Recycling works only when there is defined height!
However, as i said there is room for optimization:
Right now, you are creating adapter for inner RV
inside parent RV's onBindViewHolder()
method, thus forcing inner RV
to inflate ViewHolders
every time parent RV
decides to reuse it's previous ViewHolders
via rebinding new values.
You can create adapters for inner RV
inside onCreateVoewHolder()
of parent RV
and submit new list to inner adapter ( subsequently calling notifyDatasetChanged()
) inside OnBindViewHolder()
.
The above approach should certainly improve performance, at least on subsequent scrolling: recycling will work on parent RV
scroll, meaning inner RV
will retain its ViewHolders
and reuse them to some degree.
Unfortunately, i don't have time to post snippet precisely for your scenario but you can have a look at my another answer: Show values of same key in one TextView in Recyclerview
Upvotes: 5