我已经使用了无限动画的权重或改变了宽度,但它不是在下面的gif中显示的效果.我如何在Jetpack Compose中实现它?

推荐答案

您可以创建随进度更改右侧的形状,并将一个长方体剪裁在另一个长方体之上.

结果

enter image description here

实施

@Composable
private fun BeforeAfterLayout(
    modifier: Modifier = Modifier,
    progress: Float,
    beforeLayout: @Composable BoxScope.() -> Unit,
    afterLayout: @Composable BoxScope.() -> Unit
) {

    val shape = remember(progress) {
        GenericShape { size: Size, layoutDirection: LayoutDirection ->
            addRect(
                rect = Rect(
                    topLeft = Offset.Zero,
                    bottomRight = Offset(size.width * progress, size.height)
                )
            )
        }
    }

    Box(modifier) {
        beforeLayout()

        Box(
            modifier = Modifier.clip(shape)
        ) {
            afterLayout()
        }
    }
}

演示

@Preview
@Composable
private fun BeforeAfterTest() {

    val infiniteTransition = rememberInfiniteTransition("before-after")
    val progress by infiniteTransition.animateFloat(
        initialValue = 0f,
        targetValue = 1f,
        animationSpec = infiniteRepeatable(
            animation = tween(2000, easing = LinearEasing),
            repeatMode = RepeatMode.Reverse
        ),
        label = "before-after"
    )

    Column(
        modifier = Modifier.padding(20.dp)
    ) {

        BeforeAfterLayout(
            modifier = Modifier.size(240.dp).border(2.dp, Color.Red),
            progress = progress,
            beforeLayout = {
                Image(
                    modifier = Modifier.fillMaxSize(),
                    painter = painterResource(R.drawable.avatar_1_raster),
                    contentDescription = null,
                    contentScale = ContentScale.FillBounds
                )
            },
            afterLayout = {
                Image(
                    modifier = Modifier.fillMaxSize(),
                    painter = painterResource(R.drawable.avatar_5_raster),
                    contentDescription = null,
                    contentScale = ContentScale.FillBounds
                )
            }
        )

        BeforeAfterLayout(
            progress = progress,
            beforeLayout = {
                Button(
                    modifier = Modifier.width(150.dp),
                    onClick = {}
                ) {
                    Text("Before Button")
                }
            },
            afterLayout = {
                Button(
                    modifier = Modifier.width(150.dp),
                    colors = ButtonDefaults.buttonColors(
                        backgroundColor = Color.Green
                    ),
                    onClick = {}
                ) {
                    Text("After Button")
                }
            }
        )
    }
}

第二种方法是使用BlendMode.Clear,并将lambda中的进度传递给动画,并将其重组为

@Composable
private fun BeforeAfterLayoutWithBlendMode(
    modifier: Modifier = Modifier,
    progress: () -> Float,
    beforeLayout: @Composable BoxScope.() -> Unit,
    afterLayout: @Composable BoxScope.() -> Unit
) {
    Box(modifier) {
        beforeLayout()

        Box(
            modifier = Modifier
                .graphicsLayer {
                    compositingStrategy = CompositingStrategy.Offscreen
                }
                .drawWithContent {
                    drawContent()
                    drawRect(
                        color = Color.Transparent,
                        size = Size(size.width * (1 - progress()), size.height),
                        blendMode = BlendMode.Clear
                    )

                }
        ) {
            afterLayout()
        }
    }
}

另一种方法是,如果它只是你想要画的图像,在画布上画2个图像,然后改变第二个drawImage函数的dstOffset.

也可作为具有许多定制选项的库使用.

https://github.com/SmartToolFactory/Compose-BeforeAfter

Android相关问答推荐

view喷气背包中找不到模型组成

如何在Android Room中使用@Relation多对一查询

Android 14上的慢速意图广播交付

无法将项目添加到文件室数据库

如何删除Jetpack Compose中的Textfield底线

StateFlow集合AsState没有更新他的值Jetpack Compose导航

Kotlin Android VS Kotlin多平台

使用Android Jetpack Compose,为子Composable定义ViewModel是不是一种糟糕的做法?

如何制作安卓';s FileProvider在Android 11上使用外部存储+

Spinner - onItemLongClick 从未执行

如何删除房间数据库?

NFC getNdefMessage 在 Android 13 上写入标签后返回 null

Jetpack Compose 部分或开放侧边框

组成不重叠的元素

Android collectAsStateWithLifecycle() 不在可组合内部收集

GridLayout 和 GridView 有什么好用和区别

Kotlin Coroutines Dispatchers.IO 没有创建预期的线程

我的 react native 项目的发布签名 apk 没有在设备中打开,而且它创建的尺寸非常小

WindowManager 内的 RecyclerView 不更新

更新应用程序是否会取消对应用程序特定文件的权限?