Jetpack Compose划动组件 - SwipeBox在列表中使用

背景

上一篇文章中,我介绍了一个自己写的Compose划动组件。它可以向左或向右滑动以显示操作按钮并支持自定义设计操作按钮。它还提供了封装好的文字和
按钮组件:SwipeIcon 和 SwipeText,用于通用操作按钮。

该组件最常用的使用场景就是在列表中组合使用。但是这就要求某个已经划开的组件在列表发生滚动或其他item被划开时,需要自动恢复原样。否则的话会出现多个列表项都处于展开状态的情况,用户体验不好。而这个组件在设计的时候就考虑到了这种情况并提供了解决方案。这篇文章我们将介绍如何在列表中支持该能力。

状态创建

首先,我们需要定义一个SwipeableState来保存当前打开的列表项的划动状态,方便我们后续将其归位

var currentSwipeState: SwipeableState<Int>? by remember {
    mutableStateOf(null)
}

更新状态

然后,我们需要定义一个回调并传递给SwipeBox组件,用来更新当前展开的列表项及处理列表项之间的互斥逻辑

val onSwipeStateChanged = { state : SwipeableState<Int> ->/**     * if it is swiping back and it equals to the current state     * it means that the current open box is closed, then we set the state to null     */if (state.targetValue == 0 && currentSwipeState == state) {
        currentSwipeState = null
    }
    // if there is no opening box, we set it to this opening oneelse if (currentSwipeState == null) {
        currentSwipeState = state
    } else {
        // there already had one box opening, we need to swipe it back and then update the state to new one
        coroutineScope.launch {
            currentSwipeState!!.animateTo(0)
            currentSwipeState = state
        }
    }

}


SwipeBox(onSwipeStateChanged){  state, _, _ ->// callback on parent when the state targetValue changes which means it is swiping to another state.LaunchedEffect(state.targetValue) {
        onSwipeStateChanged(state)
    }
}

可以看到,我们在每次划动状态发生改变时,都将之前已经展开的item复位,并更新最新的状态,用于下一次归位使用。

拦截滚动

最后,我们需要定义一个nestedScrollConnection用来拦截列表的滚动,这样我们就能在滚动时将展开的列表项复位

val nestedScrollConnection = remember {
    object : NestedScrollConnection {
        /**         * we need to intercept the scroll event and check whether there is an open box         * if so ,then we need to swipe that box back and reset the state         */
    override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
            if (currentSwipeState != null && currentSwipeState!!.currentValue != 0) {
                coroutineScope.launch {
                    currentSwipeState!!.animateTo(0)
                    currentSwipeState = null
                }
            }
            return Offset.Zero
        }
    }
}

LazyColumn(
    modifier = Modifier
        .nestedScroll(nestedScrollConnection)
)

这里我们创建了一个nestedScrollConnection来拦截列表滚动,它会感知到列表滚动事件,并将当前展开的划动组件归位。这样就可以保证列表划动时不会有展开的划动组件。

总结

完成这三步后,我们就实现了划动组件在列表中自动复位的能力了。完整示例可以参考:https://github.com/KevinnZou/compose-swipeBox/blob/main/app/src/main/java/com/kevinnzou/compose/composeswipebox/SwipeBoxList.kt

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值