简体   繁体   English

Recyclerview 中的 Recyclerview 滚动第一次滞后

[英]Recyclerview in Recyclerview scrolling first time laggy

I have Recyclerview multiple view types and have Recyclerview in Recyclerview when scroll lag first time I do not know why scroll lag first time我有 Recyclerview 多种视图类型,并且在第一次滚动滞后时在 Recyclerview 中有 Recyclerview 我不知道为什么第一次滚动滞后

here my layout fragment这是我的布局片段

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:id="@+id/coordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".presentation.LottoFragment">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/teal_700"
        android:padding="20dp">

        <LinearLayout
            android:id="@+id/searchLinearLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <com.google.android.material.textfield.TextInputLayout
                android:id="@+id/menuTextInputLayout"
                style="@style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/label">

                <AutoCompleteTextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:inputType="none" />

            </com.google.android.material.textfield.TextInputLayout>

        </LinearLayout>

    </androidx.constraintlayout.widget.ConstraintLayout>

    <LinearLayout
        android:id="@+id/contentLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:behavior_peekHeight="56dp"
        app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/ic_list_header_background"
            android:clickable="true"
            android:elevation="4dp"
            android:orientation="horizontal"
            android:padding="20dp">

            <TextView
                android:id="@+id/lotto_text_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:fontFamily="@font/kanit_light"
                android:text="0 items(s)" />

            <ImageView
                android:id="@+id/filterIcon"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="end"
                android:src="@android:drawable/arrow_up_float"
                android:visibility="gone" />

        </LinearLayout>

        <LinearLayout
            android:id="@+id/front_layer_linear_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@android:color/white"
            android:orientation="vertical">

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/lotto_recycler_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:clipToPadding="false"
                android:paddingBottom="64dp"
                tools:itemCount="3"
                tools:listitem="@layout/item_lotto_prizes_one" />

        </LinearLayout>
    </LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

here my fragment这是我的片段

 lottoRecyclerView.apply {
            layoutManager = LinearLayoutManager(context)
            adapter = lottoLatestAdapter
        }

here my Adapter:这是我的适配器:

class LottoLatestAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    companion object {
        private const val VIEW_TYPE_LOTTO_PRIZE_ONE = 1
        private const val VIEW_TYPE_LOTTO_PRIZE_RUNNING_NUMBER = 2
        private const val VIEW_TYPE_LOTTO_PRIZE_ONE_NEAR = 3
        private const val VIEW_TYPE_LOTTO_PRIZE_OTHER = 4
    }
    var latestList: MutableList<LottoPrizesLatestModel> = mutableListOf()
        set(value) {
            field = value
            notifyDataSetChanged()
        }

    private val viewPool : RecycledViewPool = RecycledViewPool()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        val inflater = LayoutInflater.from(parent.context)
        return when (viewType) {
            VIEW_TYPE_LOTTO_PRIZE_ONE -> {
                LottoPrizeOneHolder(ItemLottoPrizesOneBinding.inflate(inflater, parent, false))
            }
            VIEW_TYPE_LOTTO_PRIZE_RUNNING_NUMBER -> {
                LottoPrizeRunningNumberHolder(
                    ItemLottoRunningNumbersBinding.inflate(
                        inflater,
                        parent,
                        false
                    )
                )
            }
            VIEW_TYPE_LOTTO_PRIZE_ONE_NEAR -> {
                LottoPrizeOneNearHolder(
                    ItemLottoPrizesOneNearBinding.inflate(
                        inflater,
                        parent,
                        false
                    )
                )
            }
            VIEW_TYPE_LOTTO_PRIZE_OTHER -> {
                LottoPrizeOtherListHolder(
                    ItemLottoPrizesOtherListBinding.inflate(
                        inflater,
                        parent,
                        false
                    ),
                    LottoLatestPrizeOtherAdapter()
                )
            }
            else -> throw NullPointerException("Not have view Type")
        }
    }

    override fun getItemViewType(position: Int): Int {
        return when (latestList[position]) {
            is LottoPrizesLatestModel.LottoLatestPrizeOne -> VIEW_TYPE_LOTTO_PRIZE_ONE
            is LottoPrizesLatestModel.LottoLatestRunningNumbers -> VIEW_TYPE_LOTTO_PRIZE_RUNNING_NUMBER
            is LottoPrizesLatestModel.LottoLatestPrizeFirstNear -> VIEW_TYPE_LOTTO_PRIZE_ONE_NEAR
            is LottoPrizesLatestModel.LottoLatestPrizeOther -> VIEW_TYPE_LOTTO_PRIZE_OTHER
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when (holder) {
            is LottoPrizeOneHolder -> holder.bind(latestList[position] as LottoPrizesLatestModel.LottoLatestPrizeOne)

            is LottoPrizeRunningNumberHolder -> holder.bind(latestList[position] as LottoPrizesLatestModel.LottoLatestRunningNumbers)

            is LottoPrizeOneNearHolder -> holder.bind(latestList[position] as LottoPrizesLatestModel.LottoLatestPrizeFirstNear)

            is LottoPrizeOtherListHolder -> {
                viewPool.putRecycledView(holder)
                holder.bind(latestList[position] as LottoPrizesLatestModel.LottoLatestPrizeOther, viewPool)
            }

        }
    }

    override fun getItemCount(): Int = latestList.size
}

