How to create a gradient Dropdown Menu in Jetpack Compose for Kotlin Multiplatform

How to Create a Gradient Dropdown Menu in Jetpack Compose for Kotlin Multiplatform

Create a visually appealing Gradient Dropdown Menu in Jetpack Compose, compatible with Kotlin Multiplatform (KMP), to provide user options like profile, notifications, or settings across platforms.

Explore Dropdown Menu Features

Learn to implement a customizable Dropdown Menu with a gradient background, icons for each option, and smooth interactions, designed for KMP projects.


Key features of the Gradient Dropdown Menu include:
  • Gradient Background: Uses an orange-to-purple linear gradient for visual appeal.
  • Icons per Option: Custom icons for each menu item like profile or settings.
  • Customizable: Configurable options, icons, and default text.
  • KMP Compatible: Works across Android, iOS, and other platforms with Jetpack Compose.

Step-by-Step Implementation

Follow these steps to create a Gradient Dropdown Menu in your KMP project:

  1. Define the Composable: Create the GradientDropdownMenu composable with parameters for options, icons, and default text.
  2. Manage State: Use remembered states for expansion and selected option.
  3. Build Main Layout: Use a Column for the button and dropdown positioning.
  4. Add Trigger Button: Include a button to toggle the dropdown visibility.
  5. Create Popup: Use Popup for the dropdown surface with dismiss on outside click.
  6. Style Dropdown Content: Apply gradient and list options with icons in a Column.
  7. Create a Demo: Build a demo composable to showcase the dropdown with sample options.

Step 1: Define the GradientDropdownMenu Composable

Start by defining the composable with customizable parameters for options, icons, default text, and a modifier.


@Composable
fun GradientDropdownMenu(
    options: List<String> = listOf("Profile", "Notifications", "Settings"), // Menu options
    icons: List<androidx.compose.ui.graphics.vector.ImageVector> = listOf(
        Icons.Filled.Person, // Profile icon
        Icons.Filled.Notifications, // Notifications icon
        Icons.Filled.Settings // Settings icon
    ),
    defaultText: String = "Select an option", // Default display
    modifier: Modifier = Modifier
) {
    // Step 2 and beyond here
}
  

Step 2: Manage State

Use remembered states to track dropdown visibility and the selected option.


var expanded by remember { mutableStateOf(false) } // Tracks dropdown visibility
var selectedOption by remember { mutableStateOf(defaultText) } // Tracks selected text
  

Step 3: Build Main Layout

Use a Column for centering and padding the dropdown components.


Column(
    modifier = modifier
        .fillMaxWidth()
        .padding(DropdownConstants.PADDING), // Outer padding
    horizontalAlignment = Alignment.CenterHorizontally
) {
    // Button and Popup here
}
  

Step 4: Add Trigger Button

Include a row with a decorative icon and button to open the dropdown.


Row(
    verticalAlignment = Alignment.CenterVertically,
    modifier = Modifier.padding(bottom = DropdownConstants.CONTENT_SPACING)
) {
    Text(
        text = "✔", // Decorative checkmark
        fontSize = DropdownConstants.ICON_FONT_SIZE,
        modifier = Modifier.padding(end = DropdownConstants.ICON_SPACING)
    )
    Button(
        onClick = { expanded = true }, // Trigger dropdown
        modifier = Modifier.height(DropdownConstants.BUTTON_HEIGHT)
    ) {
        Text(
            text = selectedOption,
            fontSize = DropdownConstants.TEXT_FONT_SIZE,
            textAlign = TextAlign.Center // Center align text
        )
    }
}
  

Step 5: Create Popup

Use Popup to display the dropdown when expanded, with dismiss on outside click.


if (expanded) {
    Popup(
        onDismissRequest = { expanded = false }, // Close on outside click
        properties = PopupProperties(focusable = true),
        alignment = Alignment.TopCenter
    ) {
        // Dropdown content here
    }
}
  

Step 6: Style Dropdown Content

Apply gradient background and list options with icons in a clickable Column.


Column(
    modifier = Modifier
        .widthIn(max = DropdownConstants.MAX_WIDTH)
        .clip(RoundedCornerShape(DropdownConstants.CORNER_RADIUS)) // Rounded corners
        .background(
            Brush.linearGradient(
                colors = listOf(
                    Color(0xFFFF6D00), // Orange
                    Color(0xFFD81B60), // Pink
                    Color(0xFF8E24AA)  // Purple
                )
            )
        )
        .padding(DropdownConstants.INNER_PADDING) // Inner padding
) {
    options.forEachIndexed { index, option ->
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .clickable {
                    selectedOption = option // Set selection
                    expanded = false // Close after click
                }
                .padding(DropdownConstants.ITEM_PADDING),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Icon(
                imageVector = icons.getOrElse(index) { Icons.Filled.Check }, // Fallback icon
                contentDescription = "$option Icon",
                tint = Color.White,
                modifier = Modifier.size(DropdownConstants.ICON_SIZE)
            )
            Text(
                text = option,
                color = Color.White,
                fontSize = DropdownConstants.TEXT_FONT_SIZE,
                modifier = Modifier.padding(start = DropdownConstants.ICON_SPACING)
            )
        }
    }
}
  

Step 7: Define Styling Constants and Demo

Create constants for consistent styling and a demo composable to showcase the dropdown.


private object DropdownConstants {
    val PADDING = 16.dp // Outer padding
    val INNER_PADDING = 8.dp // Inner dropdown padding
    val ITEM_PADDING = 16.dp // Space around each item
    val CONTENT_SPACING = 8.dp // Space between button and dropdown
    val ICON_SPACING = 8.dp // Icon to text spacing
    val CORNER_RADIUS = 8.dp // Rounded dropdown corners
    val MAX_WIDTH = 200.dp // Dropdown max width
    val BUTTON_HEIGHT = 40.dp // Height of selection button
    val ICON_SIZE = 24.dp // Icon size
    val TEXT_FONT_SIZE = 14.sp // Text size
    val ICON_FONT_SIZE = 18.sp // Emoji/Icon font size
}

@Composable
fun GradientDropdownMenuDemo() {
    Box(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp), // Demo screen padding
        contentAlignment = Alignment.Center
    ) {
        GradientDropdownMenu(
            options = listOf("Profile", "Notifications", "Settings"), // Demo options
            icons = listOf(
                Icons.Filled.Person, // 
                Icons.Filled.Notifications, // 
                Icons.Filled.Settings // 
            )
        )
    }
}
  

Full Source Code

Use the Gradient Dropdown Menu to provide selectable options with a modern, gradient design in KMP projects.

Examples:

  • Access user profile in a cross-platform app
  • View notifications on Android or iOS
  • Adjust settings across platforms

Post a Comment

Previous Post Next Post