0

我正在尝试Card使用 Jetbrains Compose(桌面/JVM)实现具有可移动(通过拖动)工作区和图形节点的图形视图(图形节点为 s)。

我设法制作了可拖动的图形节点(GraphNodeBox),然后我想在外部节点容器(ViewBox)上检测到拖动时移动所有节点,但状态的变化不会触发图形节点的重组。我调试记录了状态更改(当所有节点偏移都更新时)并且它是在拖动手势上执行的,但 UI 没有重新渲染。

@Composable
fun ViewBox() {
    var graphNodes by remember {
        mutableStateOf(listOf(GraphNode(Item("Test Item")), GraphNode(Item("Test Item 2"))))
    }

    Box(
        modifier = Modifier.fillMaxSize()
            .background(Color.Magenta)
            .pointerInput(Unit) {
                detectDragGestures { change, dragAmount ->
                    change.consumeAllChanges()
                    graphNodes = graphNodes.map { graphNode ->
                        GraphNode.OffsetLens.modify(graphNode) { it + dragAmount }
                    }
                }
            }
    ) {
        graphNodes.forEach { // it happens only once initially and is not called again when `graphNodes` state is changed
            GraphNodeBox(it)
        }
    }
}

@Composable
fun GraphNodeBox(graphNode: GraphNode) {
    var offset by remember { mutableStateOf(IntOffset(0, 0)) }

    Card(
        modifier = Modifier.padding(5.dp)
            .offset { offset }
            .pointerInput(Unit) {
                detectDragGestures { change, dragAmount ->
                    change.consumeAllChanges()
                    offset += IntOffset(dragAmount.x.toInt(), dragAmount.y.toInt()) // this works like a charm and the offset update triggers recomposition
                }
            }
    ) {
        Row {
            Column(modifier = Modifier.padding(10.dp)) {
                Text(
                    text = graphNode.item.name,
                    style = MaterialTheme.typography.subtitle1
                )
                Text(
                    text = graphNode.item.stereotypes.joinToString { it.toString() },
                    style = MaterialTheme.typography.subtitle2
                )
            }
        }
    }
}

data class GraphNode(
    val item: Item,
    val offset: Offset = Offset(0f, 0f)
) {
    companion object {
        val OffsetLens: Lens<GraphNode, Offset> = PLens(
            get = { it.offset },
            set = { graphNode, value -> graphNode.copy(offset = value) }
        )
    }
}

看起来外部可组合的状态更新对嵌套的可组合没有影响。

我可能错过了 Jetbrains Compose 的想法,它应该以其他方式实现,但我无法提出正确的实现。

4

0 回答 0