Can I observe state in a state hoisting class? If ...
# compose
d
Can I observe state in a state hoisting class? If yes, how can I do it?
z
Can you give a bit more detail about what you're trying to do?
d
@Zach Klippenstein (he/him) [MOD] I have two SwipeableState, one vertical and one horizontal in a state hoisting class. Vertical have states -> Expanded and Closed Horizontal have states -> Collapsed and Opened When the horizontal swipeableState changes to opened and the vertical is state(expanded), I want to animate the vertical to collapsed
z
Use a snapshotFlow to observe the states, and then you can also do the animation from the coroutine. Not at a computer at the moment so can't give you code. But snapshotFlow is your friend here.
d
It worked, thanks @Zach Klippenstein (he/him) [MOD]
s
I’d be curious to see how you solved your problem and to see snapshotFlow in action. Would it be possible to share what you did Daniel?
d
Copy code
@OptIn(ExperimentalMaterialApi::class)
class HomeAnimationState constructor(
    val horizontalSwipeState: SwipeableState<MenuState>,
    val verticalSwipeState: SwipeableState<CardState>,
    coroutineScope: CoroutineScope
) {
    private var previousCardState = verticalSwipeState.currentValue

    val collapsedCardProgress by derivedStateOf {
        when (verticalSwipeState.progress.from) {
            CardState.Collapsed -> if (verticalSwipeState.progress.fraction == 1f) 1f
            else 1 - verticalSwipeState.progress.fraction
            CardState.Expanded -> if (verticalSwipeState.progress.fraction == 1f) 0f
            else verticalSwipeState.progress.fraction
        }
    }

    init {
        coroutineScope.launch {
            snapshotFlow { horizontalSwipeState.isAnimationRunning }
                .distinctUntilChanged()
                .filter { it }
                .collect {
                    transition()
                }
        }
    }

    private suspend fun transition() {
        val targetHorizontalState = horizontalSwipeState.targetValue
        val currentVerticalState = verticalSwipeState.currentValue

        when {
            targetHorizontalState == MenuState.Opened &&
                    currentVerticalState == CardState.Expanded -> {
                previousCardState = CardState.Expanded
                verticalSwipeState.animateTo(CardState.Collapsed)
            }
            targetHorizontalState == MenuState.Closed &&
                    previousCardState == CardState.Expanded -> {
                verticalSwipeState.animateTo(CardState.Expanded)
            }
            targetHorizontalState == MenuState.Opened &&
                    currentVerticalState == CardState.Collapsed -> {
                previousCardState = CardState.Collapsed
            }
        }
    }
}
@Stylianos Gakis
🙏 1