The issue seems to be happening when doing consecutive operations (push or pop), best explained with video:
https://user-images.githubusercontent.com/20369236/177795492-c806aeaa-2046-467a-ad29-7ff85852a7c6.mp4
Full sample code:
class RootActivity : NodeActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
setContent {
MaterialTheme {
NodeHost(
integrationPoint = integrationPoint,
factory = { buildContext ->
RootNode(
buildContext = buildContext,
backstack = BackStack(
initialElement = RootNode.Routing.Child("Root"),
savedStateMap = buildContext.savedStateMap,
)
)
},
)
}
}
}
}
class RootNode(
buildContext: BuildContext,
private val backstack: BackStack<Routing>,
) : ParentNode<RootNode.Routing>(
routingSource = backstack,
buildContext = buildContext,
) {
sealed class Routing : Parcelable {
@Parcelize
data class Child(val id: String) : Routing()
}
@Composable
override fun View(modifier: Modifier) {
Surface(
modifier = modifier.fillMaxSize(),
color = Color.White
) {
Children(
routingSource = backstack,
transitionHandler = rememberBackstackSlider(
transitionSpec = { tween(2000, easing = LinearEasing) }
),
)
}
}
override fun resolve(routing: Routing, buildContext: BuildContext): Node {
return ChildNode(
name = when (routing) {
is Routing.Child -> routing.id
},
buildContext = buildContext,
pushNew = { backstack.push(Routing.Child(UUID.randomUUID().toString())) },
)
}
}
class ChildNode(
private val name: String,
private val pushNew: () -> Unit,
buildContext: BuildContext
) : Node(buildContext = buildContext) {
private val colors = listOf(
manatee,
sizzling_red,
atomic_tangerine,
silver_sand,
md_pink_500,
md_indigo_500,
md_blue_500,
md_light_blue_500,
md_cyan_500,
md_teal_500,
md_light_green_500,
md_lime_500,
md_amber_500,
md_grey_500,
md_blue_grey_500
)
private val colorIndex =
buildContext.savedStateMap?.get(KEY_COLOR_INDEX) as? Int ?: Random.nextInt(colors.size)
private val color = colors[colorIndex]
override fun onSaveInstanceState(state: MutableSavedStateMap) {
super.onSaveInstanceState(state)
state[KEY_COLOR_INDEX] = colorIndex
}
@Composable
override fun View(modifier: Modifier) {
Box(
modifier = Modifier
.fillMaxSize()
.background(
color = color,
shape = RoundedCornerShape(6.dp)
)
) {
Column(
modifier = Modifier.padding(24.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
Text("Child ($name).")
Row {
// Local UI state should be saved too (both in backstack and onSaveInstanceState)
var counter by rememberSaveable { mutableStateOf(0) }
Text(text = "Counter $counter", modifier = Modifier.align(CenterVertically))
Spacer(modifier = Modifier.width(16.dp))
Button(onClick = { counter++ }, content = { Text("Increment") })
}
Row {
Button(onClick = { navigateUp() }, content = { Text("Go up") })
}
Row {
Button(onClick = pushNew, content = { Text("Push new") })
}
}
}
}
companion object {
private const val KEY_COLOR_INDEX = "ColorIndex"
}
}
bug