Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change AppBar Menu in Jetpack Compose?

I was wondering how to change Appbar Menu in Jetpack Compose.

In the Fragment world to achieve this is to do something like this:

class SampleFragment : Fragment() {
    override fun onCreate(context: Context) {
        super.onCreate(context)
        setHasOptionsMenu(true)
    }

    // Set the R.menu.sampleMenu in the AppBar
    override fun onCreateOptionsMenu(menu: Menu) {
        ...
        menuInflater.inflate(R.menu.sampleMenu, menu)
    }

    // To handle clicks on the menu
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        // Check id of menu item and process as follow
    }
...
}

I was wondering how to do the exact same thing in Compose. I was thinking of having like:

// Have a top level state which could be set 
var menu by remember { mutableStateOf(emptyList<Menu>()) }

....
TopAppBar {
    ....
    menu.forEach {
        TextButton(...)
    }
}

....

//and then on my content ill set the `menu` to a value
onCommit {
    menu = listOf(Menu1, Menu2, Menu3, ...)
}

I was wondering whether this is the right way to do this or whether there is a better way.

I would love to have some inputs and advice thank you very much.

like image 851
Archie G. Quiñones Avatar asked Oct 25 '20 16:10

Archie G. Quiñones


1 Answers

There is a component called DropdownMenu, which you can read about here: https://developer.android.com/reference/kotlin/androidx/compose/material/package-summary#dropdownmenu

Note that you shouldn't wrap that in a button, there is a param called toggle which will be the button to open the menu.

There is also a DropdownMenuItem, that styles as defined by the Material Design spec: https://developer.android.com/reference/kotlin/androidx/compose/material/package-summary#dropdownmenuitem

About the navigation, I believe is a whole other matter, and if you have questions about that, please post other questions with details.

Here is a little sample:

var menuExpanded by remember { mutableStateOf(false) }
DropdownMenu(
    toggle = {
        TextButton({ menuExpanded = !menuExpanded }) {
            Text("Open menu", color = Color.White)
        }
    },
    expanded = menuExpanded,
    onDismissRequest = {
        menuExpanded = false
    },
) {
    DropdownMenuItem(onClick = {}) {
        Text("First item")
    }
    DropdownMenuItem(onClick = {}) {
        Text("Second item")
    }
    DropdownMenuItem (onClick = {}) {
        Text("Third item")
    }
}

EDIT: since you commented that your issue is with sharing the app bar across screen, it's important to point out that this will behave the way you implement it to be, for instance, in the code below I would have different app bars for different screens and the issue would be solved, of course that's a very simplistic sample that wouldn't be viable with more than a few screens. But there are content out there about handling navigation in Compose and if you have issues with that, you can ask other questions scoping exactly what you need.

val currentScreen by viewModel.currentScreen.observeAsState(Screen.HOME)
when (currentScreen) {
    Screen.HOME -> Scaffold(/* topBar = ... */) {
        // Home body
    }
    Screen.PROFILE -> Scaffold(/* topBar = ... */) {
        // Profile body
    }
    Screen.CHAT -> Scaffold(/* topBar = ... */) {
        // Chat body
    }
}
like image 54
Vitor Ramos Avatar answered Sep 28 '22 04:09

Vitor Ramos