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 :
val isFavorite = preferenceManager.getFavorites().contains(cocktailModel)
isFavorite
value gets loaded only once when that item's viewholder is loaded by the recyclerview and its a val
. So, even after you tap the button, it only works once. To solve this issue, you need to first convert this to a var
and then change the onClick
code to the following :
var isFavorite = preferenceManager.getFavorites().contains(cocktailModel)
updateHeartButton(isFavorite)
binding.heartButton.setOnClickListener {
if (isFavorite) {
preferenceManager.removeFavorite(cocktailModel)
} else {
preferenceManager.addFavorite(cocktailModel)
}
isFavorite = !isFavorite
// -> updateHeartButton(!isFavorite)
updateHeartButton(isFavorite)
}