here my layout holder这是我的布局持有人

<?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"
    android:layout_margin="8dp">

    <TextView
        android:id="@+id/title_prize_other_text_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fontFamily="@font/kanit_light"
        android:gravity="center"
        android:textSize="26sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/prize_other_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clipToPadding="false"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/title_prize_other_text_view"
        tools:itemCount="10"
        tools:listitem="@layout/item_lotto_prizes_other" />

    <GridLayout
        android:id="@+id/prize_other_grip_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:columnCount="2"
        android:orientation="vertical"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/title_prize_other_text_view" />

    <TextView
        android:id="@+id/text_prize_one_near_text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:fontFamily="@font/kanit_light"
        android:text="@string/lotto_prize_per_baht"
        android:textSize="16sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/prize_other_recycler_view" />

</androidx.constraintlayout.widget.ConstraintLayout>

and here my holder recyclerView in RecyclerView这是我在 RecyclerView 中的 holder recyclerView

class LottoPrizeOtherListHolder(
    private val binding: ItemLottoPrizesOtherListBinding,
    private val lottoLatestPrizeOtherAdapter: LottoLatestPrizeOtherAdapter
) :
    RecyclerView.ViewHolder(binding.root) {

    fun bind(
        lottoLatestPrizeOther: LottoPrizesLatestModel.LottoLatestPrizeOther,
        viewPool: RecyclerView.RecycledViewPool
    ) = with(binding) {

        prizeOtherRecyclerView.apply {
            layoutManager = GridLayoutManager(
                context,
                2,
                GridLayoutManager.VERTICAL,
                false
            ).apply {
                initialPrefetchItemCount = lottoLatestPrizeOther.prizeModel.number.size
            }
            this.adapter = lottoLatestPrizeOtherAdapter
            setRecycledViewPool(viewPool)
        }
        lottoLatestPrizeOtherAdapter.numberList =
            lottoLatestPrizeOther.prizeModel.number.toMutableList()
        titlePrizeOtherTextView.text = lottoLatestPrizeOther.prizeModel.name
        textPrizeOneNearTextView.text = itemView.context.getString(
            R.string.lotto_prize_per_baht,
            lottoLatestPrizeOther.prizeModel.reward
        )
    }
}

my problem is: When i scroll recyclerview for first time it is not smooth and logcat show recyclerview Skipped 51 frames?我的问题是:当我第一次滚动 recyclerview 时它不流畅并且 logcat 显示 recyclerview 跳过了 51 帧? adapter but when I reach end of recyclerView and scroll to up then scroll down it is very smooth and my recyclerview have TextView Only !!!适配器但是当我到达 recyclerView 的末尾并向上滚动然后向下滚动时它非常平滑并且我的 recyclerview 只有 TextView ! how can I solve this issue?我该如何解决这个问题?

this my video App https://youtu.be/Li7aKWmEfXQ这是我的视频应用程序https://youtu.be/Li7aKWmEfXQ

In your fragment add this after applying LayoutManager:在应用 LayoutManager 后在您的片段中添加:

lottoRecyclerView.setDrawingCacheEnabled(true);
lottoRecyclerView.setItemViewCacheSize(myCacheSize);

The main reason Jank occurs the first time because on the first time it is loading the values onto memory dynamically. Jank 第一次出现的主要原因是它第一次将值动态加载到 memory 上。 while once it is down it already has a few elements pre loaded而一旦它关闭,它已经预先加载了一些元素

You can handle it using您可以使用它来处理它

mRecyclerView.setHasFixedSize(true); 
mRecyclerview.setNestedScrollingEnabled(false);

in your kotlin code在您的 kotlin 代码中

or add android:nestedScrollingEnabled="false" in your RecyclerView xml或在您的 RecyclerView xml 中添加android:nestedScrollingEnabled="false"

You can reach some performance improvements by applying the following:您可以通过应用以下内容来实现一些性能改进:

recyclerView.setHasFixedSize(true);
recyclerView.setDrawingCacheEnabled(true);

..in combination with lite mode of MapsView: ..结合 MapsView 的精简模式:

<com.google.android.gms.maps.MapView
        android:layout_width="match_parent"
        android:layout_height="200dp"
        app:liteMode="true"
        app:mapType="normal" />

For it was not an option to disable nestedScrollingEnabled as mentioned by @Narendra_Nath, which further improves performance.因为它不是禁用nestedScrollingEnabled的选项,正如@Narendra_Nath 所提到的那样,这进一步提高了性能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM