<
Compose学习笔记 动画
>
上一篇

Litepal
下一篇

Compose paging Compose 列表分页

Compose 动画

分类

1. 状态驱动动画

2. 其他类型的动画

常用动画及示例

官方文档 https://developer.android.com/jetpack/compose/animation/choose-api

@Composable
fun AnimatedVisibilityExample() {
    var visible by remember { mutableStateOf(true) }

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

        AnimatedVisibility(visible = visible) {
            Text(
                text = "Hello, I'm visible!",
                modifier = Modifier.padding(16.dp)
            )
        }
    }
}
@Composable
fun AnimateFloatAsStateExample() {
    var expanded by remember { mutableStateOf(false) }
    val size by animateDpAsState(if (expanded) 200.dp else 100.dp)

    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center,
        modifier = Modifier.fillMaxSize()
    ) {
        Box(
            modifier = Modifier
                .size(size)
                .background(Color.Blue)
        )
        Button(onClick = { expanded = !expanded }) {
            Text("Toggle Size")
        }
    }
}
@Composable
fun AnimatedTextExample() {
    var text by remember { mutableStateOf("Hello") }

    Column {
        TextMotion.Animated(text = text)
        Button(onClick = { text = if (text == "Hello") "World" else "Hello" }) {
            Text("Change Text")
        }
    }
}
@Composable
fun InfiniteAnimationExample() {
    val infiniteTransition = rememberInfiniteTransition()

    // 创建一个持续变化的属性,例如颜色或位移
    val color by infiniteTransition.animateColor(
        initialValue = Color.Red,
        targetValue = Color.Blue,
        animationSpec = infiniteRepeatable(
            animation = tween(durationMillis = 1000),
            repeatMode = RepeatMode.Reverse
        )
    )

    Box(
        modifier = Modifier
            .size(200.dp)
            .background(color)
    )
}
@Composable
fun AnimatedContentExample() {
    var selectedOption by remember { mutableStateOf("Option 1") }

    Column {
        Button(onClick = { selectedOption = "Option 1" }) {
            Text("Option 1")
        }
        Button(onClick = { selectedOption = "Option 2" }) {
            Text("Option 2")
        }

        AnimatedContent(targetState = selectedOption) { targetState ->
            Text(
                text = targetState,
                modifier = Modifier.padding(16.dp),
                style = MaterialTheme.typography.h4
            )
        }
    }
}

使用 transitionSpec 参数可指定动画类型

AnimatedContent(
        targetState = selectedOption,
        transitionSpec = {
            // 自定义动画类型
            if (targetState == "Option 1" && initialState == "Option 2") {
                // 从 Option 2 到 Option 1
                fadeIn(animationSpec = tween(durationMillis = 300)) togetherWith fadeOut(animationSpec = tween(durationMillis = 300))
            } else {
                // 从 Option 1 到 Option 2
                fadeIn(animationSpec = tween(durationMillis = 300)) togetherWith fadeOut(animationSpec = tween(durationMillis = 300))
            }
        }
    )
@Composable
fun AnimatedTransitionExample() {
    var isExpanded by remember { mutableStateOf(false) }

    // 使用 updateTransition 来创建一个过渡动画
    val transition = updateTransition(targetState = isExpanded, label = "ExpandTransition")

    // 在过渡中定义多个属性的动画
    val height by transition.animateDp(label = "Height") { state ->
        if (state) 200.dp else 100.dp
    }

    val color by transition.animateColor(label = "Color") { state ->
        if (state) Color.Blue else Color.Red
    }

    Column(
        modifier = Modifier
            .fillMaxWidth()
            .height(height)
            .background(color)
            .clickable {
                isExpanded = !isExpanded
            },
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text("Click to ${if (isExpanded) "Collapse" else "Expand"}")
    }
}
@Composable
fun AnimatableExample() {
    var isExpanded by remember { mutableStateOf(false) }
    val size = remember { Animatable(100f) }

    LaunchedEffect(isExpanded) {
        size.animateTo(
            targetValue = if (isExpanded) 200f else 100f,
            animationSpec = tween(durationMillis = 300)
        )
    }

    Box(
        modifier = Modifier
            .size(size.value.dp)
            .background(Color.Blue)
            .clickable { isExpanded = !isExpanded },
        contentAlignment = Alignment.Center
    ) {
        Text("Click Me", color = Color.White)
    }
}

Others

位移,两种方式

Modifier
    .layout { measurable, constraints -> // `Modifier.layout{ }` 位移 影响父和兄布局
        val placeable = measurable.measure(constraints)
        layout(placeable.width + offset2.x, placeable.height + offset2.y) {
            placeable.placeRelative(offset2)
        }
    }
    .offset { // `Modifier.offset{ }` 偏移量 不会影响父布局和兄弟布局 只会影响本身和子布局。否则 如需影响父布局和兄弟布局 请使用 `Modifier.layout{ }`
        offset
    }

位移 缩放 旋转 透明,利用 graphicsLayer 函数

Modifier
    .graphicsLayer { // 图形层 绘制
        // 可以设置 透明 缩放 位移 旋转 阴影高度 阴影颜色 shape clip size 等
        scaleX = scale
        scaleY = scale
        alpha = scale * 0.1f
        transformOrigin = TransformOrigin.Center
    }

###

Top
Foot