From 7a00b4fc95c1b9754008d7c0a080f53030209e55 Mon Sep 17 00:00:00 2001 From: Eric Schmidt Date: Tue, 4 Nov 2025 13:06:41 -0800 Subject: [PATCH 1/2] feat: adds close button to list-and-detail pane sample. --- .../SampleListDetailPaneScaffold.kt | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/SampleListDetailPaneScaffold.kt b/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/SampleListDetailPaneScaffold.kt index a6be83b43..973920e66 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/SampleListDetailPaneScaffold.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/SampleListDetailPaneScaffold.kt @@ -25,7 +25,11 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Close import androidx.compose.material3.Card +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton import androidx.compose.material3.ListItem import androidx.compose.material3.Text import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @@ -34,6 +38,7 @@ import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo import androidx.compose.material3.adaptive.layout.AnimatedPane import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole +import androidx.compose.material3.adaptive.layout.PaneAdaptedValue import androidx.compose.material3.adaptive.layout.PaneScaffoldDirective import androidx.compose.material3.adaptive.navigation.BackNavigationBehavior import androidx.compose.material3.adaptive.navigation.NavigableListDetailPaneScaffold @@ -41,6 +46,7 @@ import androidx.compose.material3.adaptive.navigation.ThreePaneScaffoldPredictiv import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.tooling.preview.Preview @@ -118,6 +124,7 @@ fun SampleNavigableListDetailPaneScaffoldFull() { // [START android_compose_adaptivelayouts_sample_list_detail_pane_scaffold_full] val scaffoldNavigator = rememberListDetailPaneScaffoldNavigator() val scope = rememberCoroutineScope() + val backNavigationBehavior = BackNavigationBehavior.PopUntilScaffoldValueChange NavigableListDetailPaneScaffold( navigator = scaffoldNavigator, @@ -137,10 +144,28 @@ fun SampleNavigableListDetailPaneScaffoldFull() { } }, detailPane = { - AnimatedPane { - // Show the detail pane content if selected item is available - scaffoldNavigator.currentDestination?.contentKey?.let { - MyDetails(it) + Column { + // Allow users to dismiss the detail pane. Use back navigation to + // hide an expanded detail pane. + if (scaffoldNavigator.scaffoldValue[ListDetailPaneScaffoldRole.Detail] == PaneAdaptedValue.Expanded) { + // Material design principles promote the usage of a right-aligned + // close (X) button. + IconButton( + modifier = Modifier.align(Alignment.End).padding(16.dp), + onClick = { + scope.launch { + scaffoldNavigator.navigateBack(backNavigationBehavior) + } + } + ) { + Icon(Icons.Default.Close, contentDescription = "Close") + } + } + AnimatedPane { + // Show the detail pane content if selected item is available + scaffoldNavigator.currentDestination?.contentKey?.let { + MyDetails(it) + } } } }, From a144afd83e31d4cfd3c644d40cb3624ade0bff34 Mon Sep 17 00:00:00 2001 From: Eric Schmidt Date: Thu, 6 Nov 2025 11:20:32 -0800 Subject: [PATCH 2/2] moved `Column` inside of `AnimatedPane` --- .../SampleListDetailPaneScaffold.kt | 57 ++++++++++++------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/SampleListDetailPaneScaffold.kt b/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/SampleListDetailPaneScaffold.kt index 973920e66..ffa15f5d1 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/SampleListDetailPaneScaffold.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/SampleListDetailPaneScaffold.kt @@ -144,26 +144,26 @@ fun SampleNavigableListDetailPaneScaffoldFull() { } }, detailPane = { - Column { - // Allow users to dismiss the detail pane. Use back navigation to - // hide an expanded detail pane. - if (scaffoldNavigator.scaffoldValue[ListDetailPaneScaffoldRole.Detail] == PaneAdaptedValue.Expanded) { - // Material design principles promote the usage of a right-aligned - // close (X) button. - IconButton( - modifier = Modifier.align(Alignment.End).padding(16.dp), - onClick = { - scope.launch { - scaffoldNavigator.navigateBack(backNavigationBehavior) + AnimatedPane { + // Show the detail pane content if selected item is available + scaffoldNavigator.currentDestination?.contentKey?.let { + Column { + // Allow users to dismiss the detail pane. Use back navigation to + // hide an expanded detail pane. + if (scaffoldNavigator.scaffoldValue[ListDetailPaneScaffoldRole.Detail] == PaneAdaptedValue.Expanded) { + // Material design principles promote the usage of a right-aligned + // close (X) button. + IconButton( + modifier = Modifier.align(Alignment.End).padding(16.dp), + onClick = { + scope.launch { + scaffoldNavigator.navigateBack(backNavigationBehavior) + } + } + ) { + Icon(Icons.Default.Close, contentDescription = "Close") } } - ) { - Icon(Icons.Default.Close, contentDescription = "Close") - } - } - AnimatedPane { - // Show the detail pane content if selected item is available - scaffoldNavigator.currentDestination?.contentKey?.let { MyDetails(it) } } @@ -180,6 +180,7 @@ fun SampleListDetailPaneScaffoldWithPredictiveBackFull() { val scaffoldNavigator = rememberListDetailPaneScaffoldNavigator() val customScaffoldDirective = customPaneScaffoldDirective(currentWindowAdaptiveInfo()) val scope = rememberCoroutineScope() + val backNavigationBehavior = BackNavigationBehavior.PopUntilScaffoldValueChange ThreePaneScaffoldPredictiveBackHandler( navigator = scaffoldNavigator, @@ -208,7 +209,25 @@ fun SampleListDetailPaneScaffoldWithPredictiveBackFull() { AnimatedPane { // Show the detail pane content if selected item is available scaffoldNavigator.currentDestination?.contentKey?.let { - MyDetails(it) + Column { + // Allow users to dismiss the detail pane. Use back navigation to + // hide an expanded detail pane. + if (scaffoldNavigator.scaffoldValue[ListDetailPaneScaffoldRole.Detail] == PaneAdaptedValue.Expanded) { + // Material design principles promote the usage of a right-aligned + // close (X) button. + IconButton( + modifier = Modifier.align(Alignment.End).padding(16.dp), + onClick = { + scope.launch { + scaffoldNavigator.navigateBack(backNavigationBehavior) + } + } + ) { + Icon(Icons.Default.Close, contentDescription = "Close") + } + } + MyDetails(it) + } } } },