Popular Searches
Popular Course Categories
Popular Courses

Creating Menus, Dropdowns, and Selection Controls

Creating Menus, Dropdowns, and Selection Controls

User Interaction, Forms, and Navigation

Creating Menus, Dropdowns, and Selection Controls in Android Jetpack Compose

Course: Android App Development

Topic: Creating Menus, Dropdowns, and Selection Controls

Course Link: Android App Development Course

Demo Link: Register for a Course Demo

Website: JustAcademy


1. Introduction to Menus, Dropdowns, and Selection Controls

Menus, dropdowns, and selection controls are important UI components in Android application development. They allow users to choose options, access actions, filter information, and configure application settings without navigating through unnecessary screens.

Jetpack Compose provides declarative components for creating these interactive controls. Developers can combine Material Design components with observable state to build interfaces that respond immediately to user selections.

For example, a shopping application may use a dropdown to select a product category, a checkbox to select multiple filters, a radio button to choose a payment method, and a menu to provide actions such as Edit, Share, and Delete.

Learning Objectives

  • Understand menus, dropdowns, and selection controls.
  • Create popup menus using DropdownMenu.
  • Implement dropdown selection using DropdownMenuItem.
  • Use radio buttons for single-choice selections.
  • Use checkboxes for multiple-choice selections.
  • Use switches and segmented selection patterns for settings and filters.
  • Manage selected values using remember and mutableStateOf.
  • Build reusable selection components and handle user interactions.
  • Apply accessibility and UI design best practices.

2. Understanding Menus in Android

A menu is a UI component that displays a collection of actions or options. Menus are useful when an application needs to provide additional functionality without permanently displaying every available action on the screen.

Common Types of Menus

Menu Type Description Example
Popup Menu Displays actions near a button or another anchor. Edit, Share, Delete
Dropdown Menu Displays a list of options that can be selected. Select a country or category
Navigation Menu Provides access to application destinations. Home, Profile, Settings
Context Menu Provides actions related to a particular item. Copy or rename a document
Overflow Menu Contains additional actions that do not fit in the main toolbar. Help, Settings, About

In Jetpack Compose, DropdownMenu and DropdownMenuItem are commonly used to create popup and overflow-style menus. Navigation menus may use other components, depending on the application's navigation design.

3. Understanding DropdownMenu

DropdownMenu is a Material component that displays a popup containing menu items. It is often used when a user clicks a button or icon to reveal additional actions.

Important Parameters

Parameter Purpose
expanded Determines whether the menu is visible.
onDismissRequest Handles requests to dismiss the menu, such as tapping outside it.
DropdownMenuItem Represents an individual menu action or option.
text Defines the displayed label of a menu item.
onClick Executes an action when a menu item is activated.

The visibility of the menu is generally controlled using a Boolean state variable.

Basic Syntax

var expanded by remember {
    mutableStateOf(false)
}

Box {
    Button(
        onClick = {
            expanded = true
        }
    ) {
        Text("Open Menu")
    }

    DropdownMenu(
        expanded = expanded,
        onDismissRequest = {
            expanded = false
        }
    ) {
        DropdownMenuItem(
            text = {
                Text("Profile")
            },
            onClick = {
                expanded = false
            }
        )
    }
}

This example introduces a menu that opens when the button is clicked. The menu closes when the user selects the item or when a dismissal event occurs.

4. Creating a Complete Dropdown Menu

A dropdown menu can contain multiple actions. Each menu item can execute a different operation, such as opening a profile, navigating to settings, or displaying application information.

Complete Kotlin Example

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Button
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Text
import androidx.compose.runtime.*

