其中一种方法是使用可相互设置比例和Alpha动画的动画对象.
创建包含2个动画对象的类
class AnimatedCountdownTimer(
private val coroutineScope: CoroutineScope
) {
private val animatableScale = Animatable(1f)
private val animatableAlpha = Animatable(1f)
val scale: Float
get() = animatableScale.value
val alpha: Float
get() = animatableAlpha.value
fun start(initialValue: Int, endValue: Int, onChange: (Int) -> Unit) {
var value = initialValue
coroutineScope.launch {
while (value > endValue - 1) {
onChange(value)
animatableScale.snapTo(1f)
animatableAlpha.snapTo(1f)
animatableScale.animateTo(2f, animationSpec = tween(750))
animatableAlpha.animateTo(0f, animationSpec = tween(250))
value--
}
}
}
}
并将其用作
@Preview
@Composable
fun TimerTest() {
var timer by remember {
mutableStateOf(5)
}
val coroutineScope = rememberCoroutineScope()
val animatedCountdownTimer = remember {
AnimatedCountdownTimer(coroutineScope)
}
Column(
modifier = Modifier.fillMaxSize().padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
modifier = Modifier.graphicsLayer {
scaleX = animatedCountdownTimer.scale
scaleY = animatedCountdownTimer.scale
alpha = animatedCountdownTimer.alpha
},
text = "$timer",
fontSize = 120.sp,
fontWeight = FontWeight.Bold,
color = Color.Gray
)
Spacer(Modifier.height(20.dp))
Button(
modifier = Modifier.fillMaxWidth(),
onClick = {
animatedCountdownTimer.start(5, 0) {
timer = it
}
}
) {
Text("Start")
}
}
}
如果你不想在动画结束后zoom 到1f,那么只需要添加if块,这样它就可以保持在比例上.任何参数都可以很容易地自定义持续时间或最大规模.
如果你想保持最后一个数字的比例,你可以这样使用它
coroutineScope.launch {
while (value > endValue - 1) {
onChange(value)
animatableScale.snapTo(1f)
animatableAlpha.snapTo(1f)
animatableScale.animateTo(2f, animationSpec = tween(750))
if (value > endValue) {
animatableAlpha.animateTo(0f, animationSpec = tween(250))
}
value--
}
}