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

Posted

技术标签:

【中文标题】从 Room 数据库中删除最后一项后,布局不会立即更新【英文标题】:Layout doesn't update right away after deleting last item from Room database 【发布时间】:2022-01-02 21:21:51 【问题描述】:

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

如何让最后一个项目立即消失?在适配器中的 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()
        
    

【问题讨论】:

【参考方案1】:

在你的观察者中:

    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 之外。

【讨论】:

【参考方案2】:

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

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

    this.favoriteList = favorite
    notifyDataSetChanged()

【讨论】:

以上是关于从 Room 数据库中删除最后一项后,布局不会立即更新的主要内容,如果未能解决你的问题,请参考以下文章

在 AVQueuePlayer 中播放完最后一项后如何显示工作表视图?

删除一项后组件列表不更新状态

elementui动态表单删除其中一项后数据错乱

从listView中删除项目仅删除最后一项未选择的元素android

使用 gsutil 复制文件后,它们不会立即从本地存储中删除

Listview 添加第二项后仅显示一项