gpt4 book ai didi

android - 如果我想在滑动后调用操作,如何在 Compose 中实现滑动

转载 作者:行者123 更新时间:2023-12-04 23:46:39 28 4
gpt4 key购买 nike

我在撰写时遇到问题。我尝试实现简单的日历。我已经显示了月份,并启用了通过箭头更改月份。
enter image description here
现在我想通过滑动添加更改月份。
我试过 .swipeable这是示例:

val size = remember { mutableStateOf(Size.Zero) }
val swipeableState = rememberSwipeableState(0)
val width = if (size.value.width == 0f) 1f else size.value.width - 60.dp.value * 2
Box(
modifier = Modifier
.fillMaxWidth()
.onSizeChanged { size.value = Size(it.width.toFloat(), it.height.toFloat()) }
.swipeable(
state = swipeableState,
anchors = mapOf(0f to 0, width to 1),
thresholds = { _, _ -> FractionalThreshold(0.3f) },
orientation = Orientation.Horizontal
)
.background(Color.LightGray)
) {
Box(
Modifier
.offset { IntOffset(swipeableState.offset.value.roundToInt(), 0) }
.size(60.dp)
.background(Color.DarkGray)
)
}
但这并不完美。我需要在日历区域之外举行,我不知道如何更改月份的状态(响应显示日历)。
我的问题是“如果我想在滑动后调用 Action ,如何实现滑动”。

最佳答案

您可以使用 Side Effects 观察任何状态.如果您需要等待操作完成,可以使用 if + DisposableEffect :

if (swipeableState.isAnimationRunning) {
DisposableEffect(Unit) {
onDispose {
println("animation finished")
}
}
}
当动画开始时,我创建了一个 DisposableEffect当它结束时, onDispose被调用,表示动画结束。
对于您的代码,这也将在启动时触发,因为当您在 onSizeChanged 之后更改 anchor 时,这也开始了动画。但是你可以检查值是否已经改变,所以这不是什么大问题。
要解决你的基本问题,你还需要有左、中、右三种状态。

有点题外话,关于那条线:
val width = if (size.value.width == 0f) 1f else size.value.width - 60.dp.value * 2
  • 每次重构时都重复这个计算,你不应该那样做。您可以使用 rememebersize.value.width作为关键,因为 width仅当该值更改时才需要重新计算。
  • 您试图通过乘以 2 从 DP 中获取像素值。这是错误的,您需要使用 Density。

  • 所以最终的代码可以是这样的:
    enum class SwipeDirection(val raw: Int) {
    Left(0),
    Initial(1),
    Right(2),
    }

    @Composable
    fun TestScreen() {
    var size by remember { mutableStateOf(Size.Zero) }
    val swipeableState = rememberSwipeableState(SwipeDirection.Initial)
    val density = LocalDensity.current
    val boxSize = 60.dp
    val width = remember(size) {
    if (size.width == 0f) {
    1f
    } else {
    size.width - with(density) { boxSize.toPx() }
    }
    }
    val scope = rememberCoroutineScope()
    if (swipeableState.isAnimationRunning) {
    DisposableEffect(Unit) {
    onDispose {
    when (swipeableState.currentValue) {
    SwipeDirection.Right -> {
    println("swipe right")
    }
    SwipeDirection.Left -> {
    println("swipe left")
    }
    else -> {
    return@onDispose
    }
    }
    scope.launch {
    // in your real app if you don't have to display offset,
    // snap without animation
    // swipeableState.snapTo(SwipeDirection.Initial)
    swipeableState.animateTo(SwipeDirection.Initial)
    }
    }
    }
    }
    Box(
    modifier = Modifier
    .fillMaxWidth()
    .onSizeChanged { size = Size(it.width.toFloat(), it.height.toFloat()) }
    .clickable { }
    .swipeable(
    state = swipeableState,
    anchors = mapOf(
    0f to SwipeDirection.Left,
    width / 2 to SwipeDirection.Initial,
    width to SwipeDirection.Right,
    ),
    thresholds = { _, _ -> FractionalThreshold(0.3f) },
    orientation = Orientation.Horizontal
    )
    .background(Color.LightGray)
    ) {
    Box(
    Modifier
    .offset { IntOffset(swipeableState.offset.value.roundToInt(), 0) }
    .size(boxSize)
    .background(Color.DarkGray)
    )
    }
    }
    结果:

    p.s.如果您不需要在滑动过程中设置任何动画,我已将此逻辑移至 separate modifier .

    关于android - 如果我想在滑动后调用操作,如何在 Compose 中实现滑动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69101453/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com