Jetpack Compose Canvas重绘时保留历史绘制图形的实现问询
实现方案
核心思路
你当前代码仅存储了单个最新选中的图形标识,Canvas每次重组时只会绘制当前这一个图形,所以无法保留历史内容。我们不需要记录DrawScope的状态,只需维护一个历史图形队列的可变状态即可:
- 每次点击按钮时,把新选中的图形配置添加到队列中
- Canvas绘制时遍历队列,依次绘制所有历史图形即可保留全部内容
具体实现代码
第一步:定义图形配置数据类
用来存储每个图形的参数,后续可扩展大小、位置等属性
data class DrawingShape( val type: String, // 图形类型:Circle/Rectangle/Oval val color: Color )
第二步:修改布局代码
@Composable fun PaintBrushLayout( modifier: Modifier = Modifier, ) { // 替换原来的单值状态,改为存储所有历史图形的可变列表 val shapeList = remember { mutableStateListOf<DrawingShape>() } Column( verticalArrangement = Arrangement.Bottom, modifier = modifier.fillMaxSize() ) { Canvas( modifier = Modifier .fillMaxWidth() .fillMaxHeight(.9f) ) { // 遍历所有历史图形依次绘制 shapeList.forEach { shape -> when (shape.type) { "Circle" -> { drawCircleFig(color = shape.color) } "Rectangle" -> { drawRectangleFig(color = shape.color) } "Oval" -> { drawOvalFig(color = shape.color) } } } } Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween ) { BottomLayout("Circle") { _, _ -> // 点击时往列表添加对应图形配置 shapeList.add(DrawingShape("Circle", Color.Blue)) } BottomLayout("Rectangle") { _, _ -> shapeList.add(DrawingShape("Rectangle", Color.Red)) } BottomLayout("Oval") { _, _ -> shapeList.add(DrawingShape("Oval", Color.Gray)) } BottomLayout("Choose Color") { _, _ -> // 颜色选择逻辑可自行扩展,选中后修改后续添加图形的颜色即可 } } } } @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( color = color ) } fun DrawScope.drawRectangleFig(color: Color = Color.Red) { drawRect( color = color ) } fun DrawScope.drawOvalFig(color: Color = Color.Red) { drawOval( color = color ) }
优化建议
如果不想所有图形都重叠在一起,可以在DrawingShape中添加center: Offset、size: Size等参数,每次点击按钮添加图形时随机生成这些参数,即可实现不同位置大小的图形绘制效果。
内容的提问来源于stack exchange,提问作者hemant
相关产品推荐
相关产品推荐

