重组一个Canvas,同时保持之前的绘图

Recompose a Canvas while maintaining the previous drawing

此函数在 canvas 上绘制图形,但是当我单击按钮时,它仅显示最新单击的图形,但我想显示之前单击的所有图形。 我认为 drawScope 状态可以被记住为可变状态,但如何实现它。

请帮忙...

    @Composable
    fun PaintBrushLayout(
        modifier: Modifier = Modifier,
    ) {
var clicked by remember {
    mutableStateOf(false)
}
var figName by remember {
    mutableStateOf("")
}

Column(
    verticalArrangement = Arrangement.Bottom, modifier = modifier.fillMaxSize()
) {
    
    Canvas(
        modifier = Modifier
            .fillMaxWidth()
            .fillMaxHeight(.9f)
    ) {
        Log.d("in Paint", "PaintBrushLayout: $this")
        if (clicked) {
                Log.d("TAG", "PaintBrushLayout: $figName")
                when (figName) {
                    "Circle" -> {
                        drawCircleFig(color = Color.Blue)
                    }
                    "Rectangle" -> {
                        drawRectangleFig()
                    }
                    "Oval" -> {
                        drawOvalFig(color = Color.Gray)
                    }

                }
        }

    }

    Row(
        modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween
    ) {

        BottomLayout("Circle") { click, name ->
            clicked = click
            figName = name
        }
        BottomLayout("Rectangle") { click, name ->
            clicked = click
            figName = name
        }
        BottomLayout("Oval") { click, name ->
            clicked = click
            figName = name
        }
        BottomLayout("Choose Color") { click, name ->
            clicked = click
           // figName = name
        }
    }
}
    }

创建按钮的底部布局

    @Composable
    fun BottomLayout(
btnName: String,
click: (Boolean, String) -> Unit
    ) {
Button(onClick = {
    click(true, btnName)

}, modifier = Modifier.padding(4.dp)) {
    Text(text = btnName)
}

    }

在 canvas

上画圆圈图
    fun DrawScope.drawCircleFig(color: Color = Color.Red) {
drawCircle(
    color = color
)
    }

在 canvas

上绘制矩形图形
    fun DrawScope.drawRectangleFig(color: Color = Color.Red) {
drawRect(
    color = color
)
    }

在 canvas

上画椭圆形
    fun DrawScope.drawOvalFig(color: Color = Color.Red) {
drawOval(
    color = color
)
    }

我不知道是否可以重组 Canvas 并保持其之前的状态,让您可以在已有的基础上进行绘制。一种解决方案是跟踪您要执行的操作的队列,然后每次 Canvas 重新组合时,您遍历队列并绘制每个项目。如果这是一个绘图应用程序,它的好处是允许用户撤消之前的步骤。我还注意到,当您单击按钮时,您提供的代码不会重新组合。我以前注意到过这个问题。解决方案是将记住的值分配给另一个值。这是使用队列的示例:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val queue = mutableListOf<DrawingObject>()
            PaintBrushLayout(queue = queue)
        }
    }
}

@Composable
fun PaintBrushLayout(
    modifier: Modifier = Modifier,
    queue: MutableList<DrawingObject>
) {
    var currentDrawingObject by remember { mutableStateOf(DrawingObject.None) }
    var c = currentDrawingObject // This fixes a bug in recomposition.

    fun addToQueue(drawingObject: DrawingObject) {
        queue.add(drawingObject)
        currentDrawingObject = drawingObject
    }

    Column(
        verticalArrangement = Arrangement.Bottom, modifier = modifier.fillMaxSize()
    ) {

        Canvas(
            modifier = Modifier
                .fillMaxWidth()
                .fillMaxHeight(.9f)
        ) {
            queue.forEach { drawingObject ->
                when (drawingObject) {
                    DrawingObject.Circle -> {
                        drawCircleFig(color = Color.Blue)
                    }
                    DrawingObject.Rectangle -> {
                        drawRectangleFig()
                    }
                    DrawingObject.Oval -> {
                        drawOvalFig(color = Color.Gray)
                    }
                }
            }
        }

        Row(
            modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween
        ) {

            BottomLayout("Circle") { click, name ->
                addToQueue(DrawingObject.Circle)
            }
            BottomLayout("Rectangle") { click, name ->
                addToQueue(DrawingObject.Rectangle)
            }
            BottomLayout("Oval") { click, name ->
                addToQueue(DrawingObject.Oval)
            }
            BottomLayout("Choose Color") { click, name ->

            }
        }
    }
}

@Composable
fun BottomLayout(
    btnName: String,
    click: (Boolean, String) -> Unit
) {
    Button(onClick = {
        click(true, btnName)

    }, modifier = Modifier.padding(4.dp)) {
        Text(text = btnName)
    }
}

fun DrawScope.drawCircleFig(color: Color = Color.Red) {
    drawCircle(
        radius = 300f,
        color = color
    )
}

fun DrawScope.drawRectangleFig(color: Color = Color.Red) {
    drawRect(
        size = Size(200f, 200f),
        color = color
    )
}

fun DrawScope.drawOvalFig(color: Color = Color.Red) {
    drawOval(
        size = Size(100f, 100f),
        color = color
    )
}

enum class DrawingObject {
    None,
    Circle,
    Rectangle,
    Oval
}