在我的 android 项目中,我正在做一个简单的 float 操作按钮,它可以展开并显示执行不同操作的按钮列表。 为了跟踪 FAB 的当前状态,我有下一个枚举类
enum class FabState {
Expanded,
Collapsed
}
为了显示 float 操作按钮,我有以下可组合函数:
@Composable
fun MultiFloatingActionButton(
icon: ImageVector,
iconTint: Color = Color.White,
miniFabItems: List<MinFabItem>,
fabState: FabState, //The initial state of the FAB
onFabStateChanged: (FabState) -> Unit,
onItemClick: (MinFabItem) -> Unit
) {
val transition = updateTransition(targetState = fabState, label = "transition")
val rotate by transition.animateFloat(label = "rotate") {
when (it) {
FabState.Collapsed -> 0f
FabState.Expanded -> 315f
}
}
val fabScale by transition.animateFloat(label = "fabScale") {
when (it) {
FabState.Collapsed -> 0f
FabState.Expanded -> 1f
}
}
val alpha by transition.animateFloat(label = "alpha") {
when (it) {
FabState.Collapsed -> 0f
FabState.Expanded -> 1f
}
}
val shadow by transition.animateDp(label = "shadow", transitionSpec = { tween(50) }) { state ->
when (state) {
FabState.Expanded -> 2.dp
FabState.Collapsed -> 0.dp
}
}
Column(
horizontalAlignment = Alignment.End
) { // This is where I have my question, in the if condition
if (fabState == FabState.Expanded || transition.currentState == FabState.Expanded) {
miniFabItems.forEach { minFabItem ->
MinFab( //Composable for creating sub action buttons
fabItem = minFabItem,
alpha = alpha,
textShadow = shadow,
fabScale = fabScale,
onMinFabItemClick = {
onItemClick(minFabItem)
}
)
Spacer(modifier = Modifier.size(16.dp))
}
}
FloatingActionButton(
onClick = {
onFabStateChanged(
when (fabState) {
FabState.Expanded -> {
FabState.Collapsed
}
FabState.Collapsed -> {
FabState.Expanded
}
}
)
}
) {
Icon(
imageVector = icon,
tint = iconTint,
contentDescription = null,
modifier = Modifier.rotate(rotate)
)
}
}
}
我定义的常量用于对按钮进行动画处理,这些按钮将根据 FAB 状态显示/隐藏。
当我第一次创建该函数时,原始条件给了我不同的行为,并尝试了所有可能的条件,我得到了 3 个不同的结果:
- 第一个条件:
if (transition.currentState == FabState.Expanded) {...}
结果:animation not loading from collapsed to expanded, but it does from expanded to collapsed
- 第二个条件:
if (fabState == FabState.Expanded) {...}
结果:animation loading from collapsed to expanded, but not from expanded to collapsed
第三个条件(我现在正在使用的):
if (fabState == FabState.Expanded ||transition.currentState == FabState.Expanded) {...}
结果:animation loading in both ways
所以我的问题是:每个条件如何改变动画的行为?
如有任何帮助,我们将不胜感激。提前致谢
最佳答案
fabState
在调用 onFabStateChanged
后立即更新,transition.currentState
在结束转换和 transition 时更新。 isRunning
返回 false
仅当可组合项存在于树中时才会发生动画。当 if block 中的条件为 false 时,元素不可用于动画。
条件1在进入期间为假,这会破坏进入动画,条件2在退出期间为假,这会破坏退出动画,并且在退出后两者都是假。因此,合并它们解决了您的问题,并在不需要时从树中删除可组合项。
更好的方法
AnimatedVisibility(
visible = fabState == FabState.Expanded,
enter = fadeIn()+ scaleIn(),
exit = fadeOut() + scaleOut(),
) {
miniFabItems.forEach { minFabItem ->
MinFab(
fabItem = minFabItem,
textShadow = 0.dp,
onMinFabItemClick = {
onItemClick(minFabItem)
}
)
Spacer(modifier = Modifier.size(16.dp))
}
}
并使用graphicsLayer
修饰符来代替旋转
Icon(
imageVector = Icons.Default.Add,
tint = Color.White,
contentDescription = null,
modifier = Modifier
.graphicsLayer {
this.rotationZ = rotate
}
)
关于android - Jetpack Compose 动画的行为是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74751157/