AnimatedVisibility:根据条件显示或隐藏内容,具有淡入淡出等动画效果。
animateXXXAsState:用于在状态变化时平滑地动画化属性(如 animateDpAsState
、animateColorAsState
等)。
TextMotion.Animated:用于文本的动态效果,通常与文本变化相关。
AnimatedContent:根据内容的变化执行动画,通常用于在不同内容之间平滑过渡。
Tween Animation:使用 animate*AsState
方法,允许你定义动画的持续时间和缓动效果。
Keyframe Animation:通过 animateValue
和 keyframes
可以创建关键帧动画,指定特定时间点的动画状态。
Physics Animation:使用 spring
和 fling
动画,这些动画模拟真实世界的物理效果,例如弹性或摩擦。
Transition Animation:使用 updateTransition
来创建复杂的状态转换动画,可以在多个状态之间平滑过渡。
Draw Animation:通过 Modifier.graphicsLayer
和 drawWithContent
可以实现更复杂的绘制和动画效果。
官方文档 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)
}
}
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
}
Modifier
.graphicsLayer { // 图形层 绘制
// 可以设置 透明 缩放 位移 旋转 阴影高度 阴影颜色 shape clip size 等
scaleX = scale
scaleY = scale
alpha = scale * 0.1f
transformOrigin = TransformOrigin.Center
}
###