【问题标题】:How to animate a rectangle like a Progress Bar in Jetpack Compose如何在 Jetpack Compose 中像进度条一样为矩形设置动画
【发布时间】:2021-12-03 06:13:44
【问题描述】:

如何对第二个矩形实现类似动画的进度条,以及控制开始 & 暂停

等动画
@Composable
fun ProgressBar(modifier: Modifier = Modifier.size(300.dp, 180.dp)) {
    Canvas(modifier = modifier.fillMaxSize().padding(16.dp)) {
        val canvasWidth = size.width
        val canvasHeight = size.height
        val canvasSize = size

        val percentage = 0.2F

        drawRoundRect(
            color = Pink80,
            topLeft = Offset(x = 0F, y = 0F),
            size = Size(canvasSize.width, 55F),
            cornerRadius = CornerRadius(60F, 60F),
        )

        drawRoundRect(
            color = Purple40,
            topLeft = Offset(x = 0F, y = 0F),
            size = Size(canvasWidth * 0.2F , 55F),
            cornerRadius = CornerRadius(60F, 60F),
        )
    }
}

【问题讨论】:

标签: android kotlin android-animation android-jetpack-compose


【解决方案1】:

这里有两个解决方案。第一个使用 Compose 自己的LinearProgressIndicator。第二个是定制的。它非常简单,优点是您可以轻松自定义它。

无需使用画布。当进度条达到最大值时,代码会将其值重置为零,但您可以通过不重置值将其设置为 100%。 LaunchedEffect 仅用于模拟更新值。在生产应用程序中,您不会使用它,而是使用与您的代码业务逻辑一致的其他方式更新值...

LinearProgressIndicator:

见:LinearProgressIndicator

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        startActivity(intent)

        setContent {
            var enabled by remember { mutableStateOf(false) }
            var progress by remember { mutableStateOf(0.1f) }
            val animatedProgress by animateFloatAsState(
                targetValue = progress,
            )

            LaunchedEffect(enabled) {
                while ((progress < 1) && enabled) {
                    progress += 0.005f
                    delay(10)
                }
            }

            if (progress >= 1f) {
                enabled = false
            }

            Column(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(20.dp), horizontalAlignment = Alignment.CenterHorizontally
            ) {
                LinearProgressIndicator(progress = animatedProgress, modifier = Modifier.requiredHeight(20.dp))
                Spacer(Modifier.requiredHeight(30.dp))

                Button(
                    onClick = {
                        enabled = !enabled
                    }
                ) {
                    if (enabled) {
                        Text("Pause")
                    } else {
                        Text("Start")
                    }
                }
            }
        }
    }
}

自定义进度指示器:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        startActivity(intent)

        setContent {
            var enabled by remember { mutableStateOf(false) }.apply { this.value }
            var progressValue by remember { mutableStateOf(0) }

            LaunchedEffect(enabled) {
                while ((progressValue < 100) && enabled) {
                    progressValue++
                    delay(10)
                }

                if (progressValue == 100) {
                    enabled = false
                    progressValue = 0
                }
            }

            Column(modifier = Modifier.fillMaxSize().padding(20.dp)) {
                ProgressBar(value = progressValue)

                Button(
                    onClick = {
                        enabled = !enabled
                    }
                ) {
                    if (enabled) {
                        Text("Pause")
                    } else {
                        Text("Start")
                    }
                }
            }
        }
    }
}

@Composable
fun ProgressBar(
    value: Int
) {
    Box(
        modifier = Modifier
            .fillMaxWidth()
            .requiredHeight(20.dp)
            .border(width = 1.dp, color = Color.Black)
    ) {

        Box(
            modifier = Modifier
                .fillMaxWidth(value.toFloat() / 100f)
                .fillMaxHeight()
                .background(color = Color.Red)
        ) {
        }
    }
}

【讨论】:

    猜你喜欢
    • 2021-11-12
    • 2022-11-22
    • 2023-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-10
    相关资源
    最近更新 更多