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

Android Kotlin:RecyclerView收藏按钮点击后需滚动才更新SharedPreferences问题

解决RecyclerView收藏按钮点击状态不实时更新的问题

问题原因

  • 点击事件中依赖的是bind方法初始化时的isFavorite值,而非点击瞬间的实时收藏状态,导致第二次点击逻辑判断错误
  • CocktailModel未重写equals和hashCode方法,getFavorites().contains(cocktailModel)无法正确识别相同饮品(Gson反序列化生成的新对象与原对象引用不同)

解决方案

1. 修正ViewHolder点击事件的状态判断逻辑

将isFavorite改为可变变量,点击时直接切换状态并同步更新UI,不再依赖初始化时的旧值:

fun bind(cocktailModel: CocktailModel) {
    binding.CocktailTitle.text = cocktailModel.strDrink
    Glide.with(binding.imageView.context)
        .load(cocktailModel.strDrinkThumb)
        .into(binding.imageView)

    // 用可变变量实时维护当前收藏状态
    var isFavorite = preferenceManager.getFavorites().contains(cocktailModel)
    updateHeartButton(isFavorite)

    binding.heartButton.setOnClickListener {
        // 点击时直接切换状态
        isFavorite = !isFavorite
        if (isFavorite) {
            preferenceManager.addFavorite(cocktailModel)
        } else {
            preferenceManager.removeFavorite(cocktailModel)
        }
        updateHeartButton(isFavorite)
    }
}

2. 重写CocktailModel的equals和hashCode方法

确保contains方法能通过唯一标识(比如饮品ID)判断是否为同一对象:

data class CocktailModel(
    val idDrink: String, // 假设模型中有唯一ID字段
    val strDrink: String,
    val strDrinkThumb: String,
    // 其他字段...
) {
    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false

        other as CocktailModel
        return idDrink == other.idDrink
    }

    override fun hashCode(): Int {
        return idDrink.hashCode()
    }
}

如果你的CocktailModel已经是data class,默认会基于所有属性生成equals/hashCode,但建议明确只比较唯一ID,避免其他字段变化导致判断失效。

3. 可选优化:减少SharedPreferences频繁反序列化

每次调用getFavorites()都会反序列化整个列表,可添加内存缓存提升性能:

class SharedPrefs(context: Context) {
    private val preferences: SharedPreferences? =
        context.getSharedPreferences("FavoriteStatus", Context.MODE_PRIVATE)
    // 内存缓存收藏列表,避免重复反序列化
    private var cachedFavorites: MutableList<CocktailModel>? = null

    fun addFavorite(cocktail: CocktailModel) {
        val favorites = getFavorites()
        favorites.add(cocktail)
        saveFavorites(favorites)
        cachedFavorites = favorites
    }

    fun removeFavorite(cocktail: CocktailModel) {
        val favorites = getFavorites()
        favorites.remove(cocktail)
        saveFavorites(favorites)
        cachedFavorites = favorites
    }

    fun getFavorites(): MutableList<CocktailModel> {
        cachedFavorites?.let { return it }
        val json = preferences?.getString("favorites", "[]")
        val favorites = Gson().fromJson(json, Array<CocktailModel>::class.java)
        val mutableList = favorites?.toMutableList() ?: mutableListOf()
        cachedFavorites = mutableList
        return mutableList
    }

    private fun saveFavorites(favorites: List<CocktailModel>) {
        val json = Gson().toJson(favorites)
        preferences?.edit()?.putString("favorites", json)?.apply()
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 21:54:51