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

Jetpack Compose LazyColumn中rememberSwipeableState状态复用问题

问题解决方案

1. 为LazyColumn条目指定唯一Key

LazyColumn默认按条目在列表中的位置复用Composable实例,删除中间条目后,后续条目会继承被删除条目的swipe状态。解决方法是给items函数传入唯一的key参数,绑定每个item的唯一标识(比如item.id):

var dailyItems = viewModel.getItems().observeAsState(initial = emptyList())

LazyColumn(...) {
   items(dailyItems.value, key = { item -> item.id }) { item ->
                SomeItem(
                    item = item,
                )
            }
}

2. 修复confirmStateChange引用旧item.id的问题

rememberSwipeableState的confirmStateChange lambda会捕获初始重组时的item.id,后续重组不会自动更新这个引用。需要用rememberUpdatedState包装item.id,确保触发状态变更时能拿到最新的id:

@Composable
private fun SomeItem(
  item: Item,
  onActionsReveal: (String) -> Unit // 假设onActionsReveal是外部传入的回调
) {
    // 用rememberUpdatedState保留最新的item.id引用
    val currentItemId = rememberUpdatedState(item.id)

    val swipeState = rememberSwipeableState(
        initialValue = ItemState.HIDDEN,
        confirmStateChange = {
            // 使用currentItemId.value获取当前条目最新的id
            onActionsReveal(currentItemId.value)
            true
        }
    )

   Box(
        Modifier.swipeable(
            state = swipeState,
            anchors = anchors,
            orientation = Orientation.Horizontal,
            enabled = true,
            reverseDirection = isRtl
        )
    ) {
      ...
    }
}

原理说明

  • 指定key后,LazyColumn会根据item.id识别每个条目,删除操作后不会复用其他条目的Composable实例,每个条目拥有独立的swipe状态。
  • rememberUpdatedState会在item.id变化时更新内部引用,确保confirmStateChange触发时使用的是当前条目最新的id,而非初始捕获的旧值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 23:41:10