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

SwipeToDismissBox如何判断松手是否触发消除事件

Material3 1.2.0 SwipeToDismissBox 背景变色阈值判断方案

问题修正与核心逻辑

你代码里存在变量名错误:在backgroundContent中使用了未定义的dismissState,应替换为你声明的state变量。

修正后,利用state.targetValue判断是否触发删除的逻辑是可行的,但需注意SwipeToDismissBox的默认阈值规则:组件会取固定56dp位置阈值和组件宽度50%比例阈值中的较小值作为实际触发阈值。如果你的列表项宽度小于112dp,56dp刚好等于50%宽度,就会出现“滑动到约50%就触发变色”的情况。

若希望严格以56dp作为触发阈值,只需在SwipeToDismissBox中显式指定positionalThreshold:

val deleteValue = SwipeToDismissBoxValue.StartToEnd

val state = rememberSwipeToDismissBoxState(
    confirmValueChange = {
        if (it == deleteValue){
            L.tag("SWIPE-DISMISS").d { "onDelete..." }
            onDelete()
            true
        } else false
    }
)

SwipeToDismissBox(
    modifier = Modifier,
    state = state,
    enableDismissFromEndToStart = false,
    enableDismissFromStartToEnd = true,
    // 显式指定固定56dp阈值,忽略比例阈值
    positionalThreshold = { SwipeToDismissBoxDefaults.positionalThreshold(it) },
    backgroundContent = {
        val success = state.targetValue == deleteValue
        
        val color by animateColorAsState(
            if (success) Color.Red else Color.Transparent,
            label = ""
        )
        
        Box(
            Modifier
                .fillMaxSize()
                .background(color)
        ) {
            // ... 放置删除图标等内容
        }
    }
) {
    content()
}

替代方案(无需手动计算偏移)

如果你想完全依赖组件内置状态判断,也可通过state.progress结合state.targetValue强化逻辑,本质上targetValue已足够满足需求:

val isSwipeEnough = state.targetValue == deleteValue && state.progress > 0f

该逻辑会在滑动距离超过阈值时将背景切换为红色;若滑动未达阈值,松手后targetValue会回到初始状态,背景自动恢复透明。

版本差异说明

Material3 1.2.0将原SwipeToDismiss组件替换为SwipeToDismissBox,状态类同步改为SwipeToDismissBoxState。虽然保留了targetValue属性,但内部阈值判断逻辑新增了“位置+比例”双规则,这是导致你在1.1.2版本的原有逻辑表现不符合预期的核心原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 07:47:38