diff --git a/app/src/main/java/com/example/nav3recipes/scenes/listdetail/Content.kt b/app/src/main/java/com/example/nav3recipes/scenes/listdetail/Content.kt index 3ba7c9e9..fb949e96 100644 --- a/app/src/main/java/com/example/nav3recipes/scenes/listdetail/Content.kt +++ b/app/src/main/java/com/example/nav3recipes/scenes/listdetail/Content.kt @@ -20,6 +20,7 @@ import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth @@ -31,6 +32,10 @@ import androidx.compose.material3.ListItem import androidx.compose.material3.ListItemDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -73,24 +78,41 @@ fun ConversationListScreen( @Composable fun ConversationDetailScreen( conversationDetail: ConversationDetail, + onBack: () -> Unit, onProfileClicked: () -> Unit ) { - Column( + Box( modifier = Modifier .fillMaxSize() .background(colors[conversationDetail.colorId]) - .padding(16.dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center + .padding(16.dp) ) { - Text( - text = "Conversation Detail Screen: ${conversationDetail.id}", - style = MaterialTheme.typography.headlineMedium, - color = MaterialTheme.colorScheme.onSurface - ) - Spacer(modifier = Modifier.height(16.dp)) - Button(onClick = onProfileClicked) { - Text("View Profile") + if (LocalBackButtonVisibility.current) { + IconButton( + onClick = onBack, + modifier = Modifier.align(Alignment.TopStart) + ) { + Icon( + imageVector = Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = "Back" + ) + } + } + Column( + modifier = Modifier + .fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + Text( + text = "Conversation Detail Screen: ${conversationDetail.id}", + style = MaterialTheme.typography.headlineMedium, + color = MaterialTheme.colorScheme.onSurface + ) + Spacer(modifier = Modifier.height(16.dp)) + Button(onClick = onProfileClicked) { + Text("View Profile") + } } } } diff --git a/app/src/main/java/com/example/nav3recipes/scenes/listdetail/ListDetailActivity.kt b/app/src/main/java/com/example/nav3recipes/scenes/listdetail/ListDetailActivity.kt index 64a32201..82f54b66 100644 --- a/app/src/main/java/com/example/nav3recipes/scenes/listdetail/ListDetailActivity.kt +++ b/app/src/main/java/com/example/nav3recipes/scenes/listdetail/ListDetailActivity.kt @@ -87,6 +87,7 @@ class ListDetailActivity : ComponentActivity() { ) { conversationDetail -> ConversationDetailScreen( conversationDetail = conversationDetail, + onBack = { backStack.removeLastOrNull() }, onProfileClicked = { backStack.add(Profile) } ) } diff --git a/app/src/main/java/com/example/nav3recipes/scenes/listdetail/ListDetailScene.kt b/app/src/main/java/com/example/nav3recipes/scenes/listdetail/ListDetailScene.kt index b34cbff8..36137e50 100644 --- a/app/src/main/java/com/example/nav3recipes/scenes/listdetail/ListDetailScene.kt +++ b/app/src/main/java/com/example/nav3recipes/scenes/listdetail/ListDetailScene.kt @@ -25,6 +25,8 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.compositionLocalOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.navigation3.runtime.NavEntry @@ -52,18 +54,22 @@ class ListDetailScene( Column(modifier = Modifier.weight(0.4f)) { listEntry.Content() } - Column(modifier = Modifier.weight(0.6f)) { - AnimatedContent( - targetState = detailEntry, - contentKey = { entry -> entry.contentKey }, - transitionSpec = { - slideInHorizontally( - initialOffsetX = { it } - ) togetherWith - slideOutHorizontally(targetOffsetX = { -it }) + + // Let the detail entry know not to display a back button. + CompositionLocalProvider(LocalBackButtonVisibility provides false){ + Column(modifier = Modifier.weight(0.6f)) { + AnimatedContent( + targetState = detailEntry, + contentKey = { entry -> entry.contentKey }, + transitionSpec = { + slideInHorizontally( + initialOffsetX = { it } + ) togetherWith + slideOutHorizontally(targetOffsetX = { -it }) + } + ) { entry -> + entry.Content() } - ){ entry -> - entry.Content() } } } @@ -87,6 +93,13 @@ class ListDetailScene( } } +/** + * This `CompositionLocal` can be used by a detail `NavEntry` to decide whether to display + * a back button. Default is `true`. It is set to `false` for a detail `NavEntry` when being + * displayed in a `ListDetailScene`. + */ +val LocalBackButtonVisibility = compositionLocalOf{ true } + @Composable fun rememberListDetailSceneStrategy(): ListDetailSceneStrategy { val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass diff --git a/app/src/main/java/com/example/nav3recipes/scenes/listdetail/README.md b/app/src/main/java/com/example/nav3recipes/scenes/listdetail/README.md index 7065d580..d072585c 100644 --- a/app/src/main/java/com/example/nav3recipes/scenes/listdetail/README.md +++ b/app/src/main/java/com/example/nav3recipes/scenes/listdetail/README.md @@ -8,4 +8,6 @@ A `ListDetailSceneStrategy` will return a `ListDetailScene` if: - A `Detail` entry is the last item in the back stack - A `List` entry is in the back stack +The `ListDetailScene` provides a `CompositionLocal` named `LocalBackButtonVisibility` that can be used by the detail `NavEntry` to control whether it displays a back button. This is useful when the detail entry usually displays a back button but should not display it when being displayed in a `ListDetailScene`. See https://github.com/android/nav3-recipes/issues/151 for more details on this use case. + See `ListDetailScene.kt` for more implementation details.