Home > front end >  Layout doesn't update right away after deleting last item from Room database
Layout doesn't update right away after deleting last item from Room database

Time:11-24

I have this fragment in which I store my 'favorite items' and I can delete them when I click on a button if I want to. The implementation works well until I get to the last item and it doesn't disappear unless I go to another fragment and then come back (as in, the item is deleted but the recycler view still shows it unless I update the fragment myself).

How can I make the last item disappear right away? Setting notifyDataSetChanged() after the deleteHandler in the adapter does not seem to work.

This is the fragment where I have the items:

class FavoritesFragment : Fragment() {

    private val mfavoriteViewModel by viewModels<FavoriteViewModel>()
    private lateinit var binding: FragmentFavoritesBinding
    private val deleteHandler: (Favorites) -> Unit = {
        mfavoriteViewModel.deleteFavorite(it)

    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?,
    ): View {
        binding = FragmentFavoritesBinding.inflate(layoutInflater)
        //recyclerview
        val adapter = FavoritesAdapter(deleteHandler)
        binding.rvFavList.layoutManager = LinearLayoutManager(context)
        binding.rvFavList.adapter = adapter

        //favoriteViewModel
        mfavoriteViewModel.readAllData.observe(viewLifecycleOwner, { favorite ->

            if (favorite.isEmpty()) {
                binding.emptyState.text = getString(R.string.emptyState)
                binding.emptyState.visibility = View.VISIBLE
            } else {
                adapter.setData(favorite)
                binding.emptyState.visibility = View.GONE
            }
        })

        return binding.root
    }
}

The adapter:

class FavoritesAdapter(val deleteHandler: (Favorites) -> Unit) :
    RecyclerView.Adapter<FavoritesAdapter.ViewHolder>() {

    private var favoriteList = emptyList<Favorites>()

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        private val binding = FavItemBinding.bind(itemView)

        val favTitle: TextView = binding.tvFavsTitle
        val favItem: ImageButton = binding.btnFavs
        val favImg: ImageView = binding.ivFavs

        fun bind(favorites: Favorites) {
            Picasso.get().load(favorites.image).into(favImg)
            favTitle.text = favorites.title
        }

    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(
            LayoutInflater.from(parent.context).inflate(R.layout.fav_item, parent, false)
        )
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.bind(favoriteList[position])

        //delete favorite item
        holder.favItem.setOnClickListener {
            deleteHandler(favoriteList[position])
        }

    }

    override fun getItemCount(): Int {
        return favoriteList.size
    }

    fun setData(favorite: List<Favorites>) {
        this.favoriteList = favorite
        notifyDataSetChanged()
    }

}

This is the favorite's viewmodel:

class FavoriteViewModel(application: Application) : AndroidViewModel(application) {

    val readAllData: LiveData<List<Favorites>>
    private val repository: FavoritesRepository

    init {
        val favoriteDao = FavoriteDatabase.getDatabase(application).favoriteDao()
        repository = FavoritesRepository(favoriteDao)
        readAllData = repository.readAllData
    }

    fun addFavorite(favorite: Favorites) {
        viewModelScope.launch(Dispatchers.IO) {
            repository.addFavorite(favorite)
        }
    }

    fun deleteFavorite(favorite: Favorites) {
        viewModelScope.launch(Dispatchers.IO) {
            repository.deleteFavorite(favorite)
        }
    }

    fun deleteAllFavorites() {
        viewModelScope.launch(Dispatchers.IO) {
            repository.deleteAllFavorites()
        }
    }
}

CodePudding user response:

Here in your observer:

    mfavoriteViewModel.readAllData.observe(viewLifecycleOwner, { favorite ->

        if (favorite.isEmpty()) {
            binding.emptyState.text = getString(R.string.emptyState)
            binding.emptyState.visibility = View.VISIBLE
        } else {
            adapter.setData(favorite)
            binding.emptyState.visibility = View.GONE
        }
    })

When the list goes from one item to zero items, in the if block you show an empty message, but you fail to update the adapter data or hide the RecyclerView so it will continue to show what it did before. You should move the adapter.setData(favorite) outside the if/else.

CodePudding user response:

Clear your favourites list before setting the new items in it. You can do this in your setData() function. Like this,

fun setData(favorite: List<Favorites>) {
    
    if (favouriteList.isNotEmpty()) {
      favouriteList.clear()
    }

    this.favoriteList = favorite
    notifyDataSetChanged()
}
  • Related