Creating a high-quality user interface is impossible without a well-thought-out navigation system. In the ecosystem Android the standard solution for this is to use a menu, which can be located either at the top of the screen (Action Bar or Toolbar) or on the side (Navigation Drawer). Beginners often find it difficult to bind XML markup to Java or Kotlin code, resulting in blank screens or compilation errors. Understanding menu architecture is critical for any mobile application developer.

In this article we will look in detail at the process of integrating menus into a project, from creating resources to processing clicks. We will look at working with MenuInflater, setting attributes in res/menu and features of displaying elements depending on the version of the operating system. You will learn how to make your application intuitive and compliant with guidelines Material Design.

A properly implemented menu significantly improves the usability of the product, allowing the user to quickly switch between sections. Modern approaches in Android Studio allow you to flexibly customize the appearance of items, add icons and group elements. Let's move from theory to practice and create functional navigation from scratch.

Preparing the project and creating menu resources

The first step before adding any interface element is preparing the project structure. In Android Studio, all resources responsible for the menu are stored in a special directory res/menu. If such a folder does not exist in your project yet, you must create it manually by right-clicking on the folder res and selecting New โ†’ Android Resource Directory. In the Resource type field, select the value menu.

After creating a directory, you need to add a new menu resource file inside it. It is usually called main_menu.xml or simply menu_main.xml. This file will contain an XML description of all the items that the user will see on the screen. The file structure is based on a tag <menu>, within which elements <item>are located. Each item can have its own unique identifier, title and icon.

To display icons correctly, it is recommended to use vector graphics VectorDrawableas they scale without loss of quality on screens with different pixel densities. You can add a vector asset through the folder context menu drawableby selecting the option New โ†’ Vector Asset. This will ensure image clarity on any device, from low-cost smartphones to high-resolution tablets.

โš ๏ธ Attention: Make sure that resource file names (xml, drawable) contain only lowercase Latin letters, numbers and underscores. Using capital letters or spaces will result in a project compilation error.

An example of a basic menu file structure is as follows:

<menu xmlns:android="http://schemas.android.com/apk/res/android">

<item

android:id="@+id/action_settings"

android:title="Settings"

android:icon="@drawable/ic_settings"

android:showAsAction="ifRoom" />

</menu>

Toolbar integration in the activity layout

Modern applications rarely use the standard one Action Barprovided by the system by default, preferring the flexible component Toolbar. This widget allows you to place a menu not only at the top, but also anywhere on the screen, as well as completely customize its appearance. First, you need to add the library dependency AppCompat to the file build.gradleif it is not already included.

Next, open your activity layout file, usually activity_main.xml. You need to add a widget to the root layout (for example ConstraintLayout or LinearLayout). It's important to give it an ID so we can access it from code, and set a height that meets design standards, usually this androidx.appcompat.widget.Toolbar. It's important to give it an ID so we can access it from code, and set the height to match design standards, usually this ?attr/actionBarSize.

After placing the Toolbar in XML, you need to "bind" it to an activity in code. In the method onCreate find the widget by ID using findViewById and call the method setSupportActionBarpassing the found object there. This action will inform the system that this Toolbar will act as the main panel of the application and it is on it that the menu we created will be displayed.

โ˜‘๏ธ Preparing the Toolbar

Done: 0 / 4

Don't forget to also change the application theme in the file styles.xml or themes.xml. Make sure that the theme you use inherits from Theme.AppCompat.NoActionBar or similar to hide the standard system header and avoid duplicating navigation bars. If you don't do this, you will see two headings under each other, which looks unaesthetic.

Inflating the menu and handling clicks

After the menu resource is created and the Toolbar is configured, you need to implement the logic for its display. In Android this process is called menu inflation. To do this, you need to override the onCreateOptionsMenumethod in the activity class. Inside this method there is an object MenuInflaterthat converts the XML file into real menu objects.

The code for inflation is succinct: you call the method inflater.inflatepassing there the resource of your menu (R.menu.main_menu) and the object menuthat the system passes to method. It is necessary to return from the method trueto show the menu to the user. If you return false, the menu will not be displayed.

To respond to user actions, you need to override one more method - onOptionsItemSelected. This is where clicks on menu items are processed. The system passes an object to this method MenuItem, by whose ID (item.getItemId) you determine which element was selected. Then you can launch new activities, open dialogs, or perform other actions.

๐Ÿ’ก

Use the switch-case (in Java) or when (in Kotlin) construct to process multiple menu items, this makes the code cleaner and more readable than multiple if-conditions.

Consider an example of processing a click on a settings item:

override fun onOptionsItemSelected(item: MenuItem): Boolean {

return when (item.itemId) {

R.id.action_settings -> {

// Logic for opening settings

true

}

else -> super.onOptionsItemSelected(item)

}

}

It is important to understand the difference between the parameter showAsAction in XML. The attribute ifRoom tells the system to show the icon in the panel if there is space, otherwise it will go to the drop-down menu (three dots). The value always forces the display of an icon, but must be used with caution so as not to overload the interface.

Creating a side menu Navigation Drawer

A side drawer menu, known as Navigation Drawer, is a popular navigation pattern for applications with a large number of sections. To implement it in modern Android, a component NavigationViewis used, which is usually placed inside a container DrawerLayout. This structure allows the menu to overlap the main content when opened.

In the layout file activity_main.xml the root should be androidx.drawerlayout.widget.DrawerLayout. Inside it there are two main elements: the first is the main content of the application (for example, a frame or a coordinate grid), and the second is itself NavigationView. For NavigationView you must specify the attribute app:menu, which refers to the menu XML file that we created earlier, but adapted for the sidebar.

