如何使用 Compose 呈现纯 android ProgressBar?

How can I render plain android ProgressBar with Compose?

我的应用程序需要一个 ProgressBar,我正在尝试使用 Jetpack Compose 来实现它,所以我需要一个内置的 ProgressBar 支持(我没有找到它)或者应该有一种机制来显示纯文本 Android 带有 Compose 的小部件。这有什么可能吗?

当然,我们在 Jetpack Compose 中有进度条:

CircularProgressIndicator: 将进度条显示为圆形。它是不确定的。以样式中的原色为主题。另一个变体是 determinate 的,它将参数的进展作为 Float (0.0f - 1.0f)

示例:

// Indeterminate
CircularProgressIndicator()

// Determinate
CircularProgressIndicator(progress = 0.5f)

LinearProgressIndicator:将进度条显示为线条。它是不确定的。以样式中的原色为主题。另一个变体是 determinate 的,它将参数的进展作为 Float (0.0f - 1.0f)

示例:

// Indeterminate
LinearProgressIndicator()

// Determinate
LinearProgressIndicator(progress = 0.5f)

有了 1.0.x 你可以使用 LinearProgressIndicator or CircularProgressIndicator

// Indeterminate
CircularProgressIndicator()
LinearProgressIndicator()
// Determinate
CircularProgressIndicator(progress = ..)
LinearProgressIndicator(progress = ..)

示例:

var progress by remember {  mutableStateOf(0.1f) }

LinearProgressIndicator(
    backgroundColor = Color.White,
    progress = progress,
    color = blue700
)

要更新值,您可以使用类似的东西:

// { if (progress < 1f) progress += 0.1f }

对于圆角,我们可以使用此代码(它与 LinearProgress 相同,但有一个小的修正 - 在 drawLine 中,我们使用参数 StrokeCap.Round 进行舍入)

@Composable
fun LinearRoundedProgressIndicator(
    /*@FloatRange(from = 0.0, to = 1.0)*/
    progress: Float,
    modifier: Modifier = Modifier,
    color: Color = MaterialTheme.colors.primary,
    backgroundColor: Color = color.copy(alpha = ProgressIndicatorDefaults.IndicatorBackgroundOpacity)
) {
    val linearIndicatorHeight = ProgressIndicatorDefaults.StrokeWidth
    val linearIndicatorWidth = 240.dp
    Canvas(
        modifier
            .progressSemantics(progress)
            .size(linearIndicatorWidth, linearIndicatorHeight)
            .focusable()
    ) {
        val strokeWidth = size.height
        drawRoundedLinearIndicatorBackground(backgroundColor, strokeWidth)
        drawRoundedLinearIndicator(0f, progress, color, strokeWidth)
    }
}

private fun DrawScope.drawRoundedLinearIndicatorBackground(
    color: Color,
    strokeWidth: Float
) = drawRoundedLinearIndicator(0f, 1f, color, strokeWidth)

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

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

    // Progress line
    drawLine(color, Offset(barStart, yOffset), Offset(barEnd, yOffset), strokeWidth, StrokeCap.Round)
}

自定义线性进度指示器

@Composable
fun CustomLinearProgressIndicator(
    modifier: Modifier = Modifier,
    progress: Float,
    progressColor: Color = orangeColor,
    backgroundColor: Color = orangeColor.copy(0.24f),
    clipShape: Shape = RoundedCornerShape(16.dp)
) {
    Box(
        modifier = modifier
            .clip(clipShape)
            .background(backgroundColor)
            .height(8.dp)
    ) {
        Box(
            modifier = Modifier
                .background(progressColor)
                .fillMaxHeight()
                .fillMaxWidth(progress)
        )
    }
}