compose > 动画相关

124 阅读2分钟

动画的方法有不少,我们这里记录下几种

1 animateXXX

这个有很多种以animate开头的,看名字就知道区别了,下边举例一种

var start by remember {
    mutableStateOf(false)
}
val angle = animateFloatAsState(targetValue = if (start) 358f else 0f,
    tween(delayMillis = 500, durationMillis = 900, easing = easingCurrent))

上边的start默认是false,那么angle角就是0f,当start为true的时候angle就是358f了, angle会按照动画的设定从0变化到358,用到angle的地方就能看到动画效果了

2 transition

和上边差不多,不过这里动画直接开始了,不用像上边还得手动设置start为true

val state = remember {
    MutableTransitionState(0).apply { targetState = 1 }
}
val transition = updateTransition(transitionState = state)
val angle by transition.animateFloat(transitionSpec = {
    tween(delayMillis = 500, durationMillis = 900, easing = FastOutSlowInEasing)
}, label = "") { c ->
    if (c == 0) {
        0f
    } else {
        355f
    }
}

下边是个完整的例子

@Composable
fun circle2() {

    val state = remember {
        MutableTransitionState(0).apply { targetState = 1 }
    }
    val transition = updateTransition(transitionState = state, label = "")
    val angle by transition.animateFloat(transitionSpec = {
        tween(delayMillis = 500, durationMillis = 900, easing = FastOutSlowInEasing)
    }, label = "") { c ->
        if (c == 0) {
            0f
        } else {
            355f
        }
    }

    val shift by transition.animateFloat({
        tween(delayMillis = 500, durationMillis = 900, easing = FastOutSlowInEasing)
    }, label = "") { c ->
        if (c == 0) {
            -90f
        } else {
            -60f
        }
    }
    Canvas(
        modifier = Modifier
            .padding(10.dp)
            .fillMaxSize(),
    ) {

        val w = this.size.width
        val h = size.height
        val min = w.coerceAtMost(h)
        val max = w.coerceAtLeast(h)
        val cs = Size(min, min)
        val offset = (max - min) / 2
        drawArc(Color.Red, shift, angle, false, Offset(0f, offset), cs, style = Stroke(5f))
    }

}

3 animateContentSize

如下所示,Modifier有个animateContentSize方法,就是字面意思,内容大小发生变化的时候可以有动画效果,比如布局宽度从100dp变化到200dp,可以有个渐变的过程

Modifier.animateContentSize(
    animationSpec: FiniteAnimationSpec<IntSize> = spring(),
    finishedListener: ((initialValue: IntSize, targetValue: IntSize) -> Unit)? = null
)

4 隐藏显示动画

如下,visible发生变化的时候,组件也会有个渐变的过程

AnimatedVisibility(visible = ) {
    
}

方法如下,默认的进出动画都有,可以自定义

fun ColumnScope.AnimatedVisibility(
    visible: Boolean,
    modifier: Modifier = Modifier,
    enter: EnterTransition = fadeIn() + expandVertically(),
    exit: ExitTransition = fadeOut() + shrinkVertically(),
    label: String = "AnimatedVisibility",
    content: @Composable AnimatedVisibilityScope.() -> Unit
)

5

待续。。。