Administrator
Administrator
Published on 2024-12-22 / 18 Visits
0
0

androidx.compose.animation.animation

Group ID

androidx.compose.animation

Artifact ID

animation

Version

1.7.5

Gradle Kotlin DSL

implementation(“androidx.compose.animation:animation:1.7.5”)

文档链接

maven链接

Animatable

animation-core-android中有相同名字的API,此处是单纯的Color类型的动画

    val a = remember { Animatable(Color.Red) }
    val scope = rememberCoroutineScope()

    Box(modifier = Modifier.background(a.value).size(100.dp)) {
        Text("Hello")
    }
    Button(onClick = {
        scope.launch {
            a.animateTo(if(a.value == Color.Red) Color.Blue else Color.Red, tween(1000))
            a.snapTo(if(a.value == Color.Red) Color.Blue else Color.Red) // 瞬间切换, 无动画
        }
    }) {
        Text("Change Color")
    }

EnterTransition、ExitTransition

入场动画和出场动画。以下都是成对的,EnterTransition对应ExitTransition(只有expand例外,没有提供expandOut,expand对应的是shrink)

    //渐显渐隐
    fadeIn(animationSpec = tween(5000), initialAlpha = 0f)
    fadeOut(animationSpec = tween(5000), targetAlpha = 0f)

    //缩放进入和缩放退出
    scaleIn(animationSpec = tween(5000), initialScale = 0.5f, transformOrigin = TransformOrigin.Center)
    scaleOut(animationSpec = tween(5000), targetScale = 0.5f, transformOrigin = TransformOrigin.Center)

    //水平和垂直同时增长
    expandIn { size ->
        //size是最终的尺寸,也就是当前元素会扩展到的尺寸
        IntSize(size.width/2,size.height/2) //初始为一半大小
    }
    expandHorizontally { finalWidth ->
        //横向向右展开
        finalWidth/2 //初始宽度为一半
    }
    expandVertically { finalHeight ->
        //卷帘门效果,纵向向下展开
        finalHeight/2 //初始高度为一半
    }

    shrinkOut(animationSpec = tween(2000)) {
        // it: IntSize,为当前元素的尺寸
        IntSize(20,20) //缩小到20x20时消失,完成退出动画
    }
    shrinkHorizontally (animationSpec = tween(2000)) {
        // it: Int,为当前元素的宽度
        20 //缩小到20时消失,完成退出动画
    }
    shrinkVertically (animationSpec = tween(2000)) {
        // it: Int,为当前元素的高度
        20 //缩小到20时消失,完成退出动画
    }
    

    //平移进入和平移退出
    slideIn { size ->
        //size是容器的尺寸
        IntOffset(size.width,size.height) //从右下角向左上角滑入
    }
    slideOut { size ->
        //size是容器的尺寸
        IntOffset(size.width,size.height) //从当前位置向右下角滑出
    }

    //水平平移进入和水平平移退出
    slideInHorizontally(animationSpec = tween(2000)) {
        it //it是容器的宽度,直接返回也就是从右边向左滑入
    }
    slideOutHorizontally(animationSpec = tween(2000)) {
        it //it是容器的宽度,直接返回也就是从当前位置向右滑出边界
    }

    //垂直平移进入和垂直平移退出
    slideInVertically {
        it //it是容器的高度,直接返回也就是从下边向上滑入
    }
    slideOutVertically {
        it //it是容器的高度,直接返回也就是从当前位置向下滑出边界
    }



//不使用动画
EnterTransition.None
ExitTransition.None



//动画相加
slideInHorizontally(animationSpec = tween(2000)) {
    it
} + fadeIn(tween(5000))

元素:Crossfade

一个带交叉切换效果的元素

//元素函数签名
fun <T> Crossfade(
    targetState: T,
    modifier: Modifier = Modifier,
    animationSpec: FiniteAnimationSpec<Float> = tween(),
    label: String = "Crossfade",
    content: @Composable (T) -> Unit
)
    var currentPage by remember { mutableStateOf("Page1") }

    Column {
        Button(onClick = { currentPage = if (currentPage == "Page1") "Page2" else "Page1" }) {
            Text("Toggle Page")
        }
        Crossfade (targetState = currentPage, label = "") { page:String ->
            when (page) {
                "Page1" -> Box(modifier = Modifier.fillMaxSize().background(Color.Red)) {
                    Text("哈哈")
                }
                "Page2" -> Box(modifier = Modifier.fillMaxSize().background(Color.Blue)) {
                    Text("我是第二个page2")

                }
            }
        }
    }

元素:AnimatedVisibility

一个用State控制显示的元素,可在参数中传递退出和进入的动画。

动画函数的lamda内的参数获取到的大小或宽高都是内容区域的宽高

下面的shrinkOut函数中的it是IntSize类型,值为700*1400(px),就是200*400dp

//签名1:
fun AnimatedVisibility(
    visibleState: MutableTransitionState<Boolean>,
    modifier: Modifier = Modifier,
    enter: EnterTransition = fadeIn() + expandIn(),
    exit: ExitTransition = fadeOut() + shrinkOut(),
    label: String = "AnimatedVisibility",
    content: @Composable() AnimatedVisibilityScope.() -> Unit
)

签名2:
fun AnimatedVisibility(
    visible: Boolean,
    modifier: Modifier = Modifier,
    enter: EnterTransition = fadeIn() + expandIn(),
    exit: ExitTransition = shrinkOut() + fadeOut(),
    label: String = "AnimatedVisibility",
    content: @Composable() AnimatedVisibilityScope.() -> Unit
)

    var visible by remember { mutableStateOf(false) }

    Column {
        Button(onClick = { visible = !visible }) {
            Text("Toggle Visibility")
        }

        AnimatedVisibility(
            visible = visible,
            enter = fadeIn(animationSpec = tween(2000)),
            exit =  shrinkOut (animationSpec = tween(2000)) {
                it/ 2
            }
        ) {
            Column {
                Box(modifier = Modifier.size(200.dp).background(Color.Red))
                Box(modifier = Modifier.size(200.dp).background(Color.Blue))
            }
        }
    }


Comment