Contenuti

Android Toolbar Actions with Compose

Contenuti

Intro

Before Jetpack Compose release we were used to add menu items in Fragments or Activities classes with xml files and onCreateOptionsMenu methods.

The new UI tool is a game changer and via Scaffold composable it’s easy to add global actions to TopAppBar. With global actions I mean items that remains visible for the entire lifecycle of the controller class. When using Jetpack Navigation however there is only one Activity and the NavHost swaps composable destinations on the screen.

In this scenario is useful to have a concise way to easily add or remove actions from the ToolBar for each navigation route.

The following video shows the sample app available at this link

Sample code

Note
Provide an AAR for this feature is overkilling. You can find the ToolBarController implementation in this package.

Define a toolbarController instance (Hoist instance as up as possible)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
val toolbarController = rememberToolbarController()

val screenToolbarActions by remember {
    derivedStateOf {
        val route = currentBackStackEntry?.destination?.route ?: ""
        toolbarController.getToolbarActions(route = route)
    }
}

...
Scaffold(
    topBar = {
        TopAppBar {
            ToolbarContent(
                ...
                screenAdditionalToolbarActions = screenToolbarActions,
                navController = navController
            )
        }
    }
)
...

In composable Destination define toolbar items

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
@Composable
fun FirstScreen(
    toolbarController: ToolbarController = rememberToolbarController()
) {

    toolbarController.SetActions(  
        route = NavGraph.FIRST_SCREEN_ROUTE,  
        actions = listOf(ToolbarAction.OpenSettings {
            Toast.makeText(context, "Settings Action", Toast.LENGTH_SHORT).show()  
        })  
    )
}