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

如何禁用Jetpack Compose中SwipeToDismissBox特定项的删除?

禁用SwipeToDismissBox特定列表项的滑动删除功能

我参考YouTube示例实现了SwipeToDismissBox组件,需要禁止特定列表项(例如“Kotlin”)的删除操作。之前尝试在onDelete方法中处理,但滑动操作并未被禁用,因此寻求能够禁用特定项滑动删除的解决方案。

解决方案

核心思路是给滑动容器添加开关控制,在滑动状态变更前拦截操作,同时彻底禁用滑动交互。以下是修改后的完整代码:

1. 修改SwipeToDeleteContainer组件,添加滑动控制参数

给组件新增isSwipeEnabled参数,用来控制当前项是否允许滑动删除:

@Composable
fun <T> SwipeToDeleteContainer(
    item: T,
    onDelete: (T) -> Unit,
    isSwipeEnabled: Boolean = true, // 新增滑动控制参数
    animationDuration: Int = 500,
    content: @Composable (T) -> Unit,
) {
    var isRemoved by remember {
        mutableStateOf(false)
    }
    val state = rememberSwipeToDismissBoxState(
        confirmValueChange = { value ->
            // 不允许滑动时直接拦截状态变更
            if (!isSwipeEnabled) return@rememberSwipeToDismissBoxState false
            
            if (value == SwipeToDismissBoxValue.EndToStart) {
                isRemoved = true
                true
            } else {
                false
            }
        },
    )

    LaunchedEffect(key1 = isRemoved) {
        if (isRemoved) {
            delay(animationDuration.toLong())
            onDelete(item)
        }
    }

    AnimatedVisibility(
        visible = !isRemoved,
        exit = shrinkVertically(
            animationSpec = tween(durationMillis = animationDuration),
            shrinkTowards = Alignment.Top,
        ) + fadeOut(),
    ) {
        // 禁用滑动时直接渲染内容,跳过SwipeToDismissBox
        if (!isSwipeEnabled) {
            content(item)
        } else {
            SwipeToDismissBox(
                state = state,
                backgroundContent = {
                    DeleteBackground(swipeDismissState = state)
                },
            ) {
                content(item)
            }
        }
    }
}

2. 在调用组件时,给特定项设置禁用滑动

在MainActivity的LazyColumn中,给需要禁止删除的项(比如“Kotlin”)设置isSwipeEnabled = false:

LazyColumn(
    modifier = Modifier
        .fillMaxSize(),
) {
    items(
        items = programmingLanguages,
        key = { it },
    ) { language ->
        SwipeToDeleteContainer(
            item = language,
            onDelete = {
                programmingLanguages -= language
            },
            isSwipeEnabled = language != "Kotlin" // 禁止Kotlin项的滑动删除
        ) { language ->
            Text(
                text = language,
                modifier = Modifier
                    .fillMaxWidth()
                    .background(MaterialTheme.colorScheme.background)
                    .padding(16.dp),
            )
        }
    }
}

修改说明

  • 通过新增isSwipeEnabled参数,实现对单个列表项的滑动权限控制
  • 在confirmValueChange中拦截状态变更,确保不允许滑动的项无法触发删除流程
  • 对禁用滑动的项直接跳过SwipeToDismissBox包裹,彻底消除滑动交互,比仅拦截状态更彻底

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 20:13:13