Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Layout doesn't update right away after deleting last item from Room database

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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()
        }
    }
}

>Solution :

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading