DEV Community

myougaTheAxo
myougaTheAxo

Posted on

Material3 Adaptive Complete Guide — ListDetailPaneScaffold/NavigationSuiteScaffold

What You'll Learn

Material3 Adaptive (ListDetailPaneScaffold, NavigationSuiteScaffold, SupportingPaneScaffold, responsive UI) explained.


Setup

dependencies {
    implementation("androidx.compose.material3.adaptive:adaptive:1.1.0")
    implementation("androidx.compose.material3.adaptive:adaptive-layout:1.1.0")
    implementation("androidx.compose.material3.adaptive:adaptive-navigation:1.1.0")
    implementation("androidx.compose.material3:material3-adaptive-navigation-suite:1.3.1")
}
Enter fullscreen mode Exit fullscreen mode

ListDetailPaneScaffold

@OptIn(ExperimentalMaterial3AdaptiveApi::class)
@Composable
fun ListDetailScreen(items: List<Item>) {
    val navigator = rememberListDetailPaneScaffoldNavigator<Item>()

    ListDetailPaneScaffold(
        directive = navigator.scaffoldDirective,
        value = navigator.scaffoldValue,
        listPane = {
            AnimatedPane {
                LazyColumn {
                    items(items, key = { it.id }) { item ->
                        ListItem(
                            headlineContent = { Text(item.title) },
                            supportingContent = { Text(item.description) },
                            modifier = Modifier.clickable {
                                navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, item)
                            }
                        )
                    }
                }
            }
        },
        detailPane = {
            AnimatedPane {
                navigator.currentDestination?.contentKey?.let { item ->
                    Column(Modifier.fillMaxSize().padding(16.dp)) {
                        Text(item.title, style = MaterialTheme.typography.headlineMedium)
                        Spacer(Modifier.height(8.dp))
                        Text(item.description)
                    }
                } ?: Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                    Text("Select an item")
                }
            }
        }
    )
}
Enter fullscreen mode Exit fullscreen mode

NavigationSuiteScaffold

@Composable
fun AdaptiveNavApp() {
    var selectedItem by remember { mutableIntStateOf(0) }
    val navItems = listOf(
        NavItem("Home", Icons.Default.Home),
        NavItem("Search", Icons.Default.Search),
        NavItem("Settings", Icons.Default.Settings)
    )

    NavigationSuiteScaffold(
        navigationSuiteItems = {
            navItems.forEachIndexed { index, item ->
                item(
                    icon = { Icon(item.icon, contentDescription = item.label) },
                    label = { Text(item.label) },
                    selected = selectedItem == index,
                    onClick = { selectedItem = index }
                )
            }
        }
    ) {
        when (selectedItem) {
            0 -> HomeContent()
            1 -> SearchContent()
            2 -> SettingsContent()
        }
    }
}

// NavigationSuiteScaffold auto-switches based on screen size:
// Compact → NavigationBar (bottom)
// Medium → NavigationRail (side)
// Expanded → NavigationDrawer (permanent)
Enter fullscreen mode Exit fullscreen mode

SupportingPaneScaffold

@OptIn(ExperimentalMaterial3AdaptiveApi::class)
@Composable
fun SupportingPaneScreen() {
    val navigator = rememberSupportingPaneScaffoldNavigator()

    SupportingPaneScaffold(
        directive = navigator.scaffoldDirective,
        value = navigator.scaffoldValue,
        mainPane = {
            AnimatedPane {
                Column(Modifier.fillMaxSize().padding(16.dp)) {
                    Text("Main Content", style = MaterialTheme.typography.headlineMedium)
                    Button(onClick = {
                        navigator.navigateTo(SupportingPaneScaffoldRole.Supporting)
                    }) {
                        Text("Open Support Panel")
                    }
                }
            }
        },
        supportingPane = {
            AnimatedPane {
                Column(Modifier.fillMaxSize().padding(16.dp)) {
                    Text("Support Info", style = MaterialTheme.typography.titleMedium)
                    Text("Additional information displayed here")
                }
            }
        }
    )
}
Enter fullscreen mode Exit fullscreen mode

Summary

Component Purpose
ListDetailPaneScaffold List-detail layout
NavigationSuiteScaffold Adaptive navigation
SupportingPaneScaffold Main + support panel
AnimatedPane Pane transition animation
  • Material3 Adaptive auto-responds to screen size
  • ListDetailPaneScaffold auto-builds tablet UI
  • NavigationSuiteScaffold auto-switches Bottom/Rail/Drawer
  • AnimatedPane smooths pane transitions

Ready-Made Android App Templates

8 production-ready Android app templates with Jetpack Compose, MVVM, Hilt, and Material 3.

Browse templatesGumroad

Top comments (0)