You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase中RecyclerView滑动删除项并刷新界面实现方法

RecyclerView左右滑删除Firebase Board数据实现方案

核心实现步骤

1. 新增Firebase删除接口

在现有FirestoreClass中添加删除Board文档的方法,直接通过Board对应的documentId删除云端数据:

fun deleteBoard(activity: MainActivity, boardDocumentId: String) {
    mFireStore.collection(Constants.BOARDS)
        .document(boardDocumentId)
        .delete()
        .addOnSuccessListener {
            activity.boardDeleteSuccess()
        }
        .addOnFailureListener { e ->
            activity.hideProgressDialog()
            Log.e(activity.javaClass.simpleName, "删除Board失败", e)
            Toast.makeText(activity, "删除失败,请重试", Toast.LENGTH_SHORT).show()
        }
}

2. 调整适配器支持局部刷新

修改BoardItemAdapter,新增单条删除方法,避免每次刷新都重建适配器导致动画失效:

// 新增移除指定位置项的方法
fun removeItem(position: Int) {
    list.removeAt(position)
    notifyItemRemoved(position)
    notifyItemRangeChanged(position, list.size)
}

注意:不要在每次拉取列表时重新创建Adapter实例,后续会调整MainActivity逻辑复用适配器。

3. 绑定滑动删除手势

使用AndroidX自带的ItemTouchHelper实现滑动监听,无需引入第三方库。
首先在MainActivity中新增两个成员变量:

private lateinit var mBoardAdapter: BoardItemAdapter
private val mBoardList = ArrayList<Board>()

修改原有populateBoardListToUI方法,改为复用适配器+绑定滑动逻辑:

fun populateBoardListToUI(boardList: ArrayList<Board>) {
    hideProgressDialog()
    mBoardList.clear()
    mBoardList.addAll(boardList)
    
    if (mBoardList.size > 0) {
        binding?.appbar?.llmaincontent?.rvboardlist?.visibility = View.VISIBLE
        binding?.appbar?.llmaincontent?.tvnoboardavailable?.visibility = View.GONE
        
        // 仅首次初始化时创建适配器和绑定滑动事件
        if (!::mBoardAdapter.isInitialized) {
            binding?.appbar?.llmaincontent?.rvboardlist?.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
            binding?.appbar?.llmaincontent?.rvboardlist?.setHasFixedSize(true)
            mBoardAdapter = BoardItemAdapter(this, mBoardList)
            binding?.appbar?.llmaincontent?.rvboardlist?.adapter = mBoardAdapter
            
            // 原有列表点击事件保留
            mBoardAdapter.setOnClickListener(object: BoardItemAdapter.OnClickListener{
                override fun onClick(position: Int, model: Board) {
                    val intent = Intent(this@MainActivity,TaskListActivity::class.java)
                    intent.putExtra(Constants.DOCUMENT_ID,model.documentId)
                    startActivity(intent)
                }
            })

            // 滑动删除核心逻辑
            val swipeCallback = object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) {
                override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
                    // 不需要拖拽功能,直接返回false
                    return false
                }

                override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
                    val position = viewHolder.adapterPosition
                    val targetBoard = mBoardList[position]
                    showProgressDialog("正在删除...")
                    FirestoreClass().deleteBoard(this@MainActivity, targetBoard.documentId)
                }

                // 可选:自定义滑动时的红色背景+删除图标,优化交互
                override fun onChildDraw(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) {
                    val itemView = viewHolder.itemView
                    val deleteIcon = ContextCompat.getDrawable(this@MainActivity, R.drawable.ic_delete)
                    val iconMargin = (itemView.height - deleteIcon!!.intrinsicHeight) / 2
                    val iconTop = itemView.top + (itemView.height - deleteIcon.intrinsicHeight) / 2
                    val iconBottom = iconTop + deleteIcon.intrinsicHeight

                    if (dX > 0) { // 右滑
                        val iconLeft = itemView.left + iconMargin
                        val iconRight = itemView.left + iconMargin + deleteIcon.intrinsicWidth
                        deleteIcon.setBounds(iconLeft, iconTop, iconRight, iconBottom)
                        c.clipRect(itemView.left, itemView.top, itemView.left + dX.toInt(), itemView.bottom)
                        c.drawColor(Color.parseColor("#FFE53935"))
                    } else if (dX < 0) { // 左滑
                        val iconLeft = itemView.right - iconMargin - deleteIcon.intrinsicWidth
                        val iconRight = itemView.right - iconMargin
                        deleteIcon.setBounds(iconLeft, iconTop, iconRight, iconBottom)
                        c.clipRect(itemView.right + dX.toInt(), itemView.top, itemView.right, itemView.bottom)
                        c.drawColor(Color.parseColor("#FFE53935"))
                    } else {
                        c.clipRect(0,0,0,0)
                    }
                    deleteIcon.draw(c)
                    super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
                }
            }
            ItemTouchHelper(swipeCallback).attachToRecyclerView(binding?.appbar?.llmaincontent?.rvboardlist)
        } else {
            mBoardAdapter.notifyDataSetChanged()
        }
    } else {
        binding?.appbar?.llmaincontent?.rvboardlist?.visibility = View.GONE
        binding?.appbar?.llmaincontent?.tvnoboardavailable?.visibility = View.VISIBLE
    }
}

如果不需要自定义滑动背景,直接删掉onChildDraw覆写方法即可,不影响核心删除功能。

4. 新增删除成功回调

在MainActivity中添加删除完成后的处理方法,删除成功后重新拉取云端列表保证数据一致:

fun boardDeleteSuccess() {
    hideProgressDialog()
    Toast.makeText(this, "删除成功", Toast.LENGTH_SHORT).show()
    FirestoreClass().getBoardList(this)
}

可选优化

  • 可添加Snackbar撤销删除功能,滑动删除后3-5秒内点击撤销即可恢复本地列表项,同时取消云端删除请求
  • 如果Board下关联了任务、成员等子集合数据,删除主文档时记得同步清理子集合,避免产生冗余数据
  • 如果列表做了分页,删除单条后注意调整分页偏移量,避免后续加载出现数据重复或缺失

内容的提问来源于stack exchange,提问作者Suryansh Singh Rajput

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 06:57:24