簡體   English   中英

Android RecyclerView 不回收項目

[英]Android RecyclerView doesn't recycle items

我有一個recyclerView有多個recyclerView動態通貨膨脹,我的反應

我從服務器得到的是一個包含對象的列表,每個對象都包含一個列表和屬性

recyclerView類型( VerticalHorizontal )線性布局。

一切正常,除了當方向為垂直時,適配器等待一次加載所有視圖(停止回收)。

我進行了很多搜索以找到解決方案,但一無所獲。

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>

home_single_item 布局(包含 2 個TextViewRecyclerView

<?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>

主頁RecyclerViewonBindViewHolder

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 ,因此無法為這種情況啟用回收。 當它的水平時,回收正在工作,因為它的widthmatch_parent並且屏幕寬度是固定的。 回收只有在定義了高度時才有效!

但是,正如我所說,還有優化的空間:

現在,您正在為父 RV 的onBindViewHolder()方法中的內部RV創建適配器,因此每次RV決定通過重新綁定新值重用它以前的ViewHolders時,都會強制內部RV膨脹ViewHolders

您可以在RVonCreateVoewHolder()內部為內部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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM