一、高级别动画
1.1 简单值动画 animate***AsState
为单个值添加动画。只需要指定目标值,会从当前值向目标值渐变。
animateColorAsState | |
animateDpAsState | |
animateSizeAsState | |
animateOffsetAsState | |
animateRectAsState | |
animateIntAsState animateIntOffsetAsState animateIntSizeAsState | |
animateValueAsState TwoWayConverter | 对其他数据类型支持 |
val value = flow { //透明度逐渐降低
emit(1.0F)
delay(500)
emit(0.8F)
delay(500)
emit(0.6F)
delay(500)
emit(0.4F)
delay(500)
emit(0.2F)
}
@Composable
fun Show() {
val myAlpah: Float by animateFloatAsState(targetValue = value.collectAsState(initial = 1.0F).value)
Box(
modifier = Modifier
.graphicsLayer(alpha = myAlpah)
.background(Color.Red)
) {
Text(text = "你好")
}
}
1.2 可见性动画 AnimatedVisibility
为内容的显示或消失添加动画。默认以“淡入扩大出现,淡出缩小消失”,可通过 EnterTransition 和 ExitTransition 设置,不同的动画可以用“+”自由组合。
EnterTransition | ExitTransition | ||||
fadeIn | fadeOut | ||||
slideIn | slideOut | ||||
slideInHorizontally | slideOutHorizontally | ||||
slideInVertically | slideOutVertically | ||||
scaleIn | scaleOut | ||||
expendIn | shrinkOut | ||||
expendHorizontally | shrinkHorizontally | ||||
expendVertically | shrinkVertically |
@Composable fun AnimatedVisibility( visible: Boolean, //控制内容是否可见 modifier: Modifier = Modifier, enter: EnterTransition = fadeIn() + expandIn(), //进入动画(默认淡入扩大) exit: ExitTransition = shrinkOut() + fadeOut(), //退出动画(默认淡出缩小) label: String = "AnimatedVisibility", content: @Composable() AnimatedVisibilityScope.() -> Unit //显示或消失的内容 ) |
val value = flow { //可见不可见切换
emit(true)
delay(500)
emit(false)
delay(500)
emit(true)
delay(500)
emit(false)
}
@Composable
fun Show() {
val enable: Boolean by value.collectAsState(initial = true)
//包裹住需要控制的内容(这里是Text)
AnimatedVisibility(
visible = enable,
){
Text(text = "你好")
}
}
1.3 内容改变动画 AnimatedContent
为内容改变添加动画。默认淡出后淡入。
fun <S> AnimatedContent( 使用 transitionSpec 指定 ContentTransform 对象来配置进入动画和退出动画(with中缀表达式能组合进入动画和退出动画并返回ContentTransform对象)。 |
Column {
var count by remember { mutableStateOf(0) }
Button(onClick = { count++ }) {
Text("添加数据")
}
AnimatedContent(
targetState = count,
transitionSpec = {
//with是进入动画的扩展函数,传入退出动画,返回的是ContentTransform
scaleIn() with scaleOut()
}
) {
Text(text = "数值:${count}")
}
}
1.4 内容大小动画 Modifier.animateContentSize( )
为可大小变化的控件添加动画。注意:在修饰符链中的顺序很重要,为了确保动画流畅,务必放置在任何大小修饰符(如size或defaultMinSize)前面,以确保会将带动画效果的值的变化报告给布局。
1.5 淡入淡出动画 Crossfade
为两个内容的切换添加淡入淡出动画。
fun <T> Crossfade( targetState: T, modifier: Modifier = Modifier, animationSpec: FiniteAnimationSpec<Float> = tween(), label: String = "Crossfade", content: @Composable (T) -> Unit ) |
@Composable
fun Sample() {
var currentPage by remember { mutableStateOf(false) }
Column {
Crossfade(targetState = currentPage, animationSpec = tween(3000)) { screen ->
when (screen) {
false -> Box(modifier = Modifier.background(Color.Blue).size(100.dp))
true -> Box(modifier = Modifier.background(Color.Red).size(100.dp))
}
}
Button(onClick = { currentPage = !currentPage }, modifier = Modifier.width(100.dp)) {
Text(text = "点击切换")
}
}
}
1.6 多值动画 updateTransiton
同时运行多个动画。
1.7 重复动画 rememberInfiniteTransition
动画一进入组合阶段就开始运行,除非被移除,否则不会停止。使用 rememberInfiniteTransition 创建 InfiniteTransition 实例,使用 animateColor、animatedFloat 或 animatedValue 添加子动画,还需要指定 infiniteRepeatable 以指定动画规范。
@Composable
fun Show() {
val infiniteTransition = rememberInfiniteTransition()
val alpha = infiniteTransition.animateFloat(
initialValue = 0F, //初始值
targetValue = 1F, //目标值
animationSpec = InfiniteRepeatableSpec(
animation = keyframes {
durationMillis = 1000
1F at 500 //指定关键帧
},
repeatMode = RepeatMode.Restart //重复模式,还有一个Reverse
)
)
val color by infiniteTransition.animateColor(
initialValue = Color.Red,
targetValue = Color.Green,
animationSpec = infiniteRepeatable(
animation = tween(1000, easing = LinearEasing),
repeatMode = RepeatMode.Reverse
)
)
}