@@ -21,19 +21,19 @@ import androidx.compose.foundation.layout.Row
2121import androidx.compose.foundation.layout.fillMaxSize
2222import androidx.compose.material3.Button
2323import androidx.compose.material3.Text
24- import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
2524import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
26- import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
2725import androidx.compose.runtime.Composable
26+ import androidx.compose.runtime.remember
2827import androidx.compose.ui.Modifier
2928import androidx.navigation3.runtime.NavEntry
3029import androidx.navigation3.runtime.NavKey
31- import androidx.navigation3.runtime.entry
3230import androidx.navigation3.runtime.entryProvider
3331import androidx.navigation3.runtime.rememberNavBackStack
32+ import androidx.navigation3.scene.Scene
33+ import androidx.navigation3.scene.SceneStrategy
34+ import androidx.navigation3.scene.SceneStrategyScope
3435import androidx.navigation3.ui.NavDisplay
35- import androidx.navigation3.ui.Scene
36- import androidx.navigation3.ui.SceneStrategy
36+ import androidx.window.core.layout.WindowSizeClass
3737import androidx.window.core.layout.WindowSizeClass.Companion.WIDTH_DP_MEDIUM_LOWER_BOUND
3838import kotlinx.serialization.Serializable
3939
@@ -63,8 +63,7 @@ data class SinglePaneScene<T : Any>(
6363 * list.
6464 */
6565public class SinglePaneSceneStrategy <T : Any > : SceneStrategy <T > {
66- @Composable
67- override fun calculateScene (entries : List <NavEntry <T >>, onBack : (Int ) -> Unit ): Scene <T > =
66+ override fun SceneStrategyScope<T>.calculateScene (entries : List <NavEntry <T >>): Scene <T >? =
6867 SinglePaneScene (
6968 key = entries.last().contentKey,
7069 entry = entries.last(),
@@ -106,21 +105,22 @@ class TwoPaneScene<T : Any>(
106105 }
107106}
108107
108+ @Composable
109+ fun <T : Any > rememberTwoPaneSceneStrategy (): TwoPaneSceneStrategy <T > {
110+ val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass
111+
112+ return remember(windowSizeClass) {
113+ TwoPaneSceneStrategy (windowSizeClass)
114+ }
115+ }
116+
109117// --- TwoPaneSceneStrategy ---
110118/* *
111119 * A [SceneStrategy] that activates a [TwoPaneScene] if the window is wide enough
112120 * and the top two back stack entries declare support for two-pane display.
113121 */
114- class TwoPaneSceneStrategy <T : Any > : SceneStrategy <T > {
115- @OptIn(ExperimentalMaterial3AdaptiveApi ::class , ExperimentalMaterial3WindowSizeClassApi ::class )
116- @Composable
117- override fun calculateScene (
118- entries : List <NavEntry <T >>,
119- onBack : (Int ) -> Unit
120- ): Scene <T >? {
121-
122- val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass
123-
122+ class TwoPaneSceneStrategy <T : Any >(val windowSizeClass : WindowSizeClass ) : SceneStrategy<T> {
123+ override fun SceneStrategyScope<T>.calculateScene (entries : List <NavEntry <T >>): Scene <T >? {
124124 // Condition 1: Only return a Scene if the window is sufficiently wide to render two panes.
125125 // We use isWidthAtLeastBreakpoint with WIDTH_DP_MEDIUM_LOWER_BOUND (600dp).
126126 if (! windowSizeClass.isWidthAtLeastBreakpoint(WIDTH_DP_MEDIUM_LOWER_BOUND )) {
@@ -193,12 +193,10 @@ fun MyAppContent() {
193193 // ... other entries ...
194194 },
195195 // Simply provide your custom strategy. NavDisplay will fall back to SinglePaneSceneStrategy automatically.
196- sceneStrategy = TwoPaneSceneStrategy <Any >(),
197- onBack = { count ->
198- repeat(count) {
199- if (backStack.isNotEmpty()) {
200- backStack.removeLastOrNull()
201- }
196+ sceneStrategy = rememberTwoPaneSceneStrategy(),
197+ onBack = {
198+ if (backStack.isNotEmpty()) {
199+ backStack.removeLastOrNull()
202200 }
203201 }
204202 )
0 commit comments