@Composable
fun OptionsMenuExample() {
    var expanded by remember {
        mutableStateOf(false)
    }

    var selectedAction by remember {
        mutableStateOf("No action selected")
    }

    Column {
        Box {
            Button(
                onClick = {
                    expanded = true
                }
            ) {
                Text("More Options")
            }

            DropdownMenu(
                expanded = expanded,
                onDismissRequest = {
                    expanded = false
                }
            ) {
                DropdownMenuItem(
                    text = {
                        Text("Profile")
                    },
                    onClick = {
                        selectedAction = "Profile selected"
                        expanded = false
                    }
                )

                DropdownMenuItem(
                    text = {
                        Text("Settings")
                    },
                    onClick = {
                        selectedAction = "Settings selected"
                        expanded = false
                    }
                )

                DropdownMenuItem(
                    text = {
                        Text("Help")
                    },
                    onClick = {
                        selectedAction = "Help selected"
                        expanded = false
                    }
                )
            }
        }

        Text(text = selectedAction)
    }
}

Code Explanation

  1. The expanded state determines whether the menu is displayed.
  2. Clicking More Options sets expanded to true.
  3. The dropdown displays three menu items.
  4. Selecting an item updates selectedAction.
  5. The menu closes after the selection.
  6. The selected action appears beneath the menu button.

5. Understanding Dropdown Selection Controls

A dropdown selection control allows a user to choose one value from a list. Unlike an action menu, which primarily executes commands, a selection dropdown typically updates a value used by the application.

Examples include:

  • Selecting a country during registration.
  • Choosing a programming language in a learning application.
  • Selecting a product category in a shopping application.
  • Choosing a sort order for a list of results.
  • Selecting a city, language, or preferred theme.

A dropdown selection control typically stores the selected value in state and displays that value when the menu is closed.

