[英]Android RecyclerView doesn't recycle items
我有一個recyclerView
有多個recyclerView
動態通貨膨脹,我的反應
我從服務器得到的是一個包含對象的列表,每個對象都包含一個列表和屬性
recyclerView
類型( Vertical
或Horizontal
)線性布局。
一切正常,除了當方向為垂直時,適配器等待一次加載所有視圖(停止回收)。
我進行了很多搜索以找到解決方案,但一無所獲。
HomeFragment
中的 Main RecyclerView
<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
和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>
RecyclerView
的onBindViewHolder
。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()
}
}
}
由於您的內部RV
的高度設置為wrap_content
,因此無法為這種情況啟用回收。 當它的水平時,回收正在工作,因為它的width
是match_parent
並且屏幕寬度是固定的。 回收只有在定義了高度時才有效!
但是,正如我所說,還有優化的空間:
現在,您正在為父 RV 的onBindViewHolder()
方法中的內部RV
創建適配器,因此每次父RV
決定通過重新綁定新值重用它以前的ViewHolders
時,都會強制內部RV
膨脹ViewHolders
。
您可以在父RV
的onCreateVoewHolder()
內部為內部RV
創建適配器,並在 OnBindViewHolder() 內部向內部適配器提交新列表(隨后調用notifyDatasetChanged()
OnBindViewHolder()
。
上述方法肯定會提高性能,至少在后續滾動中是這樣:回收將在父RV
滾動上起作用,這意味着內部RV
將保留其ViewHolders
並在一定程度上重用它們。
不幸的是,我沒有時間為您的場景准確地發布代碼片段,但您可以看看我的另一個答案: Show values of same key in one TextView in Recyclerview
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.