背景
在网上看到一个有意思的动画效果,不过使用css实现的,我现在用compose复刻一下。 网址:uiverse.io/vinodjangid…
1.拆解动画
学习和使用动画最重要的就是拆解,因为动画本身就是物体状态的变化,即从一个状态变成另一个状态, 这个动画首先就是一个图标,然后变成了图标+文字
stateDiagram-v2
Icon --> (Icon+Text)
2.基础组件
compose有一个组件叫 FloatingActionButton,我们就用这个作为基础组件,里面塞上一个Icon和text,不过这个Text默认不显示,代码长这个样:
@Composable
fun Logout() {
val visible by remember { mutableStateOf(false) }
FloatingActionButton(
onClick = {},
backgroundColor = Color(255, 65, 65),
modifier = Modifier
) {
Row(
modifier = Modifier,
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceEvenly
) {
Icon(
Icons.AutoMirrored.Outlined.ExitToApp,
contentDescription = null,
tint = Color.White
)
if(visible){
Text(
text = "Logout",
color = Color.White,
fontSize = 15.sp,
fontWeight = FontWeight.Bold,
fontFamily = FontFamily.Cursive,
modifier = Modifier
.padding(horizontal = 5.dp, vertical = 3.dp)
)
}
}
}
}
3.添加动画
把if替换成 AnimatedVisibility,然后稍微优化一下,给整体的Row设置歌可变的padding,效果其实并不和网站上一样,不过也还可以:
完整代码:
//https://uiverse.io/vinodjangid07/thin-duck-22
@Composable
fun LogoutSample() {
Box(
modifier = Modifier
.fillMaxSize()
.background(Color(232, 232, 232))
.border(1.dp, Color.Green),
contentAlignment = Alignment.Center
) {
Logout()
}
}
@Composable
fun Logout() {
val interactionSource = remember { MutableInteractionSource() }
val hovered by interactionSource.collectIsHoveredAsState()
val horizontalPadding by animateDpAsState(if (hovered) 18.dp else 12.dp)
FloatingActionButton(
onClick = {},
backgroundColor = Color(255, 65, 65),
modifier = Modifier
.hoverable(interactionSource)
) {
Row(
modifier = Modifier
.padding(horizontal = horizontalPadding),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceEvenly
) {
Icon(
Icons.AutoMirrored.Outlined.ExitToApp,
contentDescription = null,
tint = Color.White
)
AnimatedVisibility(hovered) {
Text(
text = "Logout",
color = Color.White,
fontSize = 15.sp,
fontWeight = FontWeight.Bold,
fontFamily = FontFamily.Cursive,
modifier = Modifier
.padding(horizontal = 5.dp, vertical = 3.dp)
)
}
}
}
}