```html

Example: Selecting a Course Category

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Button
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Text
import androidx.compose.runtime.*

@Composable
fun CourseCategoryDropdown() {
    val categories = listOf(
        "Android Development",
        "Web Development",
        "Data Analytics",
        "Digital Marketing"
    )

    var expanded by remember {
        mutableStateOf(false)
    }

    var selectedCategory by remember {
        mutableStateOf("Select a Category")
    }

    Column {
        Box {
            Button(
                onClick = {
                    expanded = true
                }
            ) {
                Text(selectedCategory)
            }

            DropdownMenu(
                expanded = expanded,
                onDismissRequest = {
                    expanded = false
                }
            ) {
                categories.forEach { category ->
                    DropdownMenuItem(
                        text = {
                            Text(category)
                        },
                        onClick = {
                            selectedCategory = category
                            expanded = false
                        }
                    )
                }
            }
        }

        Text("Selected Category: $selectedCategory")
    }
}

In this example, the list of categories is displayed when the button is clicked. Selecting a category updates the displayed value and closes the dropdown.

6. Creating an Exposed Dropdown Menu

An exposed dropdown menu combines a text field or field-like component with a dropdown list. It is useful when the selected option needs to remain visible in a form or when users need a more conventional selection control.

Material 3 provides ExposedDropdownMenuBox, ExposedDropdownMenu, and menuAnchor for this pattern.

Example: Country Selection

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExposedDropdownMenuBox
import androidx.compose.material3.ExposedDropdownMenu
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.*

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CountryDropdown() {
    val countries = listOf(
        "India",
        "United States",
        "Canada",
        "Australia",
        "United Kingdom"
    )

    var expanded by remember {
        mutableStateOf(false)
    }

    var selectedCountry by remember {
        mutableStateOf("")
    }

    ExposedDropdownMenuBox(
        expanded = expanded,
        onExpandedChange = {
            expanded = !expanded
        }
    ) {
        OutlinedTextField(
            value = selectedCountry,
            onValueChange = {},
            readOnly = true,
            label = {
                Text("Select Country")
            },
            trailingIcon = {
                ExposedDropdownMenuDefaults.TrailingIcon(
                    expanded = expanded
                )
            },
            modifier = androidx.compose.ui.Modifier
                .menuAnchor(
                    androidx.compose.material3
                        .MenuAnchorType.PrimaryNotEditable,
                    enabled = true
                )
        )

        ExposedDropdownMenu(
            expanded = expanded,
            onDismissRequest = {
                expanded = false
            }
        ) {
            countries.forEach { country ->
                DropdownMenuItem(
                    text = {
                        Text(country)
                    },
                    onClick = {
                        selectedCountry = country
                        expanded = false
                    }
                )
            }
        }
    }
}

Note: This example uses the current Material 3 menu-anchor API. Depending on the Material 3 library version, the exact menuAnchor overload may differ. Use the API supported by your project's dependency version.

How the Exposed Dropdown Works

  • ExposedDropdownMenuBox manages the relationship between the field and the popup.
  • expanded controls whether the options are visible.
  • OutlinedTextField displays the selected country.
  • menuAnchor connects the field to the dropdown interaction.
  • ExposedDropdownMenu displays the available choices.
  • Selecting a country updates the state and closes the menu.

7. Understanding Selection Controls

Selection controls allow users to choose values or change settings. The correct component depends on whether the user can choose one option, multiple options, or enable and disable a feature.

Control Selection Behavior Example
Radio Button Choose one option from a group. Payment method
Checkbox Choose zero, one, or multiple options. Interests or filters
Switch Turn a setting on or off. Enable notifications
Segmented Button Choose among a small set of related options. Day, Week, Month
Dropdown Selection Choose an option from a compact list. Country or category
Filter Chip Select or remove a filter. Popular, Recent, Featured

8. Implementing Radio Buttons

Radio buttons are used when a user must choose exactly one option from a group. Selecting one option generally deselects the previously selected option.

Common examples include selecting a payment method, choosing a delivery option, or selecting a preferred subscription plan.

Example: Payment Method Selection

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Text
import androidx.compose.runtime.*

@Composable
fun PaymentMethodSelection() {
    val methods = listOf(
        "UPI",
        "Credit Card",
        "Cash on Delivery"
    )

    var selectedMethod by remember {
        mutableStateOf("UPI")
    }

    Column {
        Text("Select Payment Method")

        methods.forEach { method ->
            Row {
                RadioButton(
                    selected = selectedMethod == method,
                    onClick = {
                        selectedMethod = method
                    }
                )

                Text(
                    text = method,
                    modifier = androidx.compose.ui.Modifier
                        .alignByBaseline()
                )
            }
        }

        Text("Selected: $selectedMethod")
    }
}

How Radio Buttons Work

  1. The list contains the available payment methods.
  2. The selected value starts as UPI.
  3. Each radio button compares its option with the selected value.
  4. Clicking an option updates selectedMethod.
  5. Compose updates the selected appearance of the radio buttons.

For production forms, consider grouping each radio button with its label in a single accessible interactive row, so users can easily select the option by tapping the text as well.

9. Implementing Checkboxes for Multiple Selections

A checkbox allows users to select or deselect an individual option. Unlike a radio button group, several checkboxes can be selected simultaneously.

Checkboxes are useful for selecting interests, product filters, course topics, or multiple notification categories.

Example: Selecting Interests

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.material3.Checkbox
import androidx.compose.material3.Text
import androidx.compose.runtime.*

@Composable
fun InterestSelection() {
    val interests = listOf(
        "Android",
        "Kotlin",
        "Java",
        "UI Design"
    )

    var selectedInterests by remember {
        mutableStateOf(setOf<String>())
    }

    Column {
        Text("Choose Your Interests")

        interests.forEach { interest ->
            Row {
                Checkbox(
                    checked = interest in selectedInterests,
                    onCheckedChange = { checked ->
                        selectedInterests =
                            if (checked) {
                                selectedInterests + interest
                            } else {
                                selectedInterests - interest
                            }
                    }
                )

                Text(interest)
            }
        }

        Text(
            "Selected: " +
                selectedInterests.joinToString()
        )
    }
}

The state is stored as a set of strings. Selecting a checkbox adds its value to the set, while deselecting it removes the value. Assigning a new set ensures that Compose observes the state update.

10. Implementing Switch Controls

A switch represents an on/off setting. It is useful when users need to enable or disable a feature directly.

Example: Dark Mode Preference

import androidx.compose.foundation.layout.Row
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.runtime.*

@Composable
fun DarkModeSetting() {
    var darkModeEnabled by remember {
        mutableStateOf(false)
    }

    Row {
        Text("Dark Mode")

        Switch(
            checked = darkModeEnabled,
            onCheckedChange = { enabled ->
                darkModeEnabled = enabled
            }
        )
    }

    Text(
        if (darkModeEnabled) {
            "Dark mode enabled"
        } else {
            "Dark mode disabled"
        }
    )
}

This example updates the switch state and a status message. To change the application's actual color theme, connect the state to the app's theme configuration. Persist the preference if it should be retained when the app restarts.

11. Using Segmented Buttons for Selection

Segmented buttons display a small number of related choices in a compact horizontal group. They are useful for switching between views, selecting display modes, or choosing a time range.

Example: Selecting a Time Range

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.SingleChoiceSegmentedButtonRow
import androidx.compose.material3.SegmentedButton
import androidx.compose.material3.SegmentedButtonDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.*

@Composable
fun TimeRangeSelection() {
    val options = listOf("Day", "Week", "Month")

    var selectedOption by remember {
        mutableStateOf("Week")
    }

    Column {
        SingleChoiceSegmentedButtonRow {
            options.forEachIndexed { index, option ->
                SegmentedButton(
                    selected = selectedOption == option,
                    onClick = {
                        selectedOption = option
                    },
                    shape = SegmentedButtonDefaults.itemShape(
                        index = index,
                        count = options.size
                    )
                ) {
                    Text(option)
                }
            }
        }

        Text("Selected Range: $selectedOption")
    }
}

This component provides a single-choice selection pattern. For multiple simultaneous selections, use a multiple-choice design that clearly communicates which options are active.

12. Using Filter Chips for Selection

Filter chips allow users to apply or remove filters. They are useful in search screens, product listings, galleries, and dashboards.

Example: Product Filters

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.FilterChip
import androidx.compose.material3.Text
import androidx.compose.runtime.*

@Composable
fun ProductFilters() {
    var popularSelected by remember {
        mutableStateOf(false)
    }

    var recentSelected by remember {
        mutableStateOf(false)
    }

    Column {
        FilterChip(
            selected = popularSelected,
            onClick = {
                popularSelected = !popularSelected
            },
            label = {
                Text("Popular")
            }
        )

        FilterChip(
            selected = recentSelected,
            onClick = {
                recentSelected = !recentSelected
            },
            label = {
                Text("Recently Added")
            }
        )

        Text(
            "Popular: $popularSelected, " +
                "Recent: $recentSelected"
        )
    }
}

Each chip maintains its own selection state, so both filters can be active at the same time. A real application should use these values to filter the underlying data.

13. Managing Selection State with remember and mutableStateOf

Menus and selection controls need state to remember the currently selected value and whether a popup is open. The combination of remember and mutableStateOf is commonly used for local UI state.

Example

var expanded by remember {
    mutableStateOf(false)
}

var selectedOption by remember {
    mutableStateOf("Option 1")
}

The first state controls the visibility of the menu. The second stores the currently selected option.

For a simple local selection, this pattern is usually sufficient. Use rememberSaveable if the selection needs to survive supported activity recreation events, and use a ViewModel or persistent storage when the data has a longer lifetime.

14. Difference Between Action Menus and Selection Dropdowns

Feature Action Menu Selection Dropdown
Primary purpose Execute commands or actions. Choose a value.
Example Edit, Share, Delete. India, Canada, Australia.
Stored state May store the last action or no selection. Usually stores the current selection.
After activation Performs an action and often closes. Updates the selected value and often closes.
Typical component DropdownMenu ExposedDropdownMenuBox or a suitable selection control

15. Creating a Complete Selection Form

The following example combines a course dropdown, a learning-mode radio group, and an additional checkbox. It demonstrates how multiple selection controls can work together in one screen.

Complete Kotlin Example

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.material3.Button
import androidx.compose.material3.Checkbox
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Text
import androidx.compose.runtime.*

@Composable
fun CoursePreferenceForm() {
    val courses = listOf(
        "Android Development",
        "Java Development",
        "Web Development"
    )

    var expanded by remember {
        mutableStateOf(false)
    }

    var selectedCourse by remember {
        mutableStateOf(courses[0])
    }

    var learningMode by remember {
        mutableStateOf("Online")
    }

    var wantsUpdates by remember {
        mutableStateOf(false)
    }

    Column {
        Text("Choose a Course")

        androidx.compose.foundation.layout.Box {
            Button(
                onClick = {
                    expanded = true
                }
            ) {
                Text(selectedCourse)
            }

            DropdownMenu(
                expanded = expanded,
                onDismissRequest = {
                    expanded = false
                }
            ) {
                courses.forEach { course ->
                    DropdownMenuItem(
                        text = {
                            Text(course)
                        },
                        onClick = {
                            selectedCourse = course
                            expanded = false
                        }
                    )
                }
            }
        }

        Text("Learning Mode")

        listOf("Online", "Classroom").forEach { mode ->
            Row {
                RadioButton(
                    selected = learningMode == mode,
                    onClick = {
                        learningMode = mode
                    }
                )

                Text(mode)
            }
        }

        Row {
            Checkbox(
                checked = wantsUpdates,
                onCheckedChange = {
                    wantsUpdates = it
                }
            )

            Text("Receive course updates")
        }

        Button(
            onClick = {
                // Process the selected preferences.
            }
        ) {
            Text("Submit Preferences")
        }

        Text("Course: $selectedCourse")
        Text("Mode: $learningMode")
        Text("Updates: $wantsUpdates")
    }
}

What This Project Demonstrates

  • Opening and dismissing a dropdown menu.
  • Saving a selected course value.
  • Choosing exactly one learning mode.
  • Enabling or disabling an additional preference.
  • Displaying the current selection values.
  • Combining multiple interactive controls in a form.

16. Accessibility and User Experience Best Practices

Selection controls should be understandable, easy to operate, and accessible to users with different interaction needs.

  • Use clear labels for all menus and selection controls.
  • Provide meaningful descriptions for icon-only menu triggers.
  • Use radio buttons when users must choose one option from a group.
  • Use checkboxes when multiple options may be selected.
  • Use switches for settings that can be enabled or disabled.
  • Show the current selected value clearly.
  • Close popup menus after a selection when appropriate.
  • Ensure popup menus can be dismissed using supported system interactions.
  • Do not rely only on color to indicate selection.
  • Provide adequate touch targets and spacing.
  • Use standard Material components when possible to benefit from built-in interaction and accessibility behavior.
  • Keep long lists manageable and consider search or filtering when necessary.
  • Validate selections before submitting a form.

17. Common Mistakes and Troubleshooting

Mistake 1: Forgetting to Close the Dropdown

If expanded remains true after a selection, the menu may stay open. Set expanded = false inside the item's click callback.

Mistake 2: Not Handling Menu Dismissal

Always update the expanded state in onDismissRequest so that the application responds correctly when the menu is dismissed.

Mistake 3: Using the Wrong Selection Control

Using radio buttons for independent multi-selection or checkboxes for an exclusive choice can confuse users. Choose a component based on the selection requirements.

Mistake 4: Updating a Non-Observable Variable

Changing an ordinary Kotlin variable does not automatically update the UI. Store UI-dependent values in observable state or another suitable observable state holder.

Mistake 5: Not Updating the Selected Value

Closing a menu without assigning the chosen value may leave the displayed selection unchanged. Update the state and then close the menu.

Mistake 6: Using Dropdowns for Too Many Important Options

If all options must remain visible or the choice is important, radio buttons, a dialog, or a dedicated selection screen may provide a better experience.

Mistake 7: Losing State After Recreation

remember retains state across recompositions, not all lifecycle events. Use rememberSaveable or a suitable longer-lived state holder when needed.

Mistake 8: Building Very Large Dropdowns Inefficiently

Compose dropdown menus are scrollable by default, but their items are not lazily created. For very large datasets, consider a searchable selection screen or another suitable component.

18. Practice Exercises

  1. Create a dropdown menu containing five programming languages.
  2. Build a country selection dropdown that displays the selected country.
  3. Create a radio group for selecting a payment method.
  4. Build a checkbox list for selecting multiple course topics.
  5. Create a settings screen with switches for notifications and dark mode.
  6. Implement a segmented button to switch between daily, weekly, and monthly reports.
  7. Create a popup menu containing Profile, Settings, Help, and Logout.
  8. Build a form that combines a dropdown, radio buttons, and checkboxes.
  9. Use rememberSaveable to retain a supported selected value through activity recreation.
  10. Improve a selection screen with appropriate labels and accessible touch targets.

19. Interview Questions and Answers

Q1. What is DropdownMenu in Jetpack Compose?

Answer: DropdownMenu displays a popup containing a list of actions or options. Its visibility is typically controlled by a Boolean state.

Q2. What is the purpose of DropdownMenuItem?

Answer: It represents an individual option or action inside a dropdown menu and provides an onClick callback.

Q3. What is the difference between a menu and a selection dropdown?

Answer: A menu generally presents actions to perform, whereas a selection dropdown usually allows the user to choose and retain a value.

Q4. When should radio buttons be used?

Answer: Use radio buttons when the user must select one option from a group of mutually exclusive choices.

Q5. When should checkboxes be used?

Answer: Use checkboxes when users can independently select or deselect multiple options.

Q6. What is an exposed dropdown menu?

Answer: It is a dropdown selection pattern associated with a text field or field-like component, commonly implemented using Material 3's exposed dropdown menu APIs.

Q7. How do you control dropdown visibility?

Answer: Maintain an observable Boolean state and pass it to the menu's expanded parameter.

Q8. What does onDismissRequest do?

Answer: It handles a request to dismiss the menu, such as a tap outside the popup or pressing the Back key.

Q9. Why is remember used in selection controls?

Answer: It retains the state object across recompositions so that the selected value or menu visibility does not reset on every recomposition.

Q10. How can multiple selections be stored?

Answer: Store selected items in an observable state structure, such as a set, and assign an updated collection whenever the selection changes.

Q11. What is the difference between a switch and a checkbox?

Answer: A switch commonly represents an on/off setting, while a checkbox commonly represents an independently selectable item in a list or form.

Q12. How can selected values survive activity recreation?

Answer: Use rememberSaveable for supported UI values or a suitable ViewModel and persistent storage when longer-term retention is required.

20. Quick Revision Checklist

  • Understand the difference between menus and selection controls.
  • Know how to use DropdownMenu and DropdownMenuItem.
  • Manage popup visibility with observable Boolean state.
  • Use an exposed dropdown for field-based selection.
  • Use radio buttons for single-choice selection.
  • Use checkboxes for multiple-choice selection.
  • Use switches for on/off settings.
  • Use segmented buttons for a small group of related choices.
  • Update the selected value when an option is chosen.
  • Apply accessibility, state-management, and UI design best practices.

21. Conclusion

Menus, dropdowns, and selection controls are essential components for creating interactive Android applications with Jetpack Compose. They allow users to access actions, choose options, configure settings, and filter information in a structured way.

By learning DropdownMenu, ExposedDropdownMenuBox, radio buttons, checkboxes, switches, and segmented buttons, developers can build flexible forms and user-friendly interfaces.

Combining these controls with remember and mutableStateOf helps keep the interface synchronized with user selections. For larger applications, appropriate state hoisting, ViewModels, validation, and accessibility practices make selection interfaces easier to maintain and use.


Additional Learning Resources

Previous Next
whatsapp