jetpack 中的循环加载 Spinner 组成

Viv*_*odi 7 android kotlin android-jetpack android-jetpack-compose

我想在 jetpack compose 中创建加载微调器。我没有视频,但我有图像。

在此输入图像描述

我只知道CircularProgressIndicator但不知道如何自定义并看起来像上图一样。

    CircularProgressIndicator(
            progress = progress,
            color = progressColor,
            strokeWidth = strokeWidth,
            modifier = Modifier.fillMaxSize()
    )
Run Code Online (Sandbox Code Playgroud)

提前致谢。

更新

我发现该视频看起来像 Twitter 在网络中加载旋转器。我做了小视频截图。请在YouTube上观看

vit*_*dev 12

你好,兄弟试试这个,然后回答我。

@Composable
fun Indicator(
    size: Dp = 32.dp, // indicator size
    sweepAngle: Float = 90f, // angle (lenght) of indicator arc
    color: Color = MaterialTheme.colors.primary, // color of indicator arc line
    strokeWidth: Dp = ProgressIndicatorDefaults.StrokeWidth //width of cicle and ar lines
) {
    ////// animation //////

    // docs recomend use transition animation for infinite loops
    // https://developer.android.com/jetpack/compose/animation
    val transition = rememberInfiniteTransition()

    // define the changing value from 0 to 360.
    // This is the angle of the beginning of indicator arc
    // this value will change over time from 0 to 360 and repeat indefinitely.
    // it changes starting position of the indicator arc and the animation is obtained
    val currentArcStartAngle by transition.animateValue(
        0,
        360,
        Int.VectorConverter,
        infiniteRepeatable(
            animation = tween(
                durationMillis = 1100,
                easing = LinearEasing
            )
        )
    )

    ////// draw /////

    // define stroke with given width and arc ends type considering device DPI
    val stroke = with(LocalDensity.current) {
        Stroke(width = strokeWidth.toPx(), cap = StrokeCap.Square)
    }

    // draw on canvas
    Canvas(
        Modifier
            .progressSemantics() // (optional) for Accessibility services
            .size(size) // canvas size
            .padding(strokeWidth / 2) //padding. otherwise, not the whole circle will fit in the canvas
    ) {
        // draw "background" (gray) circle with defined stroke.
        // without explicit center and radius it fit canvas bounds
        drawCircle(Color.LightGray, style = stroke)

        // draw arc with the same stroke
        drawArc(
            color,
            // arc start angle
            // -90 shifts the start position towards the y-axis
            startAngle = currentArcStartAngle.toFloat() - 90,
            sweepAngle = sweepAngle,
            useCenter = false,
            style = stroke
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

简而言之 - 在画布上绘制一个圆圈,并在其顶部绘制一条指示弧。

传递动画将变量的值currentArcStartAngle从 0 到 360(这是圆的角度)循环,该变量用于设置指示弧的起始角度

为了更好地理解起始角度,请执行useCenter = true以下操作drawArc

currentArcStartAngle是状态,因此每次更改都会导致画布以新的起始角度重新组合和重新绘制

结果:

在此输入图像描述


Thr*_*ian 7

您可以使用以下方法在进度后面绘制另一个圆圈Modifier.drawBehind

val strokeWidth = 5.dp

CircularProgressIndicator(
    modifier = Modifier.drawBehind {
        drawCircle(
            Color.Red,
            radius = size.width / 2 - strokeWidth.toPx() / 2,
            style = Stroke(strokeWidth.toPx())
        )
    },
    color = Color.LightGray,
    strokeWidth = strokeWidth
)
Run Code Online (Sandbox Code Playgroud)