【问题标题】:Layout doesn't update right away after deleting last item from Room database从 Room 数据库中删除最后一项后,布局不会立即更新
【发布时间】: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()
        }
    }
}

【问题讨论】:

    标签: android kotlin android-recyclerview android-room


    【解决方案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()
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-09-28
        • 1970-01-01
        • 1970-01-01
        • 2018-06-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多