How to change Scaffold Floating Action Button action with different screens. Jetpack Compose

Viewed 939

How can I change FAB action(onClick{}) depending on current screen with Scaffold.

            Scaffold(
                floatingActionButton = {
                    FloatingActionButton(onClick = { 
                        //Different actions here depending on current screen
                    }) { }
                }
            ) {
                NavHost(
                    navController = navController,
                    startDestination = "route1"
                ) {
                    composable(
                        route = "route1"
                    ) {
                        ScreenOne()
                    }

                    composable(
                        route = "route2"
                    ) {
                        ScreenTwo()
                    }
                }
            }

For example with ScreenOne() I want to add some entities to database and with ScreenTwo() I'd like to save edited entity. And all this using same FAB shared by Scaffold.

UPDATE: Just understood that I also need to mention that I'm also need FAB to know some data to operate. For example I'd like to save some entity to database by clicking on FAB, so FAB need to know about this entity.

Example: I'm clicking on some item in the list. It opens some navigation direction with some entity. I'm modifying this entity and clicking on FAB to save edited entity.

2 Answers

You can observe the current route of the NavController and do the action accordingly.

// When you navigate to another screen, this value is updated.
val currentRoute = navController
    .currentBackStackEntryFlow
    .collectAsState(initial = navController.currentBackStackEntry)

Scaffold(
    floatingActionButton = {
        FloatingActionButton(
            onClick = {
                when (currentRoute.value?.destination?.route) {
                    "screen1" -> { /* Action for Screen 1 */ }
                    "screen2" -> { /* Action for Screen 2 */ }
                    // ...
                }
            }
        ) {
            Icon(Icons.Default.Add, contentDescription = null)
        }
    }
) {
    NavHost(navController = navController, startDestination = "screen1") {
        composable("screen1") { Screen1() }
        composable("screen2") { Screen2() }
    }
}

If you are using Navigation, you can retrieve the navController by rememberNavController() and then use this to getCurrentBackStackEntry().destination, applying conditionals in the onClick block and setting the action accordingly

Related