Skip to content

Instantly share code, notes, and snippets.

A [back stack of 2 elements]
└── X [...]
└── Y [...]
└── Z [...]
A [back stack of 1 element]
└── B [back stack of 1 element]
└── C [back stack of 1 element]
└── D [back stack of 1 element]
class Entry<T>(val element: T) {
val children: MutableMap<Any, BackStack<*>> = mutableMapOf()
}
class ScopedBackPressHandler(
// nullable, because root level doesn’t have one
var backStack: BackStack<*>? = null
) {
// remainder the same
}
@Composable
// id is a new parameter we'll use for the key in the map:
fun <T> BackHandler(id: Any, routing: T, children: @Composable() (BackStack<T>) -> Unit) {
// grab the parent handler, wherever it's up the tree
val upstream = +ambient(backPressHandler)
// is there a back stack in the upstream? then let's grab the map of the last entry
val saveRestorePoint = upstream.backStack?.lastEntry()?.children
// use existing or fall back to new instance
val backStack = saveRestorePoint?.get(id) ?: BackStack(routing).also {
saveRestorePoint?.set(id, it)
fun replace(element: T) {
elements = elements.dropLast(1) + Entry(element)
}
fun newRoot(element: T) {
elements = listOf(Entry(element))
}
fun pushAndDropNested(element: T) {
elements.last().children.clear()
push(element)
}
/**
* Based on https://medium.com/swlh/android-mvi-with-jetpack-compose-b0890f5156ac
* Adapted for 0.1.0-dev04
*/
@Composable
fun <T> observe(data: LiveData<T>): T? {
var result by state { data.value }
val observer = remember { Observer<T> { result = it } }
onCommit(data) {
sealed class Routing {
object ChildScreen1 : Routing()
object ChildScreen2 : Routing()
data class ChildScreen3(val foo: Bar) : Routing()
}
@Composable
fun MyParentComposable(defaultRouting: Routing) {
BackHandler(defaultRouting) { backStack ->
@Composable
fun PhotoAlbum() {
val photos: List<Photo> = emptyList() // TODO
TableRenderer(cols = 4, cellSpacing = 8.dp, items = photos) { cell ->
Text(cell.item.photoDescription)
}
}