-
Notifications
You must be signed in to change notification settings - Fork 63
Add bottom sheet recipe #67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jbw0033
wants to merge
81
commits into
android:main
Choose a base branch
from
jbw0033:bottomsheet
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+4,407
−138
Open
Changes from 1 commit
Commits
Show all changes
81 commits
Select commit
Hold shift + click to select a range
917a444
Adding tests for Navigator
dturner e88d470
First draft of Navigator for nested and shared destinations
dturner 1b9681c
Address AI feedback
dturner 8a36488
Add Nav2 activity and dependencies
dturner 2104f89
Add starting point for migration
dturner 6a56eca
Step 1 of migration complete
dturner 24d2fb9
Lots of refactoring
dturner caed027
Add Step 4 of the migration
dturner 40482df
Add Step 5 of the migration
dturner 0110faa
Part way through step 6 of migration
dturner 309f912
Updating all steps
dturner 5019ac2
Add final step 7.
dturner 3e9bc63
Tidy up imports
dturner 26f754d
Merge branch 'main' into dt/2to3migration
dturner 0d9b38e
Merge branch 'main' into dt/2to3migration
dturner 17b4015
Navigator uses SavedState APIs and KotlinX Serialization to persist s…
dturner de6bdf4
Remove remaining Nav2 references from step 7
dturner 466b3a1
Handle shared routes
dturner 201f488
Switch to using Saver
dturner 9caf04f
Add bottom sheet recipe
jbw0033 bd08782
Remove parenthesis from BottomSheetSceneStrategy
jbw0033 bde7f74
Minor edits
dturner 6bb1fe4
Update headings in README for better structure
dturner ba8221f
Update to latest library versions and disable snapshot artifact repo
dturner 4141b46
Replace SnapshotStateList with NavBackStack
dturner fd7be63
Address Gemini feedback
dturner d23149d
Add link to bug
dturner 5928c4d
Merge pull request #79 from android/dt/update-versions
dturner 93f9730
Create Supporting Pane Recipe
tiwiz efee1c1
Create Supporting Pane Recipe
tiwiz 17a045d
Update dependencies to sync with Supporting Pane PR
tiwiz fb49912
Merge branch 'dependencies-update' into supporting-pane
tiwiz 28146a5
Merge pull request #81 from android/dependencies-update
ianhanniballake c324bab
Fix comments
tiwiz f178728
Merge remote-tracking branch 'origin/main' into supporting-pane
tiwiz 2f164b9
Fix comments
tiwiz f496dbc
Update README file
tiwiz d4db6e1
Fix naming
tiwiz 975d88e
Merge pull request #80 from android/supporting-pane
ianhanniballake c054009
Add koin injected ViewModel recipe
dturner 3f5fe09
Slight formatting change
dturner a8e577e
Addressing AI code review
dturner dccb089
Merge pull request #83 from android/dt/koin
ianhanniballake bce2b1b
Move Material recipes to their specific package
tiwiz 47b4df3
Update README.md
tiwiz 1f0c2ee
Update README.md
dturner 496be6a
Update README.md
dturner 8def1d6
Update README.md
dturner 804f572
Update README.md
dturner a0841fe
Merge pull request #85 from android/material
tiwiz 0e5efe3
Add bottom sheet recipe
jbw0033 2bb993e
Remove parenthesis from BottomSheetSceneStrategy
jbw0033 8d0e30d
Minor edits
dturner f512dfe
Merge remote-tracking branch 'origin/bottomsheet' into bottomsheet
jbw0033 df2d43e
Add bottom sheet recipe
jbw0033 c303cd0
Remove parenthesis from BottomSheetSceneStrategy
jbw0033 49cff71
Minor edits
dturner 2115ada
Merge remote-tracking branch 'origin/bottomsheet' into bottomsheet
jbw0033 a857897
Update to alpha10
dturner 2648ce8
Update gradle/libs.versions.toml
dturner 72108df
Add migration guide
dturner 0c9eb4b
Update guide
dturner 7510ef3
Update guide
dturner a8da9c4
Update guide
dturner 90f66ab
Update guide
dturner 52032b2
Update guide
dturner f31ea9e
Update guide
dturner f46b3fc
Update guide
dturner 5c94195
Merge branch 'main' into dt/2to3migration
dturner 26133a4
Remove navigator package
dturner aaab38f
Merge pull request #89 from android/dt/alpha10
jbw0033 4ea983d
Merge remote-tracking branch 'origin/bottomsheet' into bottomsheet
jbw0033 495c65b
Fix errors in Bottomsheet Recipe
jbw0033 4beb9c0
Refactor to render NavDisplay on top of NavHost, rather than wrapping it
dturner 598c263
Merge branch 'main' into dt/2to3migration
dturner beeeddc
Update to use alpha10 API
dturner 00e4e2a
Merge pull request #46 from android/dt/2to3migration
dturner 78dd22b
Update links in migration guide
dturner 08b63ff
Fix link to migration package
dturner 28947aa
Fix version
dturner 13642c3
Merge remote-tracking branch 'origin/bottomsheet' into bottomsheet
jbw0033 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
94 changes: 94 additions & 0 deletions
94
app/src/main/java/com/example/nav3recipes/bottomsheet/BottomSheetActivity.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
/* | ||
* Copyright 2025 The Android Open Source Project | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package com.example.nav3recipes.bottomsheet | ||
|
||
import android.os.Bundle | ||
import androidx.activity.ComponentActivity | ||
import androidx.activity.compose.setContent | ||
import androidx.compose.foundation.shape.RoundedCornerShape | ||
import androidx.compose.material3.Button | ||
import androidx.compose.material3.ExperimentalMaterial3Api | ||
import androidx.compose.material3.Text | ||
import androidx.compose.runtime.remember | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.draw.clip | ||
import androidx.compose.ui.unit.dp | ||
import androidx.navigation3.runtime.NavKey | ||
import androidx.navigation3.runtime.entry | ||
import androidx.navigation3.runtime.entryProvider | ||
import androidx.navigation3.runtime.rememberNavBackStack | ||
import androidx.navigation3.ui.NavDisplay | ||
import com.example.nav3recipes.content.ContentBlue | ||
import com.example.nav3recipes.content.ContentGreen | ||
import com.example.nav3recipes.ui.setEdgeToEdgeConfig | ||
import kotlinx.serialization.Serializable | ||
|
||
/** | ||
* This recipe demonstrates how to create a bottom sheet. It does this by: | ||
* | ||
* - Adding the `BottomSheetSceneStrategy` to the list of strategies used by `NavDisplay`. | ||
* - Adding `BottomSheetSceneStrategy.bottomsheet` to a `NavEntry`'s metadata to indicate that it | ||
* is a bottom sheet. In this case it is applied to the `NavEntry` for `RouteB`. | ||
* | ||
* See also https://developer.android.com/guide/navigation/navigation-3/custom-layouts | ||
*/ | ||
|
||
@Serializable | ||
private data object RouteA : NavKey | ||
|
||
@Serializable | ||
private data class RouteB(val id: String) : NavKey | ||
|
||
class BottomSheetActivity : ComponentActivity() { | ||
|
||
@OptIn(ExperimentalMaterial3Api::class) | ||
override fun onCreate(savedInstanceState: Bundle?) { | ||
setEdgeToEdgeConfig() | ||
super.onCreate(savedInstanceState) | ||
setContent { | ||
val backStack = rememberNavBackStack(RouteA) | ||
val bottomSheetStrategy = remember { BottomSheetSceneStrategy<NavKey>() } | ||
|
||
NavDisplay( | ||
backStack = backStack, | ||
onBack = { backStack.removeLastOrNull() }, | ||
sceneStrategy = bottomSheetStrategy, | ||
entryProvider = entryProvider { | ||
entry<RouteA> { | ||
ContentGreen("Welcome to Nav3") { | ||
Button(onClick = { | ||
backStack.add(RouteB("123")) | ||
}) { | ||
Text("Click to open bottom sheet") | ||
} | ||
} | ||
} | ||
entry<RouteB>( | ||
metadata = BottomSheetSceneStrategy.bottomSheet() | ||
) { key -> | ||
ContentBlue( | ||
title = "Route id: ${key.id}", | ||
modifier = Modifier.clip( | ||
shape = RoundedCornerShape(16.dp) | ||
) | ||
) | ||
} | ||
} | ||
) | ||
} | ||
} | ||
} |
79 changes: 79 additions & 0 deletions
79
app/src/main/java/com/example/nav3recipes/bottomsheet/BottomSheetSceneStrategy.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package com.example.nav3recipes.bottomsheet | ||
|
||
import androidx.compose.material3.ExperimentalMaterial3Api | ||
import androidx.compose.material3.ModalBottomSheet | ||
import androidx.compose.material3.ModalBottomSheetProperties | ||
import androidx.compose.runtime.Composable | ||
import androidx.navigation3.runtime.NavEntry | ||
import androidx.navigation3.ui.OverlayScene | ||
import androidx.navigation3.ui.Scene | ||
import androidx.navigation3.ui.SceneStrategy | ||
|
||
/** An [OverlayScene] that renders an [entry] within a [ModalBottomSheet]. */ | ||
@OptIn(ExperimentalMaterial3Api::class) | ||
internal class BottomSheetScene<T : Any>( | ||
override val key: T, | ||
override val previousEntries: List<NavEntry<T>>, | ||
override val overlaidEntries: List<NavEntry<T>>, | ||
private val entry: NavEntry<T>, | ||
private val modalBottomSheetProperties: ModalBottomSheetProperties, | ||
private val onBack: (count: Int) -> Unit, | ||
) : OverlayScene<T> { | ||
|
||
override val entries: List<NavEntry<T>> = listOf(entry) | ||
|
||
override val content: @Composable (() -> Unit) = { | ||
ModalBottomSheet( | ||
onDismissRequest = { onBack(1) }, | ||
properties = modalBottomSheetProperties, | ||
) { | ||
entry.Content() | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* A [SceneStrategy] that displays entries that have added [bottomSheet] to their [NavEntry.metadata] | ||
* within a [ModalBottomSheet] instance. | ||
* | ||
* This strategy should always be added before any non-overlay scene strategies. | ||
*/ | ||
@OptIn(ExperimentalMaterial3Api::class) | ||
class BottomSheetSceneStrategy<T : Any>() : SceneStrategy<T> { | ||
|
||
@Composable | ||
override fun calculateScene( | ||
entries: List<NavEntry<T>>, | ||
onBack: (Int) -> Unit | ||
): Scene<T>? { | ||
val lastEntry = entries.lastOrNull() | ||
val bottomSheetProperties = lastEntry?.metadata?.get(BOTTOM_SHEET_KEY) as? ModalBottomSheetProperties | ||
return bottomSheetProperties?.let { properties -> | ||
@Suppress("UNCHECKED_CAST") | ||
BottomSheetScene( | ||
key = lastEntry.contentKey as T, | ||
previousEntries = entries.dropLast(1), | ||
overlaidEntries = entries.dropLast(1), | ||
entry = lastEntry, | ||
modalBottomSheetProperties = properties, | ||
onBack = onBack | ||
) | ||
} | ||
} | ||
|
||
companion object { | ||
/** | ||
* Function to be called on the [NavEntry.metadata] to mark this entry as something that | ||
* should be displayed within a [ModalBottomSheet]. | ||
* | ||
* @param modalBottomSheetProperties properties that should be passed to the containing | ||
* [ModalBottomSheet]. | ||
*/ | ||
@OptIn(ExperimentalMaterial3Api::class) | ||
fun bottomSheet( | ||
modalBottomSheetProperties: ModalBottomSheetProperties = ModalBottomSheetProperties() | ||
): Map<String, Any> = mapOf(BOTTOM_SHEET_KEY to modalBottomSheetProperties) | ||
|
||
internal const val BOTTOM_SHEET_KEY = "bottomsheet" | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.