Skip to content

Commit

Permalink
Fix popBackStack() animation #6
Browse files Browse the repository at this point in the history
  • Loading branch information
massivemadness committed Feb 2, 2023
1 parent 14f6285 commit 7bb0d11
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 9 deletions.
Expand Up @@ -111,11 +111,13 @@ fun FragulaNavHost(
animDurationMs = animDurationMs,
elevation = elevation,
offsetProvider = { parallaxOffset },
systemBackProvider = { swipeBackNavigator.systemBack.value != null },
positionChanger = { position, positionOffset, positionOffsetPixels ->
onPageScrolled(position, positionOffset, positionOffsetPixels)
parallaxOffset = positionOffset
},
scrollFinished = { swipeBackNavigator.markTransitionComplete(backStackEntry) },
onScrollCancelled = { swipeBackNavigator.slideOut = it == SwipeState.SLIDE_OUT },
onScrollFinished = { swipeBackNavigator.markTransitionComplete(backStackEntry) },
modifier = modifier.fillMaxSize(),
) {
NavHostContent(saveableStateHolder, backStackEntry)
Expand Down Expand Up @@ -144,8 +146,10 @@ private fun SwipeableBox(
animDurationMs: Int,
elevation: Dp,
offsetProvider: () -> Float,
systemBackProvider: () -> Boolean,
positionChanger: (Int, Float, Int) -> Unit,
scrollFinished: () -> Unit,
onScrollCancelled: (SwipeState) -> Unit,
onScrollFinished: () -> Unit,
modifier: Modifier = Modifier,
content: @Composable () -> Unit,
) {
Expand Down Expand Up @@ -177,13 +181,13 @@ private fun SwipeableBox(
pageStart -> {
pointerPosition = pageStart
swipeState = SwipeState.FOLLOW_POINTER
scrollFinished()
onScrollFinished()
}
pageEnd -> {
pointerPosition = pageStart
swipeState = SwipeState.FOLLOW_POINTER
navController.popBackStack()
scrollFinished()
onScrollFinished()
}
}
}
Expand All @@ -196,16 +200,17 @@ private fun SwipeableBox(
val positionOffsetPixels = (pageEnd * (1.0f - positionOffset)).toInt()
val positionActual = if (scrollPosition > pageStart) position - 1 else position
positionChanger(positionActual, positionOffset, positionOffsetPixels)

if (systemBackProvider()) { // system back button
swipeState = SwipeState.SLIDE_OUT
}
}

DisposableEffect(position) {
LaunchedEffect(position) {
if (animateSlideIn) {
animateSlideIn = false
swipeState = SwipeState.SLIDE_IN
}
onDispose {
// TODO popBackStack animation
}
}

val applyScrim by remember {
Expand Down Expand Up @@ -237,6 +242,7 @@ private fun SwipeableBox(
pointerPosition < pageEnd / 2 -> SwipeState.SLIDE_IN
else -> SwipeState.FOLLOW_POINTER
}
onScrollCancelled(swipeState)
}
},
).graphicsLayer {
Expand Down
@@ -1,6 +1,7 @@
package com.fragula2.compose

import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.navigation.*
import androidx.navigation.compose.rememberNavController
Expand Down Expand Up @@ -28,8 +29,10 @@ fun rememberSwipeBackNavigator(): SwipeBackNavigator {
@Navigator.Name("swipeable")
class SwipeBackNavigator : Navigator<SwipeBackNavigator.Destination>() {

internal val systemBack = mutableStateOf<Pair<NavBackStackEntry, Boolean>?>(null)
internal val transitionsInProgress get() = state.transitionsInProgress
internal val backStack get() = state.backStack
internal var slideOut = false

override fun navigate(
entries: List<NavBackStackEntry>,
Expand All @@ -46,7 +49,25 @@ class SwipeBackNavigator : Navigator<SwipeBackNavigator.Destination>() {
}

override fun popBackStack(popUpTo: NavBackStackEntry, savedState: Boolean) {
state.popWithTransition(popUpTo, savedState)
when {
slideOut -> {
state.popWithTransition(
popUpTo = popUpTo,
saveState = savedState,
)
slideOut = false
}
systemBack.value == null -> {
systemBack.value = popUpTo to savedState
}
systemBack.value != null -> {
state.popWithTransition(
popUpTo = systemBack.value?.first ?: return,
saveState = systemBack.value?.second ?: return,
)
systemBack.value = null
}
}
}

internal fun markTransitionComplete(entry: NavBackStackEntry) {
Expand Down

0 comments on commit 7bb0d11

Please sign in to comment.