This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
A [Ambient provided with value: X] | |
└── B ... | |
└── C [Ambient overridden with value: Y] | |
└── D ... | |
└── E [Ambient read: Y] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
A [root back handler] | |
└── B ... | |
└── C [back handler with fallback to last ambient (A)] | |
└── D ... | |
└── E [back handler with fallback to last ambient (C)] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ScopedBackPressHandler { | |
var children = mutableListOf<() -> Boolean>() | |
fun handle(): Boolean = | |
children.reversed().any { it() } | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val backPressHandler: Ambient<ScopedBackPressHandler> = | |
Ambient.of { throw IllegalStateException("backPressHandler is not initialized") } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Composable | |
fun <T> BackHandler(routing: T, children: @Composable() (BackStack<T>) -> Unit) { | |
// grab the parent handler, wherever it's up the tree | |
val upstream = +ambient(backPressHandler) | |
// to keep track of children down the tree | |
val downstream = +memo { ScopedBackPressHandler() } | |
// let's have a default back stack on this level | |
val backStack = BackStack(routing) | |
// our lambda for handling back press: asking all children, | |
val handleBackPressHere: () -> Boolean = { downstream.handle() || backStack.pop() } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val handleBackPressHere: () -> Boolean = { downstream.handle() || backStack.pop() } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Composable | |
fun Content() { | |
BackHandler(Routing.AlbumList as Routing) { backStack -> | |
when (val currentRouting = backStack.last()) { | |
// all Content() on the right hand side are @Composable | |
is Routing.AlbumList -> AlbumList.Content() | |
is Routing.PhotosOfAlbum -> PhotosOfAlbum.Content(currentRouting.album) | |
is Routing.FullScreenPhoto -> FullScreenPhoto.Content(currentRouting..photo) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Composable | |
fun RootBackHandler(rootHandler: ScopedBackPressHandler, children: @Composable() () -> Unit) { | |
val downstream = +memo { ScopedBackPressHandler() } | |
val handleBackPressHere: () -> Boolean = { downstream.handle() } | |
rootHandler.handlers.add(handleBackPressHere) | |
+onDispose { rootHandler.handlers.remove(handleBackPressHere) } | |
backPressHandler.Provider(value = downstream) { | |
children() | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MainActivity : AppCompatActivity() { | |
private val rootHandler = ScopedBackPressHandler() | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
setContent { | |
MaterialTheme { | |
RootBackHandler(rootHandler) { | |
Root.Content(LoggedOut) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
A [back stack of 1 element] | |
└── B [back stack of 2 elements] | |
└── C [back stack of 4 elements] | |
└── D [back stack of 1 element] |