Jetpack Compose中如何在指定位置绘制图像
问题描述
我需要在白色圆弧结束的特定X位置绘制图像。我已经实现了圆弧绘制,现在想在圆弧上方添加图像。尝试过相关方案绘制图像,但该方法无法指定X位置,自行修改后也无效,希望能指出问题所在。
初始代码
@Composable fun DrawProgressBar() { val activity = LocalContext.current as AppCompatActivity val rangeComposition = RangeComposition() val itemLst = rangeComposition.bpExplained val boxSize = 30.dp val brush = Brush.horizontalGradient(listOf(Color.Red, Color.Blue)) val progressBarPointer = rangeComposition.findReadingWithPointer(142, 90).second val vector = ImageVector.vectorResource(id = R.drawable.ic_rectangle) val painter = rememberVectorPainter(image = vector) Box( modifier = Modifier .background(Color.White) .height(height = boxSize) ) { Canvas( modifier = Modifier .fillMaxSize() .graphicsLayer(alpha = 0.99f) ) { val strokeWidth = 8.dp val canvasWidth = size.width val canvasHeight = size.height val strokeWidthPx = density.run { strokeWidth.toPx() } val pathEffect = PathEffect.dashPathEffect(floatArrayOf(canvasHeight / 19, canvasHeight / 19), 0f) with(painter) { draw(painter.intrinsicSize) } drawLine( start = Offset(x = 0f, y = canvasHeight / 2), end = Offset(x = canvasWidth, y = canvasHeight / 2), color = Color.Gray, strokeWidth = strokeWidthPx, cap = StrokeCap.Round, ) val progressBarPointerInPixel = (progressBarPointer / 100f) * canvasWidth drawLine( color = Color.White, start = Offset(x = progressBarPointerInPixel, y = canvasHeight / 2), end = Offset(x = progressBarPointerInPixel + strokeWidthPx / 2, y = canvasHeight / 2), strokeWidth = strokeWidthPx, blendMode = BlendMode.DstOut, ) drawLine( brush = brush, start = Offset(x = 0f, y = canvasHeight / 2), end = Offset(x = progressBarPointerInPixel, y = canvasHeight / 2), strokeWidth = strokeWidthPx, cap = StrokeCap.Round, ) drawArc( topLeft = Offset(x = progressBarPointerInPixel, y = canvasHeight / 2 - strokeWidthPx / 2), size = Size(strokeWidthPx, strokeWidthPx), color = Color.White, startAngle = -90f, sweepAngle = 180f, useCenter = true, blendMode = BlendMode.DstOut, ) itemLst.forEachIndexed { index, rangeItem -> val endPointInPixel = (rangeItem.endPoint / 100f) * canvasWidth if (index != itemLst.lastIndex) { drawLine( start = Offset(x = endPointInPixel, y = 0F), end = Offset(x = endPointInPixel, y = boxSize.toPx()), color = Color.Black, strokeWidth = 1.2.dp.toPx(), pathEffect = pathEffect ) } } } } }
实际效果

预期效果

更新:修改后效果与代码
在建议下修改后,效果如下:
修改后代码:
@Composable fun DrawProgressBar() { val activity = LocalContext.current as AppCompatActivity val rangeComposition = RangeComposition() val itemLst = rangeComposition.bpExplained val boxSize = 30.dp val brush = Brush.horizontalGradient(listOf(Color.Red, Color.Blue)) val progressBarPointer = rangeComposition.findReadingWithPointer(142, 90).second Box( modifier = Modifier .background(Color.White) .height(height = 36.dp) ) { Canvas( modifier = Modifier .fillMaxSize() ) { val rectSize = Size (30f,30f) val rect = Rect(Offset.Zero, rectSize) val trianglePath = Path().apply { moveTo(rect.bottomCenter.x, rect.bottomCenter.y) lineTo(rect.topRight.x , rect.topRight.y) lineTo(rect.topLeft.x, rect.topLeft.y) close() } drawIntoCanvas { canvas -> translate (30f,30f){ canvas.drawOutline( outline = Outline.Generic(trianglePath), paint = Paint().apply { color = Color.Black pathEffect = PathEffect.cornerPathEffect(rect.maxDimension / 3) } ) } } val strokeWidth = 8.dp val canvasWidth = size.width val canvasHeight = size.height val strokeWidthPx = density.run { strokeWidth.toPx() } val pathEffect = PathEffect.dashPathEffect(floatArrayOf(canvasHeight / 19, canvasHeight / 19), 0f) drawLine( start = Offset(x = 0f, y = canvasHeight / 2), end = Offset(x = canvasWidth, y = canvasHeight / 2), color = Color.Gray, strokeWidth = strokeWidthPx, cap = StrokeCap.Round, ) val progressBarPointerInPixel = (progressBarPointer / 100f) * canvasWidth drawLine( color = Color.White, start = Offset(x = progressBarPointerInPixel, y = canvasHeight / 2), end = Offset(x = progressBarPointerInPixel + strokeWidthPx / 2, y = canvasHeight / 2), strokeWidth = strokeWidthPx, ) drawLine( brush = brush, start = Offset(x = 0f, y = canvasHeight / 2), end = Offset(x = progressBarPointerInPixel, y = canvasHeight / 2), strokeWidth = strokeWidthPx, cap = StrokeCap.Round, ) drawArc( topLeft = Offset(x = progressBarPointerInPixel, y = canvasHeight / 2 - strokeWidthPx / 2), size = Size(strokeWidthPx, strokeWidthPx), color = Color.White, startAngle = -90f, sweepAngle = 180f, useCenter = true ) itemLst.forEachIndexed { index, rangeItem -> val endPointInPixel = (rangeItem.endPoint / 100f) * canvasWidth if (index != itemLst.lastIndex) { drawLine( start = Offset(x = endPointInPixel, y = 0F), end = Offset(x = endPointInPixel, y = boxSize.toPx()), color = Color.Black, strokeWidth = 1.2.dp.toPx(), pathEffect = pathEffect ) } } } } }
内容的提问来源于stack exchange,提问作者Compose Learner
相关产品推荐
相关产品推荐

