如何使用Compose渲染普通的Android ProgressBar?

38

我的应用程序需要一个进度条,在尝试使用Jetpack Compose实现它,因此要么我需要内置的ProgressBar支持(我没有找到它),要么就应该有一种机制可以在Compose中显示普通的Android小部件。这些是否有可能呢?

6个回答

55

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

CircularProgressIndicator: 显示为圆形的进度条。它是不确定的。主题设置为样式中的主要颜色。另一个变体是确定的,它将进度作为浮点数参数 (0.0f - 1.0f)。

示例:

// Indeterminate
CircularProgressIndicator()

// Determinate
CircularProgressIndicator(progress = 0.5f)

LinearProgressIndicator:将进度条显示为线条。它是不确定的。主题设置为样式中设置的主要颜色集。另一种变体是确定性的,将进度作为浮点数参数(0.0f-1.0f)。

示例:

// Indeterminate
LinearProgressIndicator()

// Determinate
LinearProgressIndicator(progress = 0.5f)

什么是修改指示器进度的有效方法?Effect<State<Float>>? - Commander Tvis
如何使角落变圆? - Mirza Ahmed Baig
调整此内容的圆角半径应该更容易。 - Kyle
1
@MirzaAhmedBaig 看起来不可能,除非你想对形状进行大量操作。 - Kyle
1
小注释 - 第一个例子有一个错别字:它缺少一个s :D 感谢您的答案。 - Yoel Gluschnaider
你能提供一个示例,展示我们如何从简单的按钮 onClick 监听器中调用这些可组合方法吗?因为我得到的只是一个错误信息:“@Composable invocations can only happen from the context of a @Composable function”。谢谢! - Pavlos Mavris

22

使用 1.0.x 版本,您可以使用LinearProgressIndicatorCircularProgressIndicator

// 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 }

输入图片描述


2
如何使角落圆滑? - Mirza Ahmed Baig
@Mirza Ahmed Baig 使用 app:trackCornerRadius 来实现圆角。 - Avital
如何隐藏 ProgressIndicator? - Tanjim ahmed
@Tanjimahmed 只需使用布尔值:if (isVisible) { LinearProgressIndicator()} - Gabriele Mariotti

5

要实现圆角,我们可以使用以下代码(与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)
}

1
确保在遇到问题时使用import androidx.compose.foundation.Canvas导入。 - Bharadwaj Giridhar

2

如果你正在寻找一个圆角线性进度条,可以使用Modifier的clip函数。

    LinearProgressIndicator(
      progress = 0.5f,
      modifier = Modifier.height(10.dp).clip(RoundedCornerShape(10.dp))
    )

2

自定义线性进度指示器

@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)
        )
    }
}

1

目前你的回答不够清晰,请编辑并添加更多细节,以帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何撰写好答案的更多信息。 - Community
虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。如果链接页面更改,仅有链接的答案可能会失效。-【来自审查】 - Vojin Purić

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接