The problem is that when I click the "Add to Favorites" button for the first time, the image changes and the data is saved to SharedPreferences. However, when I click the same button again, nothing changes. It's only when I scroll a little bit down (until the item disappears from the screen) and then scroll back up that the button I clicked before scrolling down finally shows the change.
I'm trying to keeping add favorite data in sharedPreferences
import android.content.Context
import android.content.SharedPreferences
import com.example.myapplication.data.model.CocktailModel
import com.google.gson.Gson
class SharedPrefs(context: Context) {
private val preferences: SharedPreferences? =
context.getSharedPreferences("FavoriteStatus", Context.MODE_PRIVATE)
fun addFavorite(cocktail: CocktailModel) {
val favorites = getFavorites()
favorites.add(cocktail)
saveFavorites(favorites)
}
fun removeFavorite(cocktail: CocktailModel) {
val favorites = getFavorites()
favorites.remove(cocktail)
saveFavorites(favorites)
}
fun getFavorites(): MutableList<CocktailModel> {
val json = preferences?.getString("favorites", "[]")
val favorites = Gson().fromJson(json, Array<CocktailModel>::class.java)
return favorites?.toMutableList() ?: mutableListOf()
}
private fun saveFavorites(favorites: List<CocktailModel>) {
val json = Gson().toJson(favorites)
preferences?.edit()?.putString("favorites", json)?.apply()
}
}
And my recycler view adapter is =
package com.example.myapplication.ui.adapter
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.myapplication.R
import com.example.myapplication.SharedPrefs
import com.example.myapplication.data.model.CocktailModel
import com.example.myapplication.databinding.FeedRowBinding
class FeedAdapter(private val cocktailList : ArrayList<CocktailModel>) :
RecyclerView.Adapter<FeedAdapter.FeedViewHolder>() {
class FeedViewHolder(private val binding: FeedRowBinding, private val preferenceManager: SharedPrefs) :
RecyclerView.ViewHolder(binding.root) {
fun bind(cocktailModel: CocktailModel) {
binding.CocktailTitle.text = cocktailModel.strDrink
Glide.with(binding.imageView.context)
.load(cocktailModel.strDrinkThumb)
.into(binding.imageView)
val isFavorite = preferenceManager.getFavorites().contains(cocktailModel)
updateHeartButton(isFavorite)
// favori butonuna tiklandiginda favoriye ekliyse kaldiriyor, degilse ekliyor
binding.heartButton.setOnClickListener {
if (isFavorite) {
preferenceManager.removeFavorite(cocktailModel)
} else {
preferenceManager.addFavorite(cocktailModel)
}
updateHeartButton(!isFavorite)
}
}
// favori butonunun durumunu guncelleyen fonksiyon buna gore image degistiriyoruz
private fun updateHeartButton(isFavorite: Boolean) {
if (isFavorite) {
binding.heartButton.setImageResource(R.drawable.heart)
} else {
binding.heartButton.setImageResource(R.drawable.heart2)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FeedViewHolder {
val binding = FeedRowBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return FeedViewHolder(binding, SharedPrefs(parent.context))
}
override fun getItemCount(): Int {
return cocktailList.size
}
override fun onBindViewHolder(holder: FeedViewHolder, position: Int) {
holder.bind(cocktailList[position])
}
fun updateData(cocktails: List<CocktailModel>) {
cocktailList.clear()
cocktailList.addAll(cocktails)
}
}
So the root cause of your issue is this line :
isFavoritevalue gets loaded only once when that item's viewholder is loaded by the recyclerview and its aval. So, even after you tap the button, it only works once. To solve this issue, you need to first convert this to avarand then change theonClickcode to the following :