typealias Actions = @Composable () -> Unit
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
SampleAppTheme {
var currentScreen by remember { mutableStateOf(Screen.A) }
var title by remember { mutableStateOf("Screen A") }
var action by remember { mutableStateOf<Actions>({}) }
Scaffold(
topBar = {
TopAppBar(
title = {
Text(title)
},
actions = {
action()
}
)
}
) {
Crossfade(current = currentScreen) { screen ->
when (screen) {
Screen.A -> {
MyScreen(
name = "A",
buttonName = "to Screen B",
onNext = {
currentScreen = Screen.B
title = "Screen B"
action = {
IconButton(onClick = {}) {
Icon(asset = Icons.Sharp.Home)
}
}
}
)
}
Screen.B -> {
MyScreen(
name = "B",
buttonName = "to Screen C",
onNext = {
currentScreen = Screen.C
title = "Screen B"
action = {
IconButton(onClick = {}) {
Icon(asset = Icons.Sharp.Close)
}
}
}
)
}
Screen.C -> {
MyScreen(
name = "C",
buttonName = "to Screen A",
onNext = {
currentScreen = Screen.A
title = "Screen A"
action = {}
}
)
}
}
}
}
}
}
}
}
enum class Screen {
A, B, C
}
@Composable
fun MyScreen(
name: String,
buttonName: String,
onNext: () -> Unit,
) {
Column(
Modifier.fillMaxSize().padding(24.dp),
) {
Text(
modifier = Modifier.weight(1f),
text = "I am in screen $name!",
textAlign = TextAlign.Center,
style = MaterialTheme.typography.h3
)
Button(
modifier = Modifier.fillMaxWidth(),
onClick = onNext
) {
Text(text = buttonName)
}
}
}
So with this code I have the following screen:
Notice that I am able to change the Actions in the TopAppBar, depending on the Current Screen by doing:
MyScreen(
name = "B",
buttonName = "to Screen C",
onNext = {
currentScreen = Screen.C
title = "Screen B"
// This right here!!!! -------------------
action = {
IconButton(onClick = {}) {
Icon(asset = Icons.Sharp.Close)
}
}
// This right here!!!! -------------------
}
)
My first question is whether this is a correct way to this?
For the second question, I kinda feel the values I am setting in the previous screen should instead be the responsibility of the current screen instead. so I tried doing this instead?
Screen.B -> {
// This right here!!!! -------------------
onActive {
title = "Screen B"
action = {
IconButton(onClick = {}) {
Icon(asset = Icons.Sharp.Home)
}
}
}
// This right here!!!! -------------------
MyScreen(
name = "B",
buttonName = "to Screen C",
onNext = {
currentScreen = Screen.C
}
)
}
So now, the responsibility of setting up the state is on the current screen and not the screen before it like before.
Is this better?
After some testing: Apparently moving from Screen A -> Screen B -> Screen C makes it that onActive { } gets called the wrong order. So there are states where Screen B have Screen A as its title... Screen C have Screen B as its title and so on...
Just realize even the first approach has flaws as you also have to set the state when going back to a screen.. lets say when doing... Screen A -> Screen B -> Screen C -> press back (Screen B)... Now the state is wrong...


