代码之家  ›  专栏  ›  技术社区  ›  Alex Bro

在Jetpack Compose上拖动第一个可拖动项目时,该项目不在行中其他项目的顶部

  •  1
  • Alex Bro  · 技术社区  · 1 年前

    我收藏了五件物品,它们都可以拖动。我希望实现拖动项目与所有其他项目重叠的行为。我尝试更改zIndex参数,但不起作用,我做错了什么?

    项目代码:

    @Composable
    fun <T> DragTarget(
    dataToDrop: T,
    content: @Composable () -> Unit) {
    
    var dragOffset by remember { mutableStateOf(Offset.Zero) }
    var currentPosition by remember { mutableStateOf(Rect.Zero) }
    val currentState = LocalDragTargetInfo.current
    
    Box(
        modifier = Modifier
            .zIndex(if (currentState.isDragging) 5f else 0f) // my first try
            .offset {
                IntOffset(
                    dragOffset.x.roundToInt(),
                    dragOffset.y.roundToInt()
                )
            }
            .onGloballyPositioned { layout ->
                layout
                    .boundsInWindow()
                    .let { rect ->
                        currentPosition = rect
                    }
            }
            .pointerInput(dataToDrop) {
                detectDragGestures(
                    onDragStart = {
                        currentState.isDragging = true
                        currentState.dataToDrop = dataToDrop
                        currentState.dragPosition = currentPosition
                    },
                    onDrag = { change, dragAmount ->
                        change.consume()
                        dragOffset += dragAmount
                        currentState.dragPosition = currentPosition
                    },
                    onDragEnd = {
                        currentState.isDragging = false
                        dragOffset = Offset.Zero
                        currentState.dragPosition = Rect.Zero
                    }
                )
            },
        contentAlignment = Alignment.Center
    ) {
        content()
    }}
    

    项目收集代码

    @Composable
    fun TestView() {
    Row(
        modifier = Modifier.fillMaxSize(),
        horizontalArrangement = Arrangement.spacedBy(16.dp, alignment = Alignment.CenterHorizontally),
        verticalAlignment = Alignment.CenterVertically
    ) {
        DragTarget(dataToDrop = null) {
            Box(modifier = Modifier.zIndex(5f) // my second try
                             .size(50.dp).background(Color.Blue))
        }
        DragTarget(dataToDrop = null) {
            Box(modifier = Modifier.size(50.dp).background(Color.Green))
        }
        DragTarget(dataToDrop = null) {
            Box(modifier = Modifier.size(50.dp).background(Color.LightGray))
        }
        DragTarget(dataToDrop = null) {
            Box(modifier = Modifier.size(50.dp).background(Color.Yellow))
        }
        DragTarget(dataToDrop = null) {
            Box(modifier = Modifier.size(50.dp).background(Color.Red))
        }
    }}
    

    以及我的DragTargetInfo:

    class DragTargetInfo {
    var isDragging by mutableStateOf(false)
    var dragPosition by mutableStateOf(Rect.Zero)
    var dataToDrop by mutableStateOf<Any?>(null)}
    
    val LocalDragTargetInfo = compositionLocalOf { DragTargetInfo() }
    

    我将非常感谢任何提示,因为我已经努力解开这个纠结好几天了,并达到了预期的效果。祝所有朋友平安)

    1 回复  |  直到 1 年前
        1
  •  1
  •   Yamin    1 年前

    一个解决方案是搬家 zIndex 将其转化为状态变量,并使其独立于 currentState.isDragging 并直接更改其值 onDragStart onDragEnd 拉姆达斯。

    @Composable
    fun <T> DragTarget(
        dataToDrop: T,
        content: @Composable BoxScope.() -> Unit
    ) {
        var dragOffset by remember { mutableStateOf(Offset.Zero) }
        var currentPosition by remember { mutableStateOf(Rect.Zero) }
        val currentState = LocalDragTargetInfo.current
    
        var zIndex by remember { mutableFloatStateOf(0f) }
    
        Box(
            modifier = Modifier
                .zIndex(zIndex)
                .offset {
                    IntOffset(
                        dragOffset.x.roundToInt(),
                        dragOffset.y.roundToInt()
                    )
                }
                .onGloballyPositioned { layout ->
                    layout
                        .boundsInWindow()
                        .let { rect ->
                            currentPosition = rect
                        }
                }
                .pointerInput(dataToDrop) {
                    detectDragGestures(
                        onDragStart = {
                            currentState.isDragging = true
                            currentState.dataToDrop = dataToDrop
                            currentState.dragPosition = currentPosition
                            zIndex = 1f
                        },
                        onDrag = { change, dragAmount ->
                            change.consume()
                            dragOffset += dragAmount
                            currentState.dragPosition = currentPosition
                        },
                        onDragEnd = {
                            currentState.isDragging = false
                            dragOffset = Offset.Zero
                            currentState.dragPosition = Rect.Zero
                            zIndex = 0f
                        }
                    )
                },
            contentAlignment = Alignment.Center,
            content = content
        )
    }
    
    @Composable
    fun TestView() {
        Row(
            modifier = Modifier.fillMaxSize(),
            horizontalArrangement = Arrangement.spacedBy(
                16.dp,
                alignment = Alignment.CenterHorizontally
            ),
            verticalAlignment = Alignment.CenterVertically
        ) {
            DragTarget(dataToDrop = "Blue") {
                Box(
                    modifier = Modifier
                        .size(50.dp)
                        .background(Color.Blue)
                )
            }
            DragTarget(dataToDrop = "Green") {
                Box(
                    modifier = Modifier
                        .size(50.dp)
                        .background(Color.Green)
                )
            }
            DragTarget(dataToDrop = "Gray") {
                Box(
                    modifier = Modifier
                        .size(50.dp)
                        .background(Color.LightGray)
                )
            }
            DragTarget(dataToDrop = "Yellow") {
                Box(
                    modifier = Modifier
                        .size(50.dp)
                        .background(Color.Yellow)
                )
            }
            DragTarget(dataToDrop = "Red") {
                Box(
                    modifier = Modifier
                        .size(50.dp)
                        .background(Color.Red)
                )
            }
        }
    }