Jetpack Compose 用圆点绘制圆弧
Jetpack Compose Draw Arc with Dot Circle
我想在 Jetpack Compose 中的 canvas 上画一个圆弧,在进度的边缘画一个小圆圈,如下图所示:
我找到了如何用圆弧绘制进度条canvas,但还不知道如何绘制圆来匹配圆弧线的边缘。这是我的进度代码:
@Composable
fun ComposeCircularProgressBar(
modifier: Modifier = Modifier,
percentage: Float,
fillColor: Color,
backgroundColor: Color,
strokeWidth: Dp
) {
Canvas(
modifier = modifier
.padding(strokeWidth / 2)
) {
// Background Line
drawArc(
color = backgroundColor,
135f,
270f,
false,
style = Stroke(strokeWidth.toPx(), cap = StrokeCap.Butt)
)
// Fill Line
drawArc(
color = fillColor,
135f,
270f * percentage,
false,
style = Stroke(strokeWidth.toPx(), cap = StrokeCap.Round)
)
}
}
注意:目前我知道用 Canvas.drawCircle(offset = Offset)
绘制圆圈,但我还不知道如何计算 Offset(x,y)
以匹配进度的边缘。
下面的这段代码将根据您提供的百分比生成带有圆点的圆弧。您确实答对了大部分内容,只是求解数学方程式以找到圆上的点。
我假设圆的半径为小部件的高度/2。
由于我们没有绘制完整的圆,因此起始角为 140 度,最大扫描角为 260 度。 (我通过点击和试用找到了这个,所以它看起来和你的图片很接近)
现在要绘制白色小圆圈,中心 a.k.a offset 必须位于 (x,y),其中 x 和 y 由公式
x = 半径 * sin(以弧度为单位的角度)
y = 半径 * cos(以弧度为单位的角度)
@Composable
fun ComposeCircularProgressBar(
modifier: Modifier = Modifier,
percentage: Float,
fillColor: Color,
backgroundColor: Color,
strokeWidth: Dp
) {
Canvas(
modifier = modifier
.size(150.dp)
.padding(10.dp)
) {
// Background Line
drawArc(
color = backgroundColor,
140f,
260f,
false,
style = Stroke(strokeWidth.toPx(), cap = StrokeCap.Round),
size = Size(size.width, size.height)
)
drawArc(
color = fillColor,
140f,
percentage * 260f,
false,
style = Stroke(strokeWidth.toPx(), cap = StrokeCap.Round),
size = Size(size.width, size.height)
)
var angleInDegrees = (percentage * 260.0) + 50.0
var radius = (size.height / 2)
var x = -(radius * sin(Math.toRadians(angleInDegrees))).toFloat() + (size.width / 2)
var y = (radius * cos(Math.toRadians(angleInDegrees))).toFloat() + (size.height / 2)
drawCircle(
color = Color.White,
radius = 5f,
center = Offset(x, y)
)
}
}
以下是我尝试使用的一些示例
@Preview
@Composable
fun PreviewPorgressBar() {
ComposeCircularProgressBar(
percentage = 0.80f,
fillColor = Color(android.graphics.Color.parseColor("#4DB6AC")),
backgroundColor = Color(android.graphics.Color.parseColor("#90A4AE")),
strokeWidth = 10.dp
)
}
@Preview
@Composable
fun PreviewPorgressBar() {
ComposeCircularProgressBar(
percentage = 0.45f,
fillColor = Color(android.graphics.Color.parseColor("#4DB6AC")),
backgroundColor = Color(android.graphics.Color.parseColor("#90A4AE")),
strokeWidth = 10.dp
)
}
@Preview
@Composable
fun PreviewPorgressBar() {
ComposeCircularProgressBar(
percentage = 1f,
fillColor = Color(android.graphics.Color.parseColor("#4DB6AC")),
backgroundColor = Color(android.graphics.Color.parseColor("#90A4AE")),
strokeWidth = 10.dp
)
}
我想在 Jetpack Compose 中的 canvas 上画一个圆弧,在进度的边缘画一个小圆圈,如下图所示:
我找到了如何用圆弧绘制进度条canvas,但还不知道如何绘制圆来匹配圆弧线的边缘。这是我的进度代码:
@Composable
fun ComposeCircularProgressBar(
modifier: Modifier = Modifier,
percentage: Float,
fillColor: Color,
backgroundColor: Color,
strokeWidth: Dp
) {
Canvas(
modifier = modifier
.padding(strokeWidth / 2)
) {
// Background Line
drawArc(
color = backgroundColor,
135f,
270f,
false,
style = Stroke(strokeWidth.toPx(), cap = StrokeCap.Butt)
)
// Fill Line
drawArc(
color = fillColor,
135f,
270f * percentage,
false,
style = Stroke(strokeWidth.toPx(), cap = StrokeCap.Round)
)
}
}
注意:目前我知道用 Canvas.drawCircle(offset = Offset)
绘制圆圈,但我还不知道如何计算 Offset(x,y)
以匹配进度的边缘。
下面的这段代码将根据您提供的百分比生成带有圆点的圆弧。您确实答对了大部分内容,只是求解数学方程式以找到圆上的点。
我假设圆的半径为小部件的高度/2。
由于我们没有绘制完整的圆,因此起始角为 140 度,最大扫描角为 260 度。 (我通过点击和试用找到了这个,所以它看起来和你的图片很接近)
现在要绘制白色小圆圈,中心 a.k.a offset 必须位于 (x,y),其中 x 和 y 由公式
x = 半径 * sin(以弧度为单位的角度) y = 半径 * cos(以弧度为单位的角度)
@Composable
fun ComposeCircularProgressBar(
modifier: Modifier = Modifier,
percentage: Float,
fillColor: Color,
backgroundColor: Color,
strokeWidth: Dp
) {
Canvas(
modifier = modifier
.size(150.dp)
.padding(10.dp)
) {
// Background Line
drawArc(
color = backgroundColor,
140f,
260f,
false,
style = Stroke(strokeWidth.toPx(), cap = StrokeCap.Round),
size = Size(size.width, size.height)
)
drawArc(
color = fillColor,
140f,
percentage * 260f,
false,
style = Stroke(strokeWidth.toPx(), cap = StrokeCap.Round),
size = Size(size.width, size.height)
)
var angleInDegrees = (percentage * 260.0) + 50.0
var radius = (size.height / 2)
var x = -(radius * sin(Math.toRadians(angleInDegrees))).toFloat() + (size.width / 2)
var y = (radius * cos(Math.toRadians(angleInDegrees))).toFloat() + (size.height / 2)
drawCircle(
color = Color.White,
radius = 5f,
center = Offset(x, y)
)
}
}
以下是我尝试使用的一些示例
@Preview
@Composable
fun PreviewPorgressBar() {
ComposeCircularProgressBar(
percentage = 0.80f,
fillColor = Color(android.graphics.Color.parseColor("#4DB6AC")),
backgroundColor = Color(android.graphics.Color.parseColor("#90A4AE")),
strokeWidth = 10.dp
)
}
@Preview
@Composable
fun PreviewPorgressBar() {
ComposeCircularProgressBar(
percentage = 0.45f,
fillColor = Color(android.graphics.Color.parseColor("#4DB6AC")),
backgroundColor = Color(android.graphics.Color.parseColor("#90A4AE")),
strokeWidth = 10.dp
)
}
@Preview
@Composable
fun PreviewPorgressBar() {
ComposeCircularProgressBar(
percentage = 1f,
fillColor = Color(android.graphics.Color.parseColor("#4DB6AC")),
backgroundColor = Color(android.graphics.Color.parseColor("#90A4AE")),
strokeWidth = 10.dp
)
}