Friday, March 5, 2021

jetpack compose - How to use DropdownMenu

Compose DropdownMenu
The DropdownMenu is a list widget of the android jetpack compose library. The drop-down menu displays a list of options on a temporary surface. Android application users can see the drop-down menu items by interacting with a Button, IconButton, action, or other control.

This android application development tutorial will demonstrate to us how we can display a DropdownMenu widget on our app screen and can populate it with items in a jetpack compose android application.

DropdownMenu acts like a Popup. Typically a DropdownMenu placed inside a Box layout. The DropdownMneu content is commonly DropdownMenuItems as well as custom content. DropdownMenuItem creates a menu item that matches the google material design guidelines. Android app developers also can display an icon on a DropdownMenuItem. DropdownMenu items display inside a scrollable Column layout.

When users tap outside the DropdownMenu, its calls the dismiss request function and close the items panel. It also closes on the back key press. DropdownMenu trying to be fully visible in its items and positioning itself depending on available space.

DropdownMenu’s ‘expanded’ parameter allows us to expand or collapse a DropdownMenu. In its expanded state DropdownMenu displays its items and in the collapsed mode it hides the menu items. So, in a variable, we remember the DropdownMenu expanded state and assign it to DropdownMenu ‘expanded’ argument. We change this variable value on DropdownMenu’s on dismiss event.

In this example code snippet, we also close the DropdownMenu by the first item click event. In this android example code, we display a DropDdownMenu by using an IconButton click event. We also show a toast message to the user for each menu item click.

We put Divider widget between DropdownMenu items to separate menu items by dividers. DropdownMenu is very similar to a Spinner widget of native android SDK. Copy the below kotlin file into your android studio main activity file and run it on an emulator to test the DropdownMenu.
MainActivity.kt

package com.cfsuman.jetpackcompose

import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            MainContent()
        }
    }


    @Composable
    fun MainContent(){
        val context = this;
        val expanded = remember { mutableStateOf(false)}
        
        Box(
            Modifier
                .fillMaxSize()
                .wrapContentSize(Alignment.TopEnd)
        ) {
            IconButton(onClick = { expanded.value = true }) {
                Icon(
                    Icons.Filled.MoreVert,
                    contentDescription = "Localized description"
                )
            }

            DropdownMenu(
                expanded = expanded.value,
                onDismissRequest = { expanded.value = false },
            ) {
                DropdownMenuItem(onClick = {
                    context.toast("First")
                    expanded.value = false
                }) {
                    Text("First Item")
                }

                DropdownMenuItem(onClick = {
                    context.toast("Second")
                }) {
                    Text("Second item")
                }

                Divider()

                DropdownMenuItem(onClick = {
                    context.toast("Third")
                }) {
                    Text("Third item")
                }

                Divider()

                DropdownMenuItem(onClick = {
                    context.toast("Fourth")
                }) {
                    Text("Fourth item")
                }
            }
        }
    }


    @Preview
    @Composable
    fun ComposablePreview(){
        //MainContent()
    }
}


// extension function to show toast message
fun Context.toast(message:String = ""){
    Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}