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

如何在自定义监听器中访问ItemTouchHelper回调内的Canvas参数

解决方案

核心思路

你可以在当前创建的匿名类内部新增自定义成员变量,用来存储你需要的参数或对应状态,在onChildDraw、onSwiped等系统回调触发时更新这些成员变量,之后在DialogNoticiasDismiss回调中就可以直接使用这些存储的值。注意不要长期持有Canvas、ViewHolder这类系统复用的对象,避免内存泄漏和逻辑异常。

代码实现示例

val itemSwipe = object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT), DialogFragmentNoticias.DialogFragmentDismissListener {
    // 存储操作的条目位置,不要直接存ViewHolder(会复用)
    private var currentOperatePosition: Int? = null
    // 存储你需要的绘制状态,不要直接存Canvas(仅当前绘制周期有效)
    private var customDrawFlag: Boolean = false

    override fun onMove(
            recyclerView: RecyclerView,
            viewHolder: RecyclerView.ViewHolder,
            target: RecyclerView.ViewHolder
    ): Boolean {
        return false
    }

    override fun onChildDraw(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) {
        // 回调触发后需要特殊绘制的逻辑写在这里,用当前有效的Canvas实例
        currentOperatePosition?.takeIf { it == viewHolder.bindingAdapterPosition && customDrawFlag }?.let {
            // 在这里执行你需要的绘制操作
            // ...
        }
        super.onChildDraw(c, recyclerView, viewHolder, 0f, dY, actionState, isCurrentlyActive)
    }

    override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
        return makeMovementFlags(0, ItemTouchHelper.LEFT)
    }

    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
        // 触发弹窗时记录当前操作的条目位置
        currentOperatePosition = viewHolder.bindingAdapterPosition
        // 弹出你的Dialog示例
        DialogFragmentNoticias().apply {
            setDismissListener(this@object)
            show(supportFragmentManager, "noticias_dialog")
        }
    }

    override fun DialogNoticiasDismiss() {
        currentOperatePosition?.let { position ->
            adapter.notifyItemChanged(position)
            allowed = true
            // 需要绘制就修改标记,触发RecyclerView重绘即可
            customDrawFlag = true
            recyclerView.invalidate()
        }
    }
}

注意事项

  • Canvas仅在当前onChildDraw绘制周期内有效,不要作为成员变量长期存储,需要绘制时修改状态标记后调用recyclerView.invalidate()触发重绘,在新的onChildDraw回调中用传入的新Canvas执行逻辑即可。
  • ViewHolder是RecyclerView的复用对象,可能已经被绑定到其他条目数据,不要直接存储ViewHolder实例,推荐存储bindingAdapterPosition或者条目的唯一业务ID来标识操作对象。
  • 如果需要传递触发弹窗时的临时参数,也可以在创建Dialog时把参数传入Dialog内部,在Dialog关闭时通过回调把参数带回来。

内容的提问来源于stack exchange,提问作者Rodrigo Barboza

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 12:45:01