Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/230.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何将布局修改器应用于Jetpack Compose中的每个可放置组件?_Android_Android Jetpack Compose - Fatal编程技术网

Android 如何将布局修改器应用于Jetpack Compose中的每个可放置组件?

Android 如何将布局修改器应用于Jetpack Compose中的每个可放置组件?,android,android-jetpack-compose,Android,Android Jetpack Compose,我的自定义布局中有一个可拖动的修改器。问题是,我的所有可放置对象都作为一个块移动,而我希望它们单独移动。正确的循环方式是什么,以确保一次只选择一个可放置项?还是有更好的方法?以下是我的自定义布局: @Composable fun CustomLayout( modifier: Modifier = Modifier, content: @Composable() () -> Unit ) { val coroutineScope = rememberCoro

我的自定义布局中有一个可拖动的修改器。问题是,我的所有可放置对象都作为一个块移动,而我希望它们单独移动。正确的循环方式是什么,以确保一次只选择一个可放置项?还是有更好的方法?以下是我的自定义布局:

    @Composable
fun CustomLayout(
    modifier: Modifier = Modifier,
    content: @Composable() () -> Unit
) {
    val coroutineScope = rememberCoroutineScope()
    val offsetX = remember { Animatable(0f) }
    val offsetY = remember { Animatable(0f) }

    Layout(
        modifier = modifier
            .offset {
                IntOffset(
                    offsetX.value.roundToInt(),
                    offsetY.value.roundToInt()
                )
            }
            .draggable(
                state = rememberDraggableState { delta ->
                    coroutineScope.launch {
                        offsetX.snapTo(offsetX.value + delta)
                    }
                },
                orientation = Orientation.Horizontal,
                onDragStarted = {},
                onDragStopped = {

                    coroutineScope.launch {

                        offsetX.animateTo(
                            targetValue = 0f,
                            animationSpec = tween(
                                durationMillis = 1000,
                                delayMillis = 0
                            )
                        )
                    }
                }
            ),
        content = content
    ) { measurables, constraints ->
        val tileSize = constraints.maxWidth / 7
        val childConstraints = constraints.copy(
            minWidth = minOf(constraints.minWidth, tileSize),
            maxWidth = tileSize
        )
        val placeables = measurables.map { measurable ->
            measurable.measure(childConstraints)
        }

        layout(constraints.maxWidth, constraints.maxHeight) {
            var yPosition = 0
            val xPosition = 0
            placeables.forEachIndexed { index, placeable ->
                if (index <= 6) {
                    placeable.placeRelative(x = xPosition, y = yPosition)
                } else {
                    placeable.placeRelative(
                        constraints.maxWidth - tileSize,
                        yPosition - placeable.height * 7
                    )
                }
                yPosition += placeable.height
            }
        }
    }
}
@Composable
趣味定制布局(
修饰符:修饰符=修饰符,
内容:@Composable()()->Unit
) {
val coroutineScope=rememberCoroutineScope()
val offsetX=记住{Animatable(0f)}
val offsetY=记住{Animatable(0f)}
布局(
修饰语=修饰语
.抵消{
抵消(
offsetX.value.roundToInt(),
offsetY.value.roundToInt()
)
}
.拖拉(
state=rememberdraggalestate{delta->
协同观测发射{
offsetX.snapTo(offsetX.value+delta)
}
},
方向=方向。水平,
onDragStarted={},
onDragStopped={
协同观测发射{
offsetX.animateTo(
targetValue=0f,
animationSpec=吐温(
持续时间毫秒=1000,
延迟毫秒=0
)
)
}
}
),
内容=内容
){可测量,约束->
val tileSize=constraints.maxWidth/7
val childConstraints=constraints.copy(
minWidth=minOf(constraints.minWidth,tileSize),
maxWidth=tileSize
)
val placeables=measureables.map{measured->
可测量。测量(儿童约束)
}
布局(constraints.maxWidth、constraints.maxHeight){
变量yPosition=0
val xPosition=0
placeables.foreachinedexed{index,placeable->

如果(index您的解决方案不起作用,因为您将偏移应用于整个布局,但需要将其应用于单个项目

Layout
仅用于布局项目:在
MeasureScope
中,我们只能访问项目大小/位置,不能向其添加修饰符,因为这些修饰符将修改状态并导致递归

我的建议是将items count和item generator传递给您的Composable,这样我们就可以为每个项目添加偏移和可拖动的修饰符:

@Composable
fun DraggableLayout(
    modifier: Modifier = Modifier,
    count: Int,
    item: @Composable (Int, Modifier) -> Unit
) {
    val coroutineScope = rememberCoroutineScope()
    val offsetsX = remember { mutableStateMapOf<Int, Animatable<Float, AnimationVector1D>>() }
    CustomLayout(
        modifier = modifier,
        content = {
            for (i in 0 until count) {
                item(
                    i,
                    Modifier
                        .offset {
                            IntOffset(
                                offsetsX[i]?.value?.roundToInt() ?: 0,
                                0
                            )
                        }
                        .draggable(
                            state = rememberDraggableState { delta ->
                                coroutineScope.launch {
                                    val offsetX = offsetsX[i] ?: Animatable(0f)
                                    offsetX.snapTo(offsetX.value + delta)
                                    offsetsX[i] = offsetX
                                }
                            },
                            orientation = Orientation.Horizontal,
                            onDragStarted = {},
                            onDragStopped = {
                                coroutineScope.launch {
                                    offsetsX[i]!!.animateTo(
                                        targetValue = 0f,
                                        animationSpec = tween(
                                            durationMillis = 1000,
                                            delayMillis = 0
                                        )
                                    )
                                }
                            }
                        ),
                )
            }
        }
    )
}

@Composable
fun CustomLayout(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit
) {
    Layout(
        modifier = modifier,
        content = content,
    ) { measurables, constraints ->
        val tileSize = constraints.maxWidth / 7
        val childConstraints = constraints.copy(
            minWidth = minOf(constraints.minWidth, tileSize),
            maxWidth = tileSize
        )
        val placeables = measurables.map { measurable ->
            measurable.measure(childConstraints)
        }

        layout(constraints.maxWidth, constraints.maxHeight) {
            var yPosition = 0
            val xPosition = 0
            placeables.forEachIndexed { index, placeable ->
                if (index <= 6) {
                    placeable.placeRelative(x = xPosition, y = yPosition)
                } else {
                    placeable.placeRelative(
                        constraints.maxWidth - tileSize,
                        yPosition - placeable.height * 7
                    )
                }
                yPosition += placeable.height
            }
        }
    }
}
结果是:

非常感谢,这看起来是我问题的完美解决方案!尽管现在有人告诉我,我的应用程序的可拖动和动画逻辑需要与布局逻辑分开,并且我需要遵循“一个真实来源”模式。但无论如何,你建议的代码将对我有所帮助。
CustomLayout(
    count = 10,
    item = { i, modifier ->
        Text(
            "Test $i",
            modifier = Modifier
                .size(50.dp)
                .then(modifier)
        )
    }
)