从 Room 数据库中删除最后一项后,布局不会立即更新

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

我有这个片段,其中存储了我的 'favorite items',如果需要,我可以在单击按钮时删除它们。该实现运行良好,直到我到达最后一个项目并且它不会消失,除非我转到另一个片段然后返回(例如,该项目已被删除但回收器视图仍然显示它,除非我自己更新片段)。

如何让最后一项立即消失?在适配器中的 deleteHandler 之后设置 notifyDataSetChanged() 似乎不起作用。

这是我拥有物品的片段:

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

适配器:

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

}

这是最喜欢的视图模型:

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

在其中设置新项目之前清除您的收藏夹列表。您可以在 setData() 函数中执行此操作。像这样,

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

    this.favoriteList = favorite
    notifyDataSetChanged()
}

在你的观察者这里:

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

当列表从一项变为零项时,在 if 块中显示一条空消息,但您未能更新适配器数据或隐藏 RecyclerView,因此它将继续显示之前的内容。您应该将 adapter.setData(favorite) 移到 if/else 之外。