首页 > 解决方案 > RecyclerView 优化问题

问题描述

我注意到一些 RV 性能问题。我有一个包含一些物品的 RecyclerView。当我第一次使用 RV 启动 Fragment 并尝试滚动它时,我看到了一些滞后。我将在这个问题的结尾附上一个带有活动 GPU 分析的 GIF。如您所见,当我开始滚动时,我的 FPS 下降很大,然后它变得平滑。所以我的问题是——

是否可以优化此过程?我尝试了以下方法:

1. 为我所有的 ViewHolders 创建一次视图:

私有变量 itemView:查看?=空

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
    if (itemView == null) {
        itemView = LayoutInflater.from(parent.context).inflate(R.layout.rv_contact_item, parent, false)
    }
    return ContactViewHolder(itemView)
}

但这是不可能的,因为这个视图将在第一次onCreateViewHolder调用时附加到它的父级,我正在崩溃“首先从父级分离你的视图”。

2. 在后台线程中创建 ViewHolders。

也不做什么。

我知道有可能以编程方式创建 View,但它会按预期工作吗?我有一个相当困难的视图,所以需要一些时间来尝试它。

在此处输入图像描述

升级版:

我的单项 XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:id="@+id/btn_contact"
    android:orientation="horizontal"
    android:padding="16dp"
    android:background="?attr/selectableItemBackground">

    <com.myapp.custom.AvatarView
        android:id="@+id/v_avatar"
        android:layout_width="56dp"
        android:layout_height="56dp"
        android:layout_marginEnd="16dp"
        android:layout_gravity="center"
        android:transitionName="chat_avatar_transition"
        tools:background="@color/pale_red">

        <com.myapp.custom.UserStatusView
            android:id="@+id/v_user_status"
            android:layout_width="18dp"
            android:layout_height="18dp"
            android:layout_gravity="bottom|end"/>
    </com.myapp.custom.AvatarView>

    <LinearLayout
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_gravity="center"
        android:layout_marginEnd="10dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <ImageView
                android:id="@+id/iv_conference"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:baselineAlignBottom="true"
                android:layout_marginEnd="2dp"
                app:srcCompat="@drawable/ic_vector_conference"/>

            <TextView
                android:id="@+id/tv_name"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:textSize="16sp"
                android:ellipsize="end"
                android:lines="1"
                android:transitionName="chat_name_transition"
                tools:text="Title" />
        </LinearLayout>

        <TextView
            android:id="@+id/tv_contact_subtitle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="@color/text_light"
            android:textSize="14sp"
            android:ellipsize="end"
            android:lines="1"
            tools:text="Subtitle" />

        <LinearLayout
            android:id="@+id/ll_last_message"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <ImageView
                android:id="@+id/iv_message_direction"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginEnd="3dp"
                app:srcCompat="@drawable/ic_vector_arrow_right" />

            <TextView
                android:id="@+id/tv_last_message"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:textColor="@color/text_light"
                android:textSize="14sp"
                android:ellipsize="end"
                android:lines="1"
                tools:text="Hello!" />
        </LinearLayout>
    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <ImageView
                android:id="@+id/iv_birthday"
                android:layout_width="24dp"
                android:layout_height="24dp"
                app:srcCompat="@drawable/ic_vector_birthday" />

            <ImageView
                android:id="@+id/iv_app_type"
                android:layout_width="24dp"
                android:layout_height="24dp"
                app:srcCompat="@drawable/ic_vector_mobile" />

            <ImageView
                android:id="@+id/iv_important_messages"
                android:layout_width="24dp"
                android:layout_height="24dp"
                app:srcCompat="@drawable/ic_vector_flag" />
        </LinearLayout>

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <ImageView
                android:id="@+id/iv_message_status"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:visibility="gone"
                android:layout_gravity="bottom|end"
                app:srcCompat="@drawable/ic_vector_checked" />

            <TextView
                android:id="@+id/tv_unread_counter"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:minHeight="24dp"
                android:minWidth="24dp"
                android:padding="3dp"
                android:background="@drawable/shape_rect_rounded_12dp_blue_regular"
                android:gravity="center"
                android:textColor="@android:color/white"
                android:layout_gravity="bottom|end"
                tools:text="10" />
        </FrameLayout>
    </LinearLayout>
</LinearLayout> 

UPD2:

我的绑定()方法:

fun bind(contact: ContactModel) {
            avatarView.apply {
                initialize(
                    contact.id,
                    contact.avatar,
                    contact.fullName)
            }
            ivConference.visibility = if (ContactType.CONFERENCE == contact.type)
                View.VISIBLE
            else
                View.GONE

            tvName.text = contact.fullName
            tvContactSubtitle.text = contact.subtitle
            contact.lastMessageDirection?.let { direction ->
                llLastMessage.visible

                ivLastMessageDirection.setImageDrawable(
                    VectorDrawableCompat.create(
                        itemView.context.resources,
                        direction.icon,
                        null)
                )
                tvLastMessage.text = contact.lastMessage
            } ?: llLastMessage.invisible
            ivBirthday.visibility = if (contact.isBirthdayInc) {
                View.VISIBLE
            } else
                View.GONE

            ivImportantMessages.visibility = if (contact.hasImportantMessages)
                View.VISIBLE
            else
                View.GONE

            if (contact.unreadCounter == 0) {
                tvUnreadCounter.gone
            } else {
                tvUnreadCounter.visible
                tvUnreadCounter.text = contact.unreadCounter.toString()
            }
        }

标签: androidoptimizationandroid-recyclerview

解决方案


那是因为您使用的图像质量对于这么多需要时间来优化的项目来说太高了。

请将您的图像转换为 WebP 格式以获得更好的性能。

希望能帮助到你。


推荐阅读