I have 2 composable elements with a transparent background (simple box with border and transparent background and text in it). They can be moved around the screen. But it is necessary that when one crosses the other, the one that is now moving should be clipped with the borders of the other. That's about the result I expect.enter image description here

我试图使用clipPath和Region.Op找到可能的解决方案,但我找不到一种方法来获取绘制元素的路径

通过在First下面单击来折叠第二个元素的示例代码.

enum class State {
    Collapsed,
    Expanded
}

@Composable
fun Main() {
    val cardSize = 100.dp
    var currentState by remember { mutableStateOf(State.Collapsed) }
    val transition = updateTransition(targetState = currentState, label = "expand_transition")
    val animateDpAsState by transition.animateDp(
        targetValueByState = { state ->
            when (state) {
                State.Expanded -> cardSize + 8.dp
                State.Collapsed -> 8.dp
            }
        },
        label = ""
    )

    Box(
        modifier = Modifier
            .width(cardSize + animateDpAsState)
            .clickable {
                currentState = if (currentState == State.Collapsed) {
                    State.Expanded
                } else {
                    State.Collapsed
                }
            }
    ) {
        Element(i = 1)
        Element(
            modifier = Modifier
                .offset(x = animateDpAsState + 4.dp)
                .scale(0.90f),
            i = 2
        )
    }
}

@Composable
fun Element(modifier: Modifier = Modifier, i: Int) {
    Box(
        modifier = modifier
            .size(100.dp)
            .padding(8.dp)
            .border(2.dp, Color.Black),
        contentAlignment = Alignment.Center
    ) {
        Text(text = "ITEM $i")
    }
}

推荐答案

使用Modifier.onPlaced可以在父对象中获得Rect%的合成对象.

将这Rect设置为路径并判断差异,即可得到新的Path.通过与这Path剪裁,你可以剪裁移动合成.

enum class State {
    Collapsed,
    Expanded
}

@Preview
@Composable
fun Main() {
    val cardSize = 100.dp
    var currentState by remember { mutableStateOf(State.Collapsed) }

    val pathStationary = remember {
        Path()
    }


    val pathMoving = remember {
        Path()
    }
    val transition = updateTransition(
        targetState = currentState, label = "expand_transition"
    )
    val animateDpAsState by transition.animateDp(
        targetValueByState = { state ->
            when (state) {
                State.Expanded -> cardSize + 8.dp
                State.Collapsed -> 8.dp
            }
        },
        label = ""
    )

    Box(
        modifier = Modifier
            .width(cardSize + animateDpAsState)
            .clickable {
                currentState = if (currentState == State.Collapsed) {
                    State.Expanded
                } else {
                    State.Collapsed
                }
            }
    ) {
        Element(
            modifier = Modifier.onPlaced {
                pathStationary.reset()
                pathStationary.addRect(it.boundsInParent())
            },
            i = 1
        )
        Element(
            modifier = Modifier

                .drawWithContent {
                    val diffPath =
                        Path.combine(PathOperation.Difference, path1 = pathMoving, path2 = pathStationary)

                    clipPath(diffPath){
                        this@drawWithContent.drawContent()
                    }
                }
                .offset(x = animateDpAsState + 4.dp)
                .scale(0.90f)
                .onPlaced {
                    pathMoving.reset()
                    pathMoving.addRect(it.boundsInParent())
                }
            ,
            i = 2
        )
    }
}

@Composable
fun Element(modifier: Modifier = Modifier, i: Int) {
    Box(
        modifier = modifier
            .size(100.dp)
            .border(2.dp, Color.Black),
        contentAlignment = Alignment.Center
    ) {
        Text(text = "ITEM $i")
    }
}

Android相关问答推荐

使用不同的Google帐户登录

关于BLE扫描工作原理的说明

如何在Jetpack composeH中创建具有弯曲末端的六边形形状

NativeScript在`ns run android`上重复Kotlin类

从安卓S原生库的资源中读取json文件

为什么我在 android 中使用 TabLayout 时无法启动我的 Activity?

Jetpack Compose 中的用户在线指示器

如何在 android compose 中将具有渐变边缘的透明圆圈绘制到阴影覆盖层中?

在 compose android 中创建一个圆形按钮和居中文本

Material 3 中的 ModalBottomSheet 用于 compose

从 Jetpack Compose 中的 IconButton 中删除黑色色调

用作输入参数的 Lambda 函数导致重组

React Native Android 应用程序在调试模式下运行良好,但当我们发布 apk 时,它会生成旧版本的应用程序

Jetpack Compose UI - 在 AlertDialog 中单击时按钮宽度会发生变化

Jetpack Compose Alignment - 误解了 alignBy 修饰符

缺少类 com.google.android.datatransport.runtime.ForcedSender

如何使用文件提供程序将视频从一个应用程序共享到另一个应用程序?

在 Jetpack Compose 中 Select 要省略的文本

升级到 android studio 花栗鼠后,应用程序未安装在模拟器中

如何满足设备内框架的无效 Wear OS 屏幕截图Wear OS 表盘策略违规?