You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为加载图片的RecyclerView实现DiffUtil性能优化

DiffUtil 接入实现方案

以下是针对你当前图片列表的适配改造步骤:

1. 定义列表项差异比较规则

首先创建DiffUtil.ItemCallback实现类,用来对比新旧列表中Upload对象的差异:

val PostDiffCallback = object : DiffUtil.ItemCallback<Upload>() {
    // 判定两个item是否为同一个对象,使用Firebase返回的唯一key作为判断依据
    override fun areItemsTheSame(oldItem: Upload, newItem: Upload): Boolean {
        return oldItem.getmKey() == newItem.getmKey()
    }

    // 判定两个item的展示内容是否相同,内容不同时才会触发重绑定
    override fun areContentsTheSame(oldItem: Upload, newItem: Upload): Boolean {
        return oldItem.getmImageUrl() == newItem.getmImageUrl()
    }
}

2. 改造适配器继承ListAdapter

ListAdapter是官方封装的DiffUtil适配基类,内部自动处理差异计算和局部刷新逻辑,不需要手动调用全量刷新:

class PostAdapter_Home(var mcontext: Context) :
    ListAdapter<Upload, PostAdapter_Home.PostViewHolder>(PostDiffCallback) {
    
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PostViewHolder {
        val view = LayoutInflater.from(mcontext)
            .inflate(R.layout.post_item_container_home_ex, parent, false)
        return PostViewHolder(view)
    }

    override fun onBindViewHolder(holder: PostViewHolder, position: Int) {
        val uploadCurrent = getItem(position)
        Glide.with(mcontext)
            .load(uploadCurrent.getmImageUrl())
            .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
            .placeholder(holder.shimmerDrawable)
            .fitCenter()
            .into(holder.imageView)
    }

    // 替换原有的setUploads方法,内部自动执行差异计算和更新
    fun setUploads(uploads: MutableList<Upload?>?) {
        submitList(uploads?.filterNotNull())
    }
    

    class PostViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val imageView: ShapeableImageView
        // 将shimmer初始化移到ViewHolder中,避免每次绑定item时重复创建
        val shimmerDrawable: ShimmerDrawable

        init {
            imageView = itemView.findViewById(R.id.imagePostHome)
            
            val shimmer = ColorHighlightBuilder()
                .setBaseColor(Color.parseColor("#F3F3F3"))
                .setBaseAlpha(1f)
                .setHighlightColor(Color.parseColor("#E7E7E7"))
                .setHighlightAlpha(1f)
                .setDropoff(50f)
                .build()
            shimmerDrawable = ShimmerDrawable()
            shimmerDrawable.setShimmer(shimmer)
        }
    }
}

改造说明:不需要再重写getItemCount方法,ListAdapter内部已经实现了该逻辑,同时原有全量刷新的notifyDataSetChanged调用可以全部移除。

3. 可选优化:重构Upload为data class

如果不需要兼容旧Java调用,可将Upload改为Kotlin数据类,自动生成equals、hashCode方法,后续新增字段时不需要手动调整Diff比较逻辑:

package com.example.myappnotfinal.AdaptersAndMore

import com.google.firebase.database.Exclude

data class Upload(
    internal var mImageUrl: String? = null,
    @Exclude
    private var mKey: String? = null
) {
    constructor() : this(null, null)
    constructor(imageUrl: String?) : this(imageUrl, null)

    fun getmImageUrl(): String? = mImageUrl

    fun setmImageUrl(mImageUrl: String?) {
        this.mImageUrl = mImageUrl
    }

    @Exclude
    fun getmKey(): String? = mKey

    @Exclude
    fun setmKey(Key: String?) {
        mKey = Key
    }
}

使用说明

后续在Fragment中更新列表数据时,直接调用adapter.setUploads(新的列表数据)即可,DiffUtil会自动计算新旧列表的差异,仅更新有变动的item,避免不必要的图片重加载,大幅提升列表滑动和数据更新时的性能。

内容的提问来源于stack exchange,提问作者Vasant Raval

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 17:06:03