Improve screen transitions
This commit is contained in:
parent
6f222ac564
commit
982a7eaca7
|
@ -3,6 +3,8 @@ package it.vfsfitvnm.vimusic.ui.components.themed
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.text.format.DateUtils
|
import android.text.format.DateUtils
|
||||||
import androidx.compose.animation.AnimatedContentScope
|
import androidx.compose.animation.AnimatedContentScope
|
||||||
|
import androidx.compose.animation.EnterTransition
|
||||||
|
import androidx.compose.animation.ExitTransition
|
||||||
import androidx.compose.animation.ExperimentalAnimationApi
|
import androidx.compose.animation.ExperimentalAnimationApi
|
||||||
import androidx.compose.animation.with
|
import androidx.compose.animation.with
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
|
@ -35,7 +37,6 @@ import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.media3.common.MediaItem
|
import androidx.media3.common.MediaItem
|
||||||
import it.vfsfitvnm.route.RouteHandler
|
import it.vfsfitvnm.route.RouteHandler
|
||||||
import it.vfsfitvnm.route.empty
|
|
||||||
import it.vfsfitvnm.vimusic.Database
|
import it.vfsfitvnm.vimusic.Database
|
||||||
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
|
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
|
||||||
import it.vfsfitvnm.vimusic.R
|
import it.vfsfitvnm.vimusic.R
|
||||||
|
@ -282,7 +283,7 @@ fun MediaItemMenu(
|
||||||
else -> when (initialState.route) {
|
else -> when (initialState.route) {
|
||||||
viewPlaylistsRoute -> slideIntoContainer(AnimatedContentScope.SlideDirection.Right) with
|
viewPlaylistsRoute -> slideIntoContainer(AnimatedContentScope.SlideDirection.Right) with
|
||||||
slideOutOfContainer(AnimatedContentScope.SlideDirection.Right)
|
slideOutOfContainer(AnimatedContentScope.SlideDirection.Right)
|
||||||
else -> empty
|
else -> EnterTransition.None with ExitTransition.None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,12 @@ import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
|
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
|
||||||
import it.vfsfitvnm.route.RouteHandler
|
import it.vfsfitvnm.route.RouteHandler
|
||||||
|
import it.vfsfitvnm.route.defaultStacking
|
||||||
|
import it.vfsfitvnm.route.defaultStill
|
||||||
|
import it.vfsfitvnm.route.defaultUnstacking
|
||||||
|
import it.vfsfitvnm.route.isStacking
|
||||||
|
import it.vfsfitvnm.route.isUnknown
|
||||||
|
import it.vfsfitvnm.route.isUnstacking
|
||||||
import it.vfsfitvnm.vimusic.Database
|
import it.vfsfitvnm.vimusic.Database
|
||||||
import it.vfsfitvnm.vimusic.R
|
import it.vfsfitvnm.vimusic.R
|
||||||
import it.vfsfitvnm.vimusic.models.SearchQuery
|
import it.vfsfitvnm.vimusic.models.SearchQuery
|
||||||
|
@ -33,7 +39,21 @@ import it.vfsfitvnm.vimusic.utils.rememberPreference
|
||||||
fun HomeScreen(onPlaylistUrl: (String) -> Unit) {
|
fun HomeScreen(onPlaylistUrl: (String) -> Unit) {
|
||||||
val saveableStateHolder = rememberSaveableStateHolder()
|
val saveableStateHolder = rememberSaveableStateHolder()
|
||||||
|
|
||||||
RouteHandler(listenToGlobalEmitter = true) {
|
RouteHandler(
|
||||||
|
listenToGlobalEmitter = true,
|
||||||
|
transitionSpec = {
|
||||||
|
when {
|
||||||
|
isStacking -> defaultStacking
|
||||||
|
isUnstacking -> defaultUnstacking
|
||||||
|
isUnknown -> when {
|
||||||
|
initialState.route == searchRoute && targetState.route == searchResultRoute -> defaultStacking
|
||||||
|
initialState.route == searchResultRoute && targetState.route == searchRoute -> defaultUnstacking
|
||||||
|
else -> defaultStill
|
||||||
|
}
|
||||||
|
else -> defaultStill
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) {
|
||||||
globalRoutes()
|
globalRoutes()
|
||||||
|
|
||||||
settingsRoute {
|
settingsRoute {
|
||||||
|
@ -65,6 +85,7 @@ fun HomeScreen(onPlaylistUrl: (String) -> Unit) {
|
||||||
SearchScreen(
|
SearchScreen(
|
||||||
initialTextInput = initialTextInput,
|
initialTextInput = initialTextInput,
|
||||||
onSearch = { query ->
|
onSearch = { query ->
|
||||||
|
pop()
|
||||||
searchResultRoute(query)
|
searchResultRoute(query)
|
||||||
|
|
||||||
query {
|
query {
|
||||||
|
|
|
@ -21,7 +21,13 @@ fun RouteHandler(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
listenToGlobalEmitter: Boolean = false,
|
listenToGlobalEmitter: Boolean = false,
|
||||||
handleBackPress: Boolean = true,
|
handleBackPress: Boolean = true,
|
||||||
transitionSpec: AnimatedContentScope<RouteHandlerScope>.() -> ContentTransform = { fastFade },
|
transitionSpec: AnimatedContentScope<RouteHandlerScope>.() -> ContentTransform = {
|
||||||
|
when {
|
||||||
|
isStacking -> defaultStacking
|
||||||
|
isStill -> defaultStill
|
||||||
|
else -> defaultUnstacking
|
||||||
|
}
|
||||||
|
},
|
||||||
content: @Composable RouteHandlerScope.() -> Unit
|
content: @Composable RouteHandlerScope.() -> Unit
|
||||||
) {
|
) {
|
||||||
var route by rememberSaveable(stateSaver = Route.Saver) {
|
var route by rememberSaveable(stateSaver = Route.Saver) {
|
||||||
|
@ -47,7 +53,13 @@ fun RouteHandler(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
listenToGlobalEmitter: Boolean = false,
|
listenToGlobalEmitter: Boolean = false,
|
||||||
handleBackPress: Boolean = true,
|
handleBackPress: Boolean = true,
|
||||||
transitionSpec: AnimatedContentScope<RouteHandlerScope>.() -> ContentTransform = { fastFade },
|
transitionSpec: AnimatedContentScope<RouteHandlerScope>.() -> ContentTransform = {
|
||||||
|
when {
|
||||||
|
isStacking -> defaultStacking
|
||||||
|
isStill -> defaultStill
|
||||||
|
else -> defaultUnstacking
|
||||||
|
}
|
||||||
|
},
|
||||||
content: @Composable RouteHandlerScope.() -> Unit
|
content: @Composable RouteHandlerScope.() -> Unit
|
||||||
) {
|
) {
|
||||||
val backDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher
|
val backDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher
|
||||||
|
|
|
@ -3,27 +3,44 @@ package it.vfsfitvnm.route
|
||||||
import androidx.compose.animation.AnimatedContentScope
|
import androidx.compose.animation.AnimatedContentScope
|
||||||
import androidx.compose.animation.ContentTransform
|
import androidx.compose.animation.ContentTransform
|
||||||
import androidx.compose.animation.EnterTransition
|
import androidx.compose.animation.EnterTransition
|
||||||
import androidx.compose.animation.ExitTransition
|
|
||||||
import androidx.compose.animation.ExperimentalAnimationApi
|
import androidx.compose.animation.ExperimentalAnimationApi
|
||||||
import androidx.compose.animation.core.tween
|
|
||||||
import androidx.compose.animation.fadeIn
|
import androidx.compose.animation.fadeIn
|
||||||
import androidx.compose.animation.fadeOut
|
import androidx.compose.animation.fadeOut
|
||||||
import androidx.compose.animation.with
|
import androidx.compose.animation.scaleOut
|
||||||
|
|
||||||
@ExperimentalAnimationApi
|
@ExperimentalAnimationApi
|
||||||
val AnimatedContentScope<RouteHandlerScope>.leftSlide: ContentTransform
|
val defaultStacking = ContentTransform(
|
||||||
get() = slideIntoContainer(AnimatedContentScope.SlideDirection.Left) with
|
initialContentExit = scaleOut(targetScale = 0.9f) + fadeOut(),
|
||||||
slideOutOfContainer(AnimatedContentScope.SlideDirection.Left)
|
targetContentEnter = fadeIn(),
|
||||||
|
targetContentZIndex = 1f
|
||||||
|
)
|
||||||
|
|
||||||
@ExperimentalAnimationApi
|
@ExperimentalAnimationApi
|
||||||
val AnimatedContentScope<RouteHandlerScope>.rightSlide: ContentTransform
|
val defaultUnstacking = ContentTransform(
|
||||||
get() = slideIntoContainer(AnimatedContentScope.SlideDirection.Right) with
|
initialContentExit = fadeOut(),
|
||||||
slideOutOfContainer(AnimatedContentScope.SlideDirection.Right)
|
targetContentEnter = EnterTransition.None,
|
||||||
|
targetContentZIndex = 0f
|
||||||
|
)
|
||||||
|
|
||||||
@ExperimentalAnimationApi
|
@ExperimentalAnimationApi
|
||||||
val AnimatedContentScope<RouteHandlerScope>.fastFade: ContentTransform
|
val defaultStill = ContentTransform(
|
||||||
get() = fadeIn(tween(200)) with fadeOut(tween(200))
|
initialContentExit = scaleOut(targetScale = 0.9f) + fadeOut(),
|
||||||
|
targetContentEnter = fadeIn(),
|
||||||
|
targetContentZIndex = 1f
|
||||||
|
)
|
||||||
|
|
||||||
@ExperimentalAnimationApi
|
@ExperimentalAnimationApi
|
||||||
val AnimatedContentScope<RouteHandlerScope>.empty: ContentTransform
|
inline val AnimatedContentScope<RouteHandlerScope>.isStacking: Boolean
|
||||||
get() = EnterTransition.None with ExitTransition.None
|
get() = initialState.route == null && targetState.route != null
|
||||||
|
|
||||||
|
@ExperimentalAnimationApi
|
||||||
|
inline val AnimatedContentScope<RouteHandlerScope>.isUnstacking: Boolean
|
||||||
|
get() = initialState.route != null && targetState.route == null
|
||||||
|
|
||||||
|
@ExperimentalAnimationApi
|
||||||
|
inline val AnimatedContentScope<RouteHandlerScope>.isStill: Boolean
|
||||||
|
get() = initialState.route == null && targetState.route == null
|
||||||
|
|
||||||
|
@ExperimentalAnimationApi
|
||||||
|
inline val AnimatedContentScope<RouteHandlerScope>.isUnknown: Boolean
|
||||||
|
get() = initialState.route != null && targetState.route != null
|
||||||
|
|
Loading…
Reference in a new issue