英文:
How to make CircularProgressIndicator in jetpack compose smoother
问题
我正在构建一个显示分钟和秒的计时器,周围使用了一个CircularProgressIndicator来进行可视化。但是CircularProgressIndicator在更新时会从一秒钟跳到下一秒钟。有没有办法让它平稳流畅地运行?
我尝试了两个LaunchedEffect,一个用于计时器,一个用于CircularProgressIndicator,并尝试了一些疯狂的公式,但效果不太好。
以下是我目前的代码:
var currentTime by remember { mutableLongStateOf(totalTime) } // 例如,10
var progress by remember { mutableFloatStateOf(1f) }
// 动画
val progressAnimate by animateFloatAsState(
targetValue = progress,
animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec
)
CircularProgressIndicator(
progress = progressAnimate,
modifier = Modifier.size(size = 300.dp),
color = color,
strokeWidth = 10.dp,
strokeCap = StrokeCap.Round,
)
LaunchedEffect(isTimerRunning) {
while (currentTime > 0) {
delay(1000L)
currentTime--
progress = currentTime / totalTime.toFloat()
onTimerChange(currentTime)
}
}
希望这能帮助你解决问题。
英文:
I'm build a timer that shows the minutes and seconds, and around it a used a CircularProgressIndicator for the visuals. But the CircularProgressIndicator updates jumping from second to second. Is there a way to make it run smoothly, flowing?
I tried two LauchedEffect one for the timer and one for the CircularProgressIndicator and came up with some crazy formulas but it didn't sync up very well.
here is my code so far
var currentTime by remember { mutableLongStateOf(totalTime) } // 10 for example
var progress by remember { mutableFloatStateOf(1f) }
// animation
val progressAnimate by animateFloatAsState(
targetValue = progress,
animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec
)
CircularProgressIndicator(
progress = progressAnimate,
modifier = Modifier.size(size = 300.dp),
color = color,
strokeWidth = 10.dp,
strokeCap = StrokeCap.Round,
)
LaunchedEffect(isTimerRunning) {
while (currentTime > 0) {
delay(1000L)
currentTime--
progress = currentTime / totalTime.toFloat()
onTimerChange(currentTime)
}
}
答案1
得分: 0
我认为你正在寻找的是动画规范 tween,它的工作原理如下:
tween 会在指定的 durationMillis 内在起始值和结束值之间进行动画,使用缓动曲线。有关更多信息,请参阅缓动 (Easing)。
你还可以指定 delayMillis 来推迟动画的开始。
因此,你的代码应该是这样的:
var currentTime by remember { mutableLongStateOf(totalTime) } // 例如 10
var progress by remember { mutableFloatStateOf(1f) }
// 动画
val progressAnimate by animateFloatAsState(
targetValue = progress,
animationSpec = tween(
durationMillis = 300, // 动画持续时间
delayMillis = 50, // 动画开始前的延迟
easing = LinearOutSlowInEasing
)
)
CircularProgressIndicator(
progress = progressAnimate,
modifier = Modifier.size(size = 300.dp),
color = color,
strokeWidth = 10.dp,
strokeCap = StrokeCap.Round,
)
LaunchedEffect(isTimerRunning) {
while (currentTime > 0) {
delay(1000L)
currentTime--
progress = currentTime / totalTime.toFloat()
onTimerChange(currentTime)
}
}
英文:
I think what you are looking for is the animation spec tween and it works like this:
> tween animates between start and end values over the specified
> durationMillis using an easing curve. See Easing for more information.
> You can also specify delayMillis to postpone the start of the
> animation.
So your code would be:
var currentTime by remember { mutableLongStateOf(totalTime) } // 10 for example
var progress by remember { mutableFloatStateOf(1f) }
// animation
val progressAnimate by animateFloatAsState(
targetValue = progress,
animationSpec = tween(
durationMillis = 300,//animation duration
delayMillis = 50,//delay before animation start
easing = LinearOutSlowInEasing
)
CircularProgressIndicator(
progress = progressAnimate,
modifier = Modifier.size(size = 300.dp),
color = color,
strokeWidth = 10.dp,
strokeCap = StrokeCap.Round,
)
LaunchedEffect(isTimerRunning) {
while (currentTime > 0) {
delay(1000L)
currentTime--
progress = currentTime / totalTime.toFloat()
onTimerChange(currentTime)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论