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

自定义BottomSheetDialogFragment拖拽始终触发ACTION_DOWN,仅下滑关闭如何实现?

BottomSheetDialogFragment拖拽关闭逻辑修复方案

你当前代码的核心问题是在ACTION_DOWN事件触发阶段就直接执行了dismiss(),且触摸监听器直接返回true消费了所有后续事件,因此无论是点击、上滑还是下滑操作都会直接触发弹窗关闭,也无法响应默认的展开逻辑。

修复思路

  • 新增变量记录触摸初始Y坐标和滑动判定阈值,阈值可根据交互需求调整,避免轻微触碰误触发
  • 仅在识别到用户向下滑动超过阈值时才执行关闭操作,其余场景将事件交还给系统,走BottomSheet默认的展开、点击等交互逻辑

修复后代码

// 类内全局变量,记录按下时的初始Y坐标
private var initDownY = 0f
// 滑动判定阈值,单位px,可自行调整,示例为40dp对应的像素值
private val dragThreshold = (40 * Resources.getSystem().displayMetrics.density).toInt()

binding.dragDownImage.setOnTouchListener { view, motionEvent ->
    when(motionEvent.action) {
        MotionEvent.ACTION_DOWN -> {
            // 仅记录初始坐标,不触发关闭
            initDownY = motionEvent.rawY
            // 返回true表示后续触摸事件继续交给当前监听器处理
            true
        }
        MotionEvent.ACTION_MOVE -> {
            val offsetY = motionEvent.rawY - initDownY
            when {
                // 向下滑动超过阈值,触发关闭
                offsetY > dragThreshold -> {
                    dismiss()
                    true
                }
                // 向上滑动/滑动距离未达阈值,不消费事件,交给BottomSheet默认逻辑处理
                else -> false
            }
        }
        MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
            // 重置状态
            initDownY = 0f
            // 点击场景(滑动距离小于阈值)不消费事件,走默认交互
            false
        }
        else -> false
    }
}

可选优化

  • 如果需要支持点击图标切换弹窗展开/收起状态,可以在ACTION_UP分支判断滑动距离小于阈值时,获取弹窗对应的BottomSheetBehavior实例,调用setState方法切换状态
  • 如果需要和系统BottomSheet的滑动行为完全联动,可以直接监听BottomSheetBehavior的slideOffset变化实现关闭逻辑,适配性更强

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 16:06:13