Wear Compose:让SwipeToDismiss仅支持右滑删除,左滑交由SwipeToDismissBox处理
解决方案
要实现卡片仅响应右滑删除、左滑交由外层返回的需求,核心是阻止卡片的SwipeToDismiss拦截左滑触摸事件,让事件能透传到外层的SwipeToDismissBox。具体实现如下:
修改SwipeToDeleteCard组件
通过添加触摸事件拦截逻辑,仅在右滑(EndToStart)时让SwipeToDismiss处理事件,左滑时直接将事件向上传递给外层:
@OptIn(ExperimentalMaterialApi::class, ExperimentalFoundationApi::class) @Composable private fun SwipeToDeleteCard( onClick: (courseUuid: String) -> Unit, onSwipeToDelete: (courseUuid: String) -> Unit, myModel: MyModel, ) { val swipeState = rememberDismissState( confirmStateChange = { dismissValue -> if (dismissValue == DismissValue.DismissedToStart) { onSwipeToDelete(myModel.uuid) // 修正原代码变量引用错误 false } else { true } } ) SwipeToDismiss( state = swipeState, directions = setOf(EndToStart), modifier = Modifier .pointerInput(Unit) { detectHorizontalDragGestures( onDragStart = { downPosition -> // 预判断滑动方向,左滑则终止当前触摸检测,让外层处理 awaitPointerEventScope { val dragEvent = awaitPointerEvent() val dx = dragEvent.changes.first().position.x - downPosition.x if (dx > 0) { // 左滑(StartToEnd),取消当前触摸监听,事件透传外层 this@pointerInput.coroutineContext.job.cancel() } } } ) }, background = { Box(modifier = Modifier.fillMaxSize()) { Icon( painter = painterResource(id = R.drawable.trash), tint = Color.Unspecified, contentDescription = "Delete", modifier = Modifier .size(24.dp) .align(Alignment.CenterEnd) ) } }, dismissContent = { MyCard( myModel = myModel, onClick = onClick ) } ) }
关键逻辑说明
- 触摸方向判断:在
onDragStart阶段计算触摸位置变化(dx > 0表示左滑),提前识别滑动方向。 - 事件透传:检测到左滑时,立即取消当前
SwipeToDismiss的触摸监听,让事件自然向上传递到外层SwipeToDismissBox,触发返回逻辑。 - 保留右滑功能:仅拦截左滑事件,右滑(
dx < 0)时SwipeToDismiss正常处理,触发删除逻辑。
额外注意点
- 确保外层
SwipeToDismissBox的modifier设置为fillMaxSize(),保证能接收全屏范围的触摸事件。
内容的提问来源于stack exchange,提问作者Jéwôm'
相关产品推荐
相关产品推荐