To control the opening and closing of the menu, the class ActionBarDrawerToggleis programmatically used. It adds the famous "hamburger" icon (three stripes) to the left corner of the Toolbar and associates it with the DrawerLayout. When you click on this icon, the menu slides out smoothly. It is also necessary to synchronize the state of the indicator in the method onPostCreate and process screen rotation.

Features of working with fragments

When using the Navigation Drawer, there is often a need to replace the contents of the screen when an item is selected. To do this, use FragmentManager and fragment replacement transactions inside the onNavigationItemSelected handler.

Processing the selection of an element in the side menu occurs through the interface NavigationView.OnNavigationItemSelectedListener. You assign this listener to your NavigationView activity code. The callback method returns a Boolean value: true, if the event is processed and the menu should be closed, and false, if you want to leave the menu open.

Grouping elements and checkboxes

Often, a menu needs to implement mutually exclusive selection logic, for example, when switching themes or sorting the list. In an XML menu this is achieved using the tag <group>. Elements placed inside a group with an attribute android:checkableBehavior="single"behave like radio buttons: selecting one item automatically deselects the others.

If you need to allow the user to select several options at the same time (for example, filters), use the value all for the attribute checkableBehavior. In this case, the items will be displayed with checkboxes. To manually control the selection state from code, you can use the method setChecked(true) on a specific object MenuItem.

Grouping is also useful for visually dividing menus into logical blocks without using dividing lines. You can set different IDs for groups to control their visibility or accessibility programmatically. For example, hide the entire group of settings for unregistered users.

Group attribute Value Result
single One of many Radio buttons, select one item
all Multiple Checkboxes, selection of several items
none Absent Regular items without marks

When programmatically changing the state of items, do not forget to call the method invalidateOptionsMenuif the visual update does not occur automatically. This will force the system to redraw the menu and apply the new checkbox states.

Extended menus and submenus

For complex applications with a deep hierarchy of settings, it may be necessary to create submenus. In Android, this is implemented by nesting a tag <menu> inside a tag <item>. A parent menu item containing a submenu is usually displayed with an arrow indicating the presence of nested elements.

The structure of a submenu allows you to organize the space more compactly, without cluttering the main screen with dozens of buttons. However, you should not abuse the depth of nesting: no more than two levels are considered optimal. It should be convenient for the user to get to the desired function in a minimum number of taps.

In the side menu (NavigationView), submenus are often implemented through group headers or special drop-down list widgets, since the standard submenu may not be displayed correctly depending on the version of the design library. In such cases, it is recommended to use separate settings screens or dialog boxes for minor options.

๐Ÿ“Š Which menu type do you use most often?
Toolbar (top)
Navigation Drawer (side)
Bottom Navigation (lower)
Combined

When working with submenus, event processing becomes a little more complicated, since you need to track clicks on elements of different levels. The logic remains the same - ID verification, but the XML structure becomes more voluminous. Always check the display on small screen emulators to make sure that the text in the submenu is not cut off.

Frequent errors and performance optimization

One โ€‹โ€‹of the common problems is memory leaks or unnecessary interface redraws. If you call invalidateOptionsMenu inside loops or animations unnecessarily, this can lead to a drop in FPS and increased battery consumption. Call this method only when the composition of the menu or the state of the items has actually changed.

Another mistake is using heavy raster images instead of vectors for menu icons. This increases the APK size and may cause blurring on high pixel density screens. Always use VectorDrawable or compressed PNGs of the required size for different screen densities (mdpi, xhdpi etc.).

โš ๏ธ Attention: Android support interfaces and libraries are updated frequently. Methods described in older tutorials (such as using legacy ActionBar classes) may not work in newer versions of Android Studio. Always check the official documentation.

It is also worth remembering about accessibility. Make sure that all menu items have a android:title or android:contentDescriptionattribute, even if only an icon is displayed on the screen. This is necessary for the operation of screen readers used by people with visual impairments.

๐Ÿ’ก

Using vector graphics and proper grouping of menu elements is the key to creating a lightweight and user-friendly application that runs quickly on any device.

Optimizing menu code also includes eliminating complex calculations within methods. onCreateOptionsMenu i onPrepareOptionsMenu. These methods can be called frequently, so the logic inside them should be as simple and fast as possible. If you need to download data from the network to display items, do it asynchronously.

How to hide a specific menu item programmatically?

To hide a menu item, find it by ID using the method menu.findItem(R.id.your_item_id) and call the method setVisible(false). To show it again, use setVisible(true). The changes will take effect immediately or after the call invalidateOptionsMenu.

Is it possible to change the menu icon while the application is running?

Yes, this is possible. Get a link to the menu item via findItem and call the method setIcon(R.drawable.new_icon). This is often used to toggle a state, such as the like icon or sync status.

Why doesn't the menu appear on the Toolbar?

Check three things: whether the method is called, whether the method is overridden setSupportActionBarwhether the method is overridden onCreateOptionsMenu and whether it returns data-i="181">, and whether the correct resource file is specified in the inflator method. Also make sure that the application theme does not hide the Action Bar. true, and whether the correct resource file is specified in the inflator method. Also make sure that the application theme does not hide the Action Bar.

How to add a dividing line to the menu?

The standard Android menu does not have a direct tag for the line, but you can simulate it by adding a menu item with an empty title and height, or using groups with different IDs, which are displayed indented in themes. In Navigation Drawer, you can use tag <group android:checkableBehavior="none"> to separate.

What is the difference between Menu and PopupMenu?

The main menu (Options Menu) is attached to the activity and is displayed in the Toolbar or Drawer. PopupMenu is a temporary menu, which appears next to a specific View when you click on it, is often used for contextual actions with a specific list item.