Refactor AnimatedOffset

This commit is contained in:
Thomas Andres Gomez 2022-06-22 14:47:23 +02:00
parent 52cfe78b6e
commit 5ac6d6b352
5 changed files with 76 additions and 40 deletions

View file

@ -1,16 +1,38 @@
package com.pixelized.biblib.ui.composable.animation package com.pixelized.biblib.ui.composable.animation
import androidx.compose.animation.*
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@Composable @Composable
fun AnimatedDelayer( fun AnimatedDelayer(
delay: Delay = Delay(), delay: Int = 0,
content: @Composable AnimatedDelayerScope.() -> Unit content: @Composable AnimatedDelayerScope.() -> Unit
) { ) {
val scope = AnimatedDelayerScope(delay = delay) val scope = AnimatedDelayerScope(
delay = Delay(value = delay)
)
scope.content() scope.content()
} }
@OptIn(ExperimentalAnimationApi::class)
@Composable
fun <T> AnimatedDelayer(
targetState: T,
delay: Int = 0,
content: @Composable AnimatedDelayerScope.(T) -> Unit
) {
AnimatedContent(
targetState = targetState,
transitionSpec = { EnterTransition.None with ExitTransition.None }
) {
AnimatedDelayer(
delay = delay,
) {
content(targetState)
}
}
}
class AnimatedDelayerScope( class AnimatedDelayerScope(
var delay: Delay = Delay() var delay: Delay = Delay()
) )

View file

@ -8,9 +8,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.State import androidx.compose.runtime.State
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.SaverScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.graphicsLayer
@ -80,6 +77,17 @@ fun AnimatedOffset(
) )
} }
//////////////////////////////////////
// region: Transition
private class TransitionData(
alpha: State<Float>,
offset: State<Dp>,
) {
val alpha by alpha
val offset by offset
}
@Composable @Composable
private fun updateTransition( private fun updateTransition(
displayed: MutableTransitionState<Boolean>, displayed: MutableTransitionState<Boolean>,
@ -114,27 +122,4 @@ private fun updateTransition(
return remember(transition) { TransitionData(alpha, offset) } return remember(transition) { TransitionData(alpha, offset) }
} }
private class TransitionData( // endregion
alpha: State<Float>,
offset: State<Dp>,
) {
val alpha by alpha
val offset by offset
}
@Composable
private inline fun <reified T> rememberSavableMutableTransitionState(
initialState: T, targetState: T
) = rememberSaveable(saver = saver()) {
MutableTransitionState(initialState).apply { this.targetState = targetState }
}
private inline fun <reified T> saver() = object : Saver<MutableTransitionState<T>, Pair<T, T>> {
override fun restore(value: Pair<T, T>): MutableTransitionState<T> {
return MutableTransitionState(value.first).apply { targetState = value.second }
}
override fun SaverScope.save(value: MutableTransitionState<T>): Pair<T, T> {
return value.currentState to value.targetState
}
}

View file

@ -0,0 +1,29 @@
package com.pixelized.biblib.ui.composable.animation
import androidx.compose.animation.core.MutableTransitionState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.SaverScope
import androidx.compose.runtime.saveable.rememberSaveable
@Composable
inline fun <reified T> rememberSavableMutableTransitionState(
initialState: T,
targetState: T,
): MutableTransitionState<T> {
return rememberSaveable(saver = mutableTransitionStateSaver()) {
MutableTransitionState(initialState).apply { this.targetState = targetState }
}
}
inline fun <reified T> mutableTransitionStateSaver() =
object : Saver<MutableTransitionState<T>, Pair<T, T>> {
override fun restore(value: Pair<T, T>): MutableTransitionState<T> {
return MutableTransitionState(value.first).apply { targetState = value.second }
}
override fun SaverScope.save(value: MutableTransitionState<T>): Pair<T, T> {
return value.currentState to value.targetState
}
}

View file

@ -1,6 +1,7 @@
package com.pixelized.biblib.ui.scaffold package com.pixelized.biblib.ui.scaffold
import android.content.Context import android.content.Context
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.material.BottomSheetScaffold import androidx.compose.material.BottomSheetScaffold
import androidx.compose.material.BottomSheetScaffoldState import androidx.compose.material.BottomSheetScaffoldState
@ -42,6 +43,10 @@ fun BottomDetailScaffold(
}, },
content = content content = content
) )
BackHandler(bottomStateController.scaffoldState.bottomSheetState.isExpanded) {
bottomStateController.collapse()
}
} }
} }

View file

@ -3,7 +3,6 @@ package com.pixelized.biblib.ui.screen.detail
import android.content.res.Configuration.UI_MODE_NIGHT_NO import android.content.res.Configuration.UI_MODE_NIGHT_NO
import android.content.res.Configuration.UI_MODE_NIGHT_YES import android.content.res.Configuration.UI_MODE_NIGHT_YES
import androidx.activity.compose.BackHandler import androidx.activity.compose.BackHandler
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
@ -33,8 +32,6 @@ import com.pixelized.biblib.ui.composable.Cover
import com.pixelized.biblib.ui.composable.SpannedText import com.pixelized.biblib.ui.composable.SpannedText
import com.pixelized.biblib.ui.composable.animation.AnimatedDelayer import com.pixelized.biblib.ui.composable.animation.AnimatedDelayer
import com.pixelized.biblib.ui.composable.animation.AnimatedOffset import com.pixelized.biblib.ui.composable.animation.AnimatedOffset
import com.pixelized.biblib.ui.composable.animation.Delay
import com.pixelized.biblib.ui.scaffold.LocalBottomDetailController
import com.pixelized.biblib.ui.screen.home.common.uio.BookUio import com.pixelized.biblib.ui.screen.home.common.uio.BookUio
import com.pixelized.biblib.ui.screen.home.common.uio.CoverUio import com.pixelized.biblib.ui.screen.home.common.uio.CoverUio
import com.pixelized.biblib.ui.theme.BibLibTheme import com.pixelized.biblib.ui.theme.BibLibTheme
@ -53,11 +50,6 @@ fun DetailScreen(
} else { } else {
Box(modifier = Modifier.fillMaxSize()) Box(modifier = Modifier.fillMaxSize())
} }
val bottomDetailState = LocalBottomDetailController.current
BackHandler {
bottomDetailState.collapse()
}
} }
@Composable @Composable
@ -68,7 +60,10 @@ private fun DetailScreenContent(
onEpub: () -> Unit = todo(), onEpub: () -> Unit = todo(),
onSend: () -> Unit = todo(), onSend: () -> Unit = todo(),
) { ) {
AnimatedDelayer(delay = Delay(300)) { AnimatedDelayer(
targetState = book,
delay = 300,
) {
Column( Column(
modifier = Modifier modifier = Modifier
.verticalScroll(rememberScrollState()) .verticalScroll(rememberScrollState())
@ -170,7 +165,7 @@ private fun DetailScreenContent(
AnimatedOffset(modifier = Modifier.weight(1f)) { AnimatedOffset(modifier = Modifier.weight(1f)) {
TitleLabel( TitleLabel(
title = stringResource(id = R.string.detail_rating), title = stringResource(id = R.string.detail_rating),
label = book.rating?.toString(), label = book.rating.toString(),
) )
} }
@ -184,7 +179,7 @@ private fun DetailScreenContent(
AnimatedOffset(modifier = Modifier.weight(1f)) { AnimatedOffset(modifier = Modifier.weight(1f)) {
TitleLabel( TitleLabel(
title = stringResource(id = R.string.detail_release), title = stringResource(id = R.string.detail_release),
label = book.date ?: "-" , label = book.date ?: "-",
) )
} }
} }