Compose (10/N) - 动画

一、高级别动画

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(
    targetState: S,
    modifier: Modifier = Modifier,
    transitionSpec: AnimatedContentScope<S>.() -> ContentTransform = {
        fadeIn(animationSpec = tween(220, delayMillis = 90)) +
            scaleIn(initialScale = 0.92f, animationSpec = tween(220, delayMillis = 90)) with
            fadeOut(animationSpec = tween(90))
    },
    contentAlignment: Alignment = Alignment.TopStart,
    label: String = "AnimatedContent",
    content: @Composable() AnimatedVisibilityScope.(targetState: S) -> Unit
)

使用 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
        )
    )
}

二、低级别动画

2.1 Animatable

2.2 Animation

三、自定义动画

3.1 AnimationSpec

3.2 Easing

3.3 AnimationVector

猜你喜欢

转载自blog.csdn.net/HugMua/article/details/130070605