如何在自定义监听器中访问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
相关产品推荐
相关产品推荐

