ModalNavigationDrawer

Functions summary

Unit
@Composable
ModalNavigationDrawer(
    drawerContent: @Composable NavigationDrawerScope.(DrawerValue) -> Unit,
    modifier: Modifier,
    drawerState: DrawerState,
    scrimBrush: Brush,
    content: @Composable () -> Unit
)

Navigation drawers provide ergonomic access to destinations in an app.

Functions

ModalNavigationDrawer

@Composable
fun ModalNavigationDrawer(
    drawerContent: @Composable NavigationDrawerScope.(DrawerValue) -> Unit,
    modifier: Modifier = Modifier,
    drawerState: DrawerState = rememberDrawerState(DrawerValue.Closed),
    scrimBrush: Brush = SolidColor(LocalColorScheme.current.scrim.copy(alpha = 0.5f)),
    content: @Composable () -> Unit
): Unit

Navigation drawers provide ergonomic access to destinations in an app. Modal navigation drawers are good for infrequent, but more focused, switching to different destinations.

It displays content associated with the closed state when the drawer is not in focus and displays content associated with the open state when the drawer or its contents are focused on. Modal navigation drawers are elevated above most of the app’s UI and don’t affect the screen’s layout grid.

Example:

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.selection.selectableGroup
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material3.Button
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.tv.material3.Icon
import androidx.tv.material3.ModalNavigationDrawer
import androidx.tv.material3.NavigationDrawer
import androidx.tv.material3.NavigationDrawerItem
import androidx.tv.material3.Text

var selectedIndex by remember { mutableIntStateOf(0) }

val items =
    listOf(
        "Home" to Icons.Default.Home,
        "Settings" to Icons.Default.Settings,
        "Favourites" to Icons.Default.Favorite,
    )

val closeDrawerWidth = 80.dp
val backgroundContentPadding = 10.dp
ModalNavigationDrawer(
    drawerContent = {
        Column(
            Modifier.background(Color.Gray).fillMaxHeight().padding(12.dp).selectableGroup(),
            horizontalAlignment = Alignment.Start,
            verticalArrangement = Arrangement.spacedBy(10.dp),
        ) {
            items.forEachIndexed { index, item ->
                val (text, icon) = item

                NavigationDrawerItem(
                    selected = selectedIndex == index,
                    onClick = { selectedIndex = index },
                    leadingContent = { Icon(imageVector = icon, contentDescription = null) },
                ) {
                    Text(text)
                }
            }
        }
    }
) {
    Button(
        modifier =
            Modifier.padding(closeDrawerWidth + backgroundContentPadding)
                .height(100.dp)
                .fillMaxWidth(),
        onClick = {},
    ) {
        Text("BUTTON")
    }
}
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.selection.selectableGroup
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material3.Button
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.tv.material3.Icon
import androidx.tv.material3.ModalNavigationDrawer
import androidx.tv.material3.NavigationDrawer
import androidx.tv.material3.NavigationDrawerItem
import androidx.tv.material3.Text

var selectedIndex by remember { mutableIntStateOf(0) }

val items =
    listOf(
        "Home" to Icons.Default.Home,
        "Settings" to Icons.Default.Settings,
        "Favourites" to Icons.Default.Favorite,
    )

val closeDrawerWidth = 80.dp
val backgroundContentPadding = 10.dp

ModalNavigationDrawer(
    drawerContent = {
        Column(
            Modifier.background(Color.Gray).fillMaxHeight().padding(12.dp).selectableGroup(),
            horizontalAlignment = Alignment.Start,
            verticalArrangement = Arrangement.spacedBy(10.dp),
        ) {
            items.forEachIndexed { index, item ->
                val (text, icon) = item

                NavigationDrawerItem(
                    selected = selectedIndex == index,
                    onClick = { selectedIndex = index },
                    leadingContent = { Icon(imageVector = icon, contentDescription = null) },
                ) {
                    Text(text)
                }
            }
        }
    },
    scrimBrush = Brush.horizontalGradient(listOf(Color.DarkGray, Color.Transparent)),
) {
    Button(
        modifier =
            Modifier.padding(closeDrawerWidth + backgroundContentPadding)
                .height(100.dp)
                .fillMaxWidth(),
        onClick = {},
    ) {
        Text("BUTTON")
    }
}
Parameters
drawerContent: @Composable NavigationDrawerScope.(DrawerValue) -> Unit

Content that needs to be displayed on the drawer based on whether the drawer is DrawerValue.Open or DrawerValue.Closed. Drawer-entries can be animated when the drawer moves from Closed to Open state and vice-versa. For, e.g., the entry could show only an icon in the Closed state and slide in text to form (icon + text) when in the Open state.

To limit the width of the drawer in the open or closed state, wrap the content in a box with the required width.

modifier: Modifier = Modifier

the Modifier to be applied to this drawer

drawerState: DrawerState = rememberDrawerState(DrawerValue.Closed)

state of the drawer

scrimBrush: Brush = SolidColor(LocalColorScheme.current.scrim.copy(alpha = 0.5f))

brush to paint the scrim that obscures content when the drawer is open

content: @Composable () -> Unit

content of the rest of the UI. The content extends to the edge of the container under the modal navigation drawer. Focusable content that is not part of the background must have start-padding sufficient to prevent it from being drawn under the drawer in the Closed state.