Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexjlockwood/c3a334c41911b75f528074bb872b7c28 to your computer and use it in GitHub Desktop.
Save alexjlockwood/c3a334c41911b75f528074bb872b7c28 to your computer and use it in GitHub Desktop.
ScreenTransition composable
@Composable
fun <S> ScreenTransition(
targetBackstack: List<S>,
modifier: Modifier = Modifier,
content: @Composable (S) -> Unit,
) {
// TODO: figure out if we are sliding in from left or right
ScreenTransition(
targetState = targetBackstack.last(),
modifier = modifier,
content = content,
)
}
@OptIn(ExperimentalAnimationApi::class)
@Composable
private fun <S> ScreenTransition(
targetState: S,
modifier: Modifier = Modifier,
content: @Composable (S) -> Unit
) {
var screens by remember { mutableStateOf(emptyList<TransitionScreen<S>>()) }
val initiallyVisible = remember(screens) { screens.isEmpty() }
val lastTarget = remember { mutableStateOf(targetState) }
if (lastTarget.value != targetState || screens.isEmpty()) {
lastTarget.value = targetState
// Only manipulate the list when the state is changed, or in the first run.
val keys = screens.map { it.key }.run {
if (!contains(targetState)) {
toMutableList().also { it.add(targetState) }
} else {
this
}
}
screens = keys.map { key ->
TransitionScreen(key) {
AnimatedVisibility(
visible = key == targetState,
enter = slideInHorizontally(
animationSpec = tween(durationMillis = 5000),
initialOffsetX = { it },
),
exit = slideOutHorizontally(
animationSpec = tween(durationMillis = 5000),
targetOffsetX = { -it },
),
initiallyVisible = initiallyVisible,
) {
DisposableEffect(Unit) {
onDispose { screens.filterNot { it.key == key } }
}
key(key) {
content(key)
}
}
}
}
}
Box(modifier) {
screens.forEach {
key(it.key) {
it.content()
}
}
}
}
private data class TransitionScreen<T>(
val key: T,
val content: @Composable () -> Unit,
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment