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
相关产品推荐
相关产品推荐

