gpt4 book ai didi

android - Compose 中带圆角的 CircularProgressIndicator

转载 作者:行者123 更新时间:2023-12-04 23:55:59 40 4
gpt4 key购买 nike

我正在尝试使用 jetpack compose 绕过 CircularProgressIndicator 的角落。但我没有看到任何成员变量这样做。以下是源代码,但它没有以 Stroke 作为参数。如果可以,那么我们将能够创建带有圆帽的自定义 Stroke。

@Composable
fun CircularProgressIndicator(
/*@FloatRange(from = 0.0, to = 1.0)*/
progress: Float,
modifier: Modifier = Modifier,
color: Color = MaterialTheme.colors.primary,
strokeWidth: Dp = ProgressIndicatorDefaults.StrokeWidth
) {
val stroke = with(LocalDensity.current) {
Stroke(width = strokeWidth.toPx(), cap = StrokeCap.Butt)
}
Canvas(
modifier
.progressSemantics(progress)
.size(CircularIndicatorDiameter)
.focusable()
) {
// Start at 12 O'clock
val startAngle = 270f
val sweep = progress * 360f
drawDeterminateCircularIndicator(startAngle, sweep, color, stroke)
}
}

最佳答案

cap 在源函数中是硬编码的。我使用的解决方案基本上是复制粘贴源函数和更改笔画上限。此外,对于线性指示器,您需要做一些额外的数学运算,以使圆形大写不会超过指定的宽度。

import androidx.compose.foundation.Canvas
import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.progressSemantics
import androidx.compose.material.MaterialTheme
import androidx.compose.material.ProgressIndicatorDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp

private val LinearIndicatorWidth = 240.dp
private val LinearIndicatorHeight = ProgressIndicatorDefaults.StrokeWidth

private val CircularIndicatorDiameter = 40.dp

@Composable
internal fun RoundedLinearProgressIndicator(
/*@FloatRange(from = 0.0, to = 1.0)*/
progress: Float,
modifier: Modifier = Modifier,
color: Color = MaterialTheme.colors.primary,
backgroundColor: Color = color.copy(alpha = ProgressIndicatorDefaults.IndicatorBackgroundOpacity)
) {
Canvas(
modifier
.progressSemantics(progress)
.size(LinearIndicatorWidth, LinearIndicatorHeight)
.focusable()
) {
val strokeWidth = size.height
drawRoundedLinearProgressIndicator(
startFraction = 0f,
endFraction = 1f,
color = backgroundColor,
strokeWidth = strokeWidth
)
drawRoundedLinearProgressIndicator(
startFraction = 0f,
endFraction = progress,
color = color,
strokeWidth = strokeWidth
)
}
}

@Composable
internal fun RoundedCircularProgressIndicator(
/*@FloatRange(from = 0.0, to = 1.0)*/
progress: Float,
modifier: Modifier = Modifier,
color: Color = MaterialTheme.colors.primary,
strokeWidth: Dp = ProgressIndicatorDefaults.StrokeWidth
) {
val stroke = with(LocalDensity.current) {
Stroke(width = strokeWidth.toPx(), cap = StrokeCap.Round)
}
Canvas(
modifier
.progressSemantics(progress)
.size(CircularIndicatorDiameter)
.focusable()
) {
// Start at 12 O'clock
val startAngle = 270f
val sweep = progress * 360f
drawRoundedCircularIndicator(startAngle, sweep, color, stroke)
}
}

private fun DrawScope.drawRoundedCircularIndicator(
startAngle: Float,
sweep: Float,
color: Color,
stroke: Stroke
) {
// To draw this circle we need a rect with edges that line up with the midpoint of the stroke.
// To do this we need to remove half the stroke width from the total diameter for both sides.
val diameterOffset = stroke.width / 2
val arcDimen = size.width - 2 * diameterOffset
drawArc(
color = color,
startAngle = startAngle,
sweepAngle = sweep,
useCenter = false,
topLeft = Offset(diameterOffset, diameterOffset),
size = Size(arcDimen, arcDimen),
style = stroke
)
}

private fun DrawScope.drawRoundedLinearProgressIndicator(
startFraction: Float,
endFraction: Float,
color: Color,
strokeWidth: Float,
) {
val cap = StrokeCap.Round
val width = size.width
val height = size.height
// Start drawing from the vertical center of the stroke
val yOffset = height / 2

val roundedCapOffset = size.height / 2

val isLtr = layoutDirection == LayoutDirection.Ltr
val barStart = (if (isLtr) startFraction else 1f - endFraction) * width + if (isLtr) roundedCapOffset else -roundedCapOffset
val barEnd = (if (isLtr) endFraction else 1f - startFraction) * width - if (isLtr) roundedCapOffset else -roundedCapOffset

// Progress line
drawLine(
color = color,
start = Offset(barStart, yOffset),
end = Offset(barEnd, yOffset),
strokeWidth = strokeWidth,
cap = cap,
)
}

关于android - Compose 中带圆角的 CircularProgressIndicator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68299964/

40 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com