簡體   English   中英

Jetpack Compose MutableTransitionState currentState 持有錯誤的值

[英]Jetpack Compose MutableTransitionState currentState holds wrong value

我使用AnimatedVisibility來動畫從LazyColumn刪除一個項目以及MutableTransitionState來捕捉動畫結束以從LazyColumn的列表中刪除這個項目。

我為此編寫了一個方便的擴展函數:

@ExperimentalTransitionApi
fun MutableTransitionState<Boolean>.transitionState(): TransitionState =
         if (this.isIdle && this.currentState)  TransitionState.Visible
    else if (this.isIdle && !this.currentState) TransitionState.Invisible
    else if (!this.isIdle && this.currentState) TransitionState.Disappearing
    else TransitionState.Appearing


enum class TransitionState(private val whatever: Int) {
    Visible(1),
    Appearing(2),
    Invisible(-1),
    Disappearing(-2)
}

從某種意義上說,它返回正確的值(經過測試)是正確的,但currentState似乎只是最初為false ,所以我無法捕捉到我唯一感興趣的事件 - Invisible

這是我的LazyColumn

val items by viewModel.itemsFlow.collectAsState()

LazyColumn(
    verticalArrangement = Arrangement.spacedBy(10.dp),
    contentPadding = PaddingValues(horizontal = 15.dp, vertical = 15.dp)
) {
    items(items) { item ->
        val animationState = remember {
            MutableTransitionState(false) // The only time currentState is false!
        }.apply { targetState = true }
        AnimatedVisibility(
            visibleState = animationState,
            enter = slideInVertically() + fadeIn(),
            exit = slideOutHorizontally(
                targetOffsetX = { it*2 },
                animationSpec = tween(
                    durationMillis = 700
                )
            )
        ) {
            ItemCard(
                item = item,
                viewModel = viewModel,
                animationState = animationState
            )
        }
    }
}

我的ItemCard有一個將animationState.tagetValue更改為falseButton ,並且狀態記錄在卡片中:

Card {
    Log.v("ANIMATION", "View ${item.name} is now ${animationState.transitionState().name}")
    Log.v("ANIMATION", "View ${item.name} has values: isIdle = ${animationState.isIdle}, currentState = ${animationState.currentState}")
        /*...*/
        Button(
            /*...*/
            onClick = {
                animationState.targetState = false
            }
        ) {/*...*/}
 }

很不幸,我的日志是這樣的:

V/ANIMATION: View name is now Appearing
V/ANIMATION: View name has values: isIdle = false, currentState = false
V/ANIMATION: View name is now Appearing
V/ANIMATION: View name has values: isIdle = false, currentState = false
V/ANIMATION: View name is now Visible
V/ANIMATION: View name has values: isIdle = true, currentState = true
V/ANIMATION: View name is now Visible
V/ANIMATION: View name has values: isIdle = true, currentState = true
// After I click the button:
V/ANIMATION: View name is now Disappearing
V/ANIMATION: View name has values: isIdle = false, currentState = true
V/ANIMATION: View name is now Disappearing
V/ANIMATION: View name has values: isIdle = false, currentState = true
V/ANIMATION: View name is now Disappearing
V/ANIMATION: View name has values: isIdle = false, currentState = true

那么隱形狀態在哪里,即false currentState 我做錯了什么嗎?

每次更改狀態時,都會觸發相關的視圖重組。 並且您在每次重新組合時使用.apply { targetState = true }animationState設置為true

很可能您想在開始時顯示動畫,然后您需要使用LaunchedEffect :它只會在視圖出現時調用一次。

val animationState = remember {
    MutableTransitionState(false)
}
LaunchedEffect(Unit) {
    animationState.targetState = true
}

閱讀更多關於Thinking in Compose 中的重組和狀態文檔中 Compose 中的state 的更多信息

經過一些測試...

我在一個單獨的項目中測試了這種類型的動畫,並發現AnimatedVisibility內容在animationState發出其最終值之前已被處理,因此您不可能從您正在制作動畫的視圖內部捕獲它。

按照@Philip Dukhov 的建議,我的LazyColumn項目現在是這樣的:

            val animationState by remember {
                mutableStateOf(MutableTransitionState(false))
            }
            LaunchedEffect(Unit) {
                animationState.targetState = true
            }
            when(animationState.transitionState()) {
                TransitionState.Invisible -> viewModel.deleteInvisibleItems()
                else -> {}
            }
            Log.v("ANIMATION", "View ${item.name} is now ${animationState.transitionState().name}")

這可以完美地捕獲發出的值。

暫無
暫無

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

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