This tutorial will cover how to build a menu and integrate it into your Android app. We will also learn how to create submenus, dynamically add or remove items from the menu, and create a pop-up menu.
The layout for our menu will be written in an XML file and stored inside a dedicated menu directory. To create this menu directory, right-click on the res folder (found by clicking Project > app) and select New > Android Resource Directory
Set both the directory name and resource type to 'menu' then press OK.
With the directory now in place, we can create the menu layout file. Right-click on the menu directory then select New > Menu resource file
Set the file name to 'menu_main' then press OK.
We can now write the content of the menu in the newly created menu_main.xml file.
Open the menu_main.xml file in Code view and replace the code that is there with the following:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/menu_settings"
android:title="@string/menu_settings"
app:showAsAction="never" />
</menu>
The above code adds an item (as indicated by the <item> tag) to our menu. The item will have the text which is encoded in the 'menu_settings' string. Currently, this string does not exist (hence why it is likely coloured in red). Let's fix that by opening up the strings resource file. You can find this file by clicking Project > app > res > values
Add the following string to the file:
<string name="menu_settings">Settings</string>
The last part of our menu item code was app:showAsAction="never". The showAsAction attribute determines how the menu item should be displayed. It will accept the following values:
We must now 'inflate' the menu to get it to load when the app is run. To do this, open the MainActivity.kt file by clicking Project > app > java > folder with your project name
Copy and paste the following code below the override fun onCreate function.
override fun onCreateOptionsMenu(menu: Menu): Boolean {
val inflater = menuInflater
inflater.inflate(R.menu.menu_main, menu)
return super.onCreateOptionsMenu(menu)
}
Note you may also need to add the following import statement to the MainActivity.kt file:
import android.view.Menu
The onCreateOptionsMenu function uses the menuInflater class to import the contents of the menu_main.xml file into the action bar. This code is sufficient to add the menu to our app. We will spend the rest of this tutorial learning how to make the menu functional and exploring other ways to format the menu.
If you want to create a submenu then simply add another menu element inside the item that will open the submenu. For example, you could add two submenu items to the menu like this:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/menu_settings"
android:title="@string/menu_settings"
app:showAsAction="never">
<!-- The submenu starts here -->
<menu>
<item android:id="@+id/submenu_item1"
android:title="@string/submenu_item1" />
<item android:id="@+id/submenu_item2"
android:title="@string/submenu_item2" />
</menu>
</item>
</menu>
You will also need to add strings to your strings.xml file for each of your submenu item's titles.
<string name="submenu_item1">Item 1</string>
<string name="submenu_item2">Item 2</string>
In addition to creating a submenu, you can also group menu items together so they can be worked on collectively.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/menu_settings"
android:title="@string/menu_settings"
app:showAsAction="never">
<!-- Grouped items go here -->
<group android:id="@+id/group_items1">
<item android:id="@+id/group_item1"
android:title="@string/group_item1"
app:showAsAction="ifRoom" />
<item android:id="@+id/group_item2"
android:title="@string/group_item2"
app:showAsAction="ifRoom" />
</group>
</item>
</menu>
Any items in the same group that share a showAsAction attribute of 'ifRoom' will either all be displayed in the action bar together or not at all. You won't get one item showing without the other.
Another useful reason to group menu items is that you can apply methods to all them with a single command. For example, you can use:
You can apply these methods in your Kotlin code so they are initiated when a function is called. For example, you could run the methods when the menu is loaded:
override fun onCreateOptionsMenu(menu: Menu): Boolean {
val inflater = menuInflater
inflater.inflate(R.menu.menu_main, menu)
// Set whether the group items are visible or not using 'true' and 'false'
menu.setGroupVisible(R.id.group_items1, true)
// Determine whether the group items can be pressed or not (true or false)
menu.setGroupEnabled(R.id.group_items1, true)
// Render group items checkable (true or false) and determine whether only one item or all items can be checked at once (exclusive: true or false)
menu.setGroupCheckable(R.id.group_items1, true, false)
return super.onCreateOptionsMenu(menu)
}
There are times when you may wish to change the layout of the menu based on user action. For example, maybe you want a 'Download' button to appear when the user presses a button. To make a menu item appear or disappear, open your main Kotlin file and declare the following variables:
private var downloadItem: Int = 1
private var showDownloadItem: Boolean = false
Together these variables will help us create a menu item that is hidden by default because the boolean value is set to false.
Now add the following line to the onCreateOptionsMenu function so the Download item can be added to the menu:
menu.add(0, downloadItem, 0, R.string.download_item)
Note you may need to add the 'download_item' string to your strings.xml file:
<string name="download_item">Download</string>
Add to your Kotlin file an onPrepareOptionsMenu function to allow the menu to be modified while the app is running. The function below will make our Download button visible.
override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
var menuItem: MenuItem = menu!!.findItem(downloadItem)
menuItem.isVisible = showDownloadItem
menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
return super.onPrepareOptionsMenu(menu)
}
Note you may need to import the MenuItem class.
import android.view.MenuItem
We just need to add one more function to our Kotlin file. This 'showDownload' function will make the Download menu item visible or invisible when a button we will add shortly is clicked.
fun showDownload(v: View) {
showDownloadItem=!showDownloadItem
invalidateOptionsMenu()
}
The last thing to do is add a button to your layout file (e.g. activity_main.xml). Set the 'onClick' attribute of the button to 'showDownload' so the Download item is hidden/revealed when the button is pressed.
Your app should now work like this:
Pop-up menus are not restricted to the action bar and can be loaded in the main body of the app. For example, you might want to create a reply button that gives the user a list of options for responding to an email.
First and foremost, add the following strings to your strings.xml file:
<string name="menu_reply">Reply</string>
<string name="menu_reply_all">Reply All</string>
<string name="menu_forward">Forward</string>
Next, create a layout file for the pop-up menu. This can be done by clicking Project > app > res, right-clicking on the menu folder and selecting New > Menu resource file.
Name the file 'popup' then press OK. Copy and paste the following code into the newly created popup.xml file to give the menu three items (reply, reply all and forward).
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_reply"
android:title="@string/menu_reply" />
<item android:id="@+id/menu_reply_all"
android:title="@string/menu_reply_all" />
<item android:id="@+id/menu_forward"
android:title="@string/menu_forward" />
</menu>
Next, we need to add the icon which will load the pop-up menu when pressed. For this example, we will use an ImageButton as the icon, so drag and drop it from the Palette onto your layout of choice (e.g. activity_main.xml). In the Resources window select the 'ic_menu_revert' icon then press OK.
Set the id of the ImageButton to 'replyButton' so you can refer to the button in your Kotlin code.
We'll now write the code which will allow the ImageButton to load the pop-up menu when pressed. Open your main Kotlin file (e.g. MainActivity.kt) and add the following code to the onCreate(savedInstanceState: Bundle?) function:
val clickListener = View.OnClickListener { view ->
when (view.id) {
R.id.replyButton -> {
showPopup(view)
}
}
}
replyButton.setOnClickListener(clickListener)
The above code calls the showPopup function each time the ImageButton is clicked. We have not written this function yet and so it may be coloured in red. Note you may also need to import the layout which holds the ImageButton. If the ImageButton is located in the activity_main.xml file then the import statement will look like this:
import kotlinx.android.synthetic.main.activity_main.*
All we need to do now to get the ImageButton working is write the showPopup function. This function will inflate the popup.xml menu layout whenever the user presses the ImageButton:
private fun showPopup(view: View) {
val popup = PopupMenu(this, view)
popup.inflate(R.menu.popup)
popup.show()
}
Note you may need to import the PopupMenu class.
import androidx.appcompat.widget.PopupMenu
And that's it! You have now created a pop-up menu!
x10hosting offers free and fast web hosting as well as other extras for your website such as custom email address and SQL databases. Creating a free or premium account using this link will help support this site.