簡體   English   中英

Jetpack Compose 動畫的行為是什么?

[英]What is the behavior of Jetpack Compose animations?

在我的 android 項目中,我正在做一個簡單的浮動操作按鈕,它可以展開並顯示按鈕列表以執行不同的操作。 要跟蹤 FAB 的當前 state,我有下一個枚舉 class

enum class FabState {
    Expanded,
    Collapsed
}

為了顯示浮動操作按鈕,我有以下可組合項 function:

@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 state 的按鈕。

當我第一次制作 function 時,原始條件給了我不同的行為,並嘗試了所有可能的條件,我得到了 3 個不同的結果:

  • 第一個條件: if (transition.currentState == FabState.Expanded) {...}

結果: animation 不是從折疊加載到展開,而是從展開加載到折疊

  • 第二個條件: if (fabState == FabState.Expanded) {...}

結果: animation 加載從折疊到展開,但不是從展開到折疊

第三個條件(我現在正在使用的條件): if (fabState == FabState.Expanded || transition.currentState == FabState.Expanded) {...}

結果: animation 雙向加載

所以我的問題是:每個條件如何改變動畫的行為?

任何幫助,將不勝感激。 提前致謝

一旦調用fabState就會更新onFabStateChanged並且transition.currentState在它結束轉換時更新並且transition.isRunning返回 false

Animation 僅當樹中存在可組合項時才會發生。 當 if 塊中的條件為假時,元素不可用於 animation。

在打破進入 animation 的進入期間條件 1 為假,在打破退出 animation 的退出期間條件 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修改器來代替rotate

Icon(
    imageVector = Icons.Default.Add,
    tint = Color.White,
    contentDescription = null,
    modifier = Modifier
        .graphicsLayer {
            this.rotationZ = rotate
        }
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM