【问题标题】:How to learn whether a Snackbar button was pressed?如何了解是否按下了 Snackbar 按钮?
【发布时间】:2022-11-17 10:07:54
【问题描述】:

我有一个 Snackbar,当用户在 RecyclerView 元素上滑动以删除它时,它正在打开。这个 Snackbar 允许用户撤消他的操作。我知道如何取回 RecyclerView 的元素。但我也有一个数据库(SQLite)。在我看来,从 detabase 中删除的最好方法是在我了解用户不按“撤消”时执行此操作。否则我需要先删除然后再添加。

我想做这样的事情:

when (snackbar_button){
was_pressed -> adapter.restoreItem(cachedPosition, cachedItem)
was_not_pressed -> dbManager.removeItem(listArray[pos].id.toString())
}

这是我在 MainActivity 上的代码:

val onSwipe = object : OnSwipe(this) {
    override fun onSwiped(viewHolder: ViewHolder, direction: Int) {
        val cachedPosition = viewHolder.absoluteAdapterPosition
        val cachedItem = adapter.listArray[cachedPosition]
        when (direction) {
            ItemTouchHelper.RIGHT -> {
                adapter.removeItem(cachedPosition)

Snackbar.make(binding.rv, "Deleted", Snackbar.LENGTH_SHORT)
                        .apply {
                            setAction("Undo") {
                                adapter.restoreItem(cachedPosition, cachedItem)
                            }
                            show()
                        }
                }
            }
        }

    }

我的适配器:

fun removeItem(pos: Int) {
    listArray.removeAt(pos)
    notifyItemRemoved(pos)
    }

    fun restoreItem(pos: Int, listMain: ListItem) {
        listArray.add(pos, listMain)
        notifyItemInserted(pos)
  }

我在数据库中删除的代码:

    fun removeItem(_id: String) {
        val id = BaseColumns._ID + "=$_id"

【问题讨论】:

    标签: android kotlin android-recyclerview snackbar itemtouchhelper


    【解决方案1】:

    查看 addCallback 函数 - 您可以添加 BaseCallbackonDismissed 函数,其中提供解雇的原因。 DISMISS_EVENT_ACTION 表示您的撤消按钮被点击,任何其他意味着小吃店被刷走,超时后消失等。

    所以你可以这样做:

    Snackbar.make(binding.rv, "Deleted", Snackbar.LENGTH_SHORT)
        .setAction("Undo") { // no need to do anything }
        .setCallback(object: BaseCallback<Snackbar> {
            override fun onDismissed(transientBottomBar: Snackbar, event: Int) {
                // if the user didn't click Undo, delete the item
                if (event != DISMISS_EVENT_ACTION) adapter.removeItem(cachedPosition)
            }
        }
        .show()
    

    不过,从列表中删除该项目并在setAction lambda 或onDismissed 回调中恢复它(如果按下按钮)仍然是个好主意。这样用户会看到它消失并重新出现 - 延迟删除有利于避免从数据库中删除东西,你不想触摸真实的数据,直到你确定。

    您仍然可以使用此处的内容来做到这一点:

    // delete/hide it
    adapter.removeItem(cachedPosition)
    
    Snackbar.make(binding.rv, "Deleted", Snackbar.LENGTH_SHORT)
        .setAction("Undo") { // no need to do anything }
        .setCallback(object: BaseCallback<Snackbar> {
            override fun onDismissed(transientBottomBar: Snackbar, event: Int) {
                // add the item back if they DID click Undo
                if (event == DISMISS_EVENT_ACTION) adapter.restoreItem(cachedPosition, cachedItem)
                else // do something else if they didn't, like delete cachedItem from database
            }
        }
        .show()
    
    

    此外,如果您要访问 adapter 并像这样在外部管理撤消状态,我会让 removeItem 返回已删除的项目(这样您就不必直接访问适配器的数据列表)并且可能将 restoreItem 重命名为 addItem,因为从技术上讲,您是在某个位置插入您喜欢的任何内容。

    不过真的,最好保留最后删除的项目适配器内部,因此您可以调用删除(位置)恢复()让适配器处理细节并管理自己的状态。它只是更清洁并防止错误

    【讨论】:

      猜你喜欢
      • 2022-06-14
      • 2015-10-30
      • 2012-04-25
      • 1970-01-01
      • 1970-01-01
      • 2018-01-25
      • 2012-04-24
      • 1970-01-01
      • 2013-06-11
      相关资源
      最近更新 更多