Skip to content

Instantly share code, notes, and snippets.

@hoc081098
Created August 18, 2023 09:46
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 hoc081098/f989cd7cb6512439d8cf776d8880ad2b to your computer and use it in GitHub Desktop.
Save hoc081098/f989cd7cb6512439d8cf776d8880ad2b to your computer and use it in GitHub Desktop.
NavHost.kt
@Composable
fun <T: Any> rememberMutableStateListOf(vararg elements: T): SnapshotStateList<T> {
return rememberSaveable(
saver = listSaver(
save = { stateList ->
if (stateList.isNotEmpty()) {
val first = stateList.first()
if (!canBeSaved(first)) {
throw IllegalStateException("${first::class} cannot be saved. By default only types which can be stored in the Bundle class can be saved.")
}
}
stateList.toList()
},
restore = { it.toMutableStateList() }
)
) {
elements.toList().toMutableStateList()
}
}
sealed interface AppScreen : Parcelable {
@Parcelize
object ScreenA : AppScreen
@Parcelize
data class ScreenB(val id: Int) : AppScreen
}
@Composable fun NavHost() {
val stack: SnapshotStateList<AppScreen> = rememberMutableStateListOf(AppScreen.ScreenA)
val currentScreenState = remember(stack) {
derivedStateOf { stack.last() }
}
val saveableStateHolder = rememberSaveableStateHolder()
val navigateToScreen: (AppScreen) -> Unit = remember {
{ screen: AppScreen ->
stack.add(screen)
}
}
val onNavigateBack: () -> Unit = remember {
{
val removed = stack.removeLast()
saveableStateHolder.removeState(removed)
}
}
saveableStateHolder.SaveableStateProvider(key = currentScreenState.value) {
when (val screen = currentScreenState.value) {
AppScreen.ScreenA -> {
rememberSaveable {
mutableStateOf(0)
}
Button(onClick = {
navigateToScreen(AppScreen.ScreenB(1))
}) {
Text(text = "A")
}
}
is AppScreen.ScreenB -> {
Button(onClick = onNavigateBack) {
Text(text = "B ${screen.id}")
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment