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
相关产品推荐
相关产品推荐

