From 2ba0e9857755a717be34736c44513620788437c3 Mon Sep 17 00:00:00 2001 From: Srikrishna Sakunia Date: Thu, 13 Nov 2025 18:05:55 +0530 Subject: [PATCH 01/11] Added Code Snippets for Decorators --- .../decorators/DecoratorSnippets.kt | 33 ++++ .../decorators/TracingNavEntryDecorator.kt | 145 ++++++++++++++++++ 2 files changed, 178 insertions(+) create mode 100644 compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt create mode 100644 compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/TracingNavEntryDecorator.kt diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt new file mode 100644 index 00000000..fbf3b619 --- /dev/null +++ b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt @@ -0,0 +1,33 @@ +package com.example.compose.snippets.navigation3.decorators + +import androidx.compose.runtime.Composable +import androidx.lifecycle.viewmodel.navigation3.rememberViewModelStoreNavEntryDecorator +import androidx.navigation3.runtime.NavKey +import androidx.navigation3.runtime.entryProvider +import androidx.navigation3.runtime.rememberNavBackStack +import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator +import androidx.navigation3.ui.NavDisplay +import com.example.compose.snippets.navigation3.savingstate.Home +import kotlinx.serialization.Serializable + + +// [START android_compose_navigation3_decorator_1] +@Serializable +data object Home : NavKey + +@Composable +fun DecoratorsBasic() { + + val backStack = rememberNavBackStack(Home) + NavDisplay( + entryDecorators = listOf( + rememberSaveableStateHolderNavEntryDecorator(), + rememberViewModelStoreNavEntryDecorator() + ), + backStack = backStack, + entryProvider = entryProvider { }, + ) + // [END android_compose_navigation3_decorator_1] +} + + diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/TracingNavEntryDecorator.kt b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/TracingNavEntryDecorator.kt new file mode 100644 index 00000000..aad973a5 --- /dev/null +++ b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/TracingNavEntryDecorator.kt @@ -0,0 +1,145 @@ +package com.example.compose.snippets.navigation3.decorators + +import android.os.SystemClock +import android.os.Trace +import android.util.Log +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.SideEffect +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberUpdatedState +import androidx.navigation3.runtime.NavEntryDecorator +import androidx.navigation3.runtime.NavKey +import androidx.navigation3.runtime.entryProvider +import androidx.navigation3.runtime.rememberNavBackStack +import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator +import androidx.navigation3.ui.NavDisplay +import kotlinx.serialization.Serializable + + +/** + * Decorator that automatically applies performance tracking and lifecycle tracing to every + * [NavEntry] it wraps. + * + * This is a powerful mechanism for managing cross-cutting concerns like logging and tracing + * without cluttering individual screen composables. + * + * Features: + * 1. **System Tracing**: Uses [Trace.beginSection] and [Trace.endSection] within a [DisposableEffect] + * to mark the exact lifespan of the screen in composition. This is viewable in the + * Android Studio Profiler (System Trace). + * 2. **Render Timing**: Uses a [SideEffect] to calculate the duration from the start of the + * composition until the first successful layout, providing an estimate for Time-to-First-Frame (TTFF). + * 3. **Jank State Reporting**: Provides a callback to an external system to signal when the + * current screen becomes active or inactive, which is essential for contextualizing Jank data. + * + * @param logTag The tag used for logging performance metrics (TTFF estimate). + * @param onReportJankState Callback to report screen visibility for external performance tooling. + */ + +// [START android_compose_navigation3_custom_decorator_1] +class TracingNavEntryDecorator( + private val logTag: String, + private val onReportJankState: (String, Boolean) -> Unit +): NavEntryDecorator( + onPop = { key-> + // Your onPop logic goes in here + // [START_EXCLUDE] + Log.v(logTag, "${key} popped. Cleaning up performance markers.") + // [END_EXCLUDE] + }, + decorate = {entry -> + // Your decorate logic goes in here + val name = entry.contentKey.toString() + // [START_EXCLUDE] + + DisposableEffect(entry.contentKey) { + try { + Trace.beginSection(name) + } catch (e: Exception) { + Log.e(logTag, "Ran into an $e exception") + } + + onReportJankState(name,true) + + onDispose { + Trace.endSection() + onReportJankState(name, false) + } + } + + val startTime = remember(entry.contentKey) { SystemClock.uptimeMillis() } + + SideEffect { + val duration = SystemClock.uptimeMillis() - startTime + + if (duration > 0) { + Log.d(logTag, "$name Composition to Layout took $duration ms" ) + } + } + // [END_EXCLUDE] + + entry.Content() + } +) + +// [START_EXCLUDE] +/** + * Creates and remembers a [TracingNavEntryDecorator] instance. + * + * This function handles creating the decorator and hoisting the [onReportJankState] lambda + * using [rememberUpdatedState] to ensure the latest callback is always used, + * preventing unnecessary recreation of the decorator class itself. + * + * @param logTag The tag used for Logcat output when reporting render timings and cleanup. + * The default value is "NavTrace". + * @param onReportJankState A callback used to report the entry's visibility state to an + * external performance monitoring system (like JankStats or a custom analytics engine). + * The first parameter is the screen's [contentKey] (as a String), and the second is its visibility (`true` for visible, `false` for inactive/disposed). + * @return A new or remembered instance of [TracingNavEntryDecorator]. + */ + +// [END_EXCLUDE] + +@Composable +fun rememberTracingNavEntryDecorator( + logTag: String = "NavPerformance", + reportJankState: (screenName: String, isVisible: Boolean) -> Unit = { _, _ -> }, +): TracingNavEntryDecorator { + + val currentReportJankState = rememberUpdatedState(reportJankState) + + return remember(logTag, currentReportJankState) { + TracingNavEntryDecorator( + // [START_EXCLUDE] + logTag = logTag, + onReportJankState = { name, visible -> + currentReportJankState.value.invoke(name, visible) + } + ) + } +} + +@Serializable +data object FirstScreen : NavKey + +@Composable +fun CustomDecorators() { + + val backStack = rememberNavBackStack(FirstScreen) + // [END_EXCLUDE] + NavDisplay( + entryDecorators = listOf( + rememberSaveableStateHolderNavEntryDecorator(), + rememberTracingNavEntryDecorator() + ), + // [START_EXCLUDE] + backStack = backStack, + entryProvider = entryProvider { }, + // [END_EXCLUDE] + ) + // [END android_compose_navigation3_custom_decorator_1] +} + + + From d398b380d3f96dadd831011d5f2df83d8c43e4be Mon Sep 17 00:00:00 2001 From: srikrishnasakunia <43899917+srikrishnasakunia@users.noreply.github.com> Date: Thu, 13 Nov 2025 12:41:43 +0000 Subject: [PATCH 02/11] Apply Spotless --- .../decorators/DecoratorSnippets.kt | 19 ++++++++-- .../decorators/TracingNavEntryDecorator.kt | 36 ++++++++++++------- 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt index fbf3b619..a20565e1 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt @@ -1,3 +1,19 @@ +/* + * 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 + * + * https://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.compose.snippets.navigation3.decorators import androidx.compose.runtime.Composable @@ -10,7 +26,6 @@ import androidx.navigation3.ui.NavDisplay import com.example.compose.snippets.navigation3.savingstate.Home import kotlinx.serialization.Serializable - // [START android_compose_navigation3_decorator_1] @Serializable data object Home : NavKey @@ -29,5 +44,3 @@ fun DecoratorsBasic() { ) // [END android_compose_navigation3_decorator_1] } - - diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/TracingNavEntryDecorator.kt b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/TracingNavEntryDecorator.kt index aad973a5..5144abc2 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/TracingNavEntryDecorator.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/TracingNavEntryDecorator.kt @@ -1,3 +1,19 @@ +/* + * 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 + * + * https://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.compose.snippets.navigation3.decorators import android.os.SystemClock @@ -16,7 +32,6 @@ import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator import androidx.navigation3.ui.NavDisplay import kotlinx.serialization.Serializable - /** * Decorator that automatically applies performance tracking and lifecycle tracing to every * [NavEntry] it wraps. @@ -38,17 +53,17 @@ import kotlinx.serialization.Serializable */ // [START android_compose_navigation3_custom_decorator_1] -class TracingNavEntryDecorator( +class TracingNavEntryDecorator( private val logTag: String, private val onReportJankState: (String, Boolean) -> Unit -): NavEntryDecorator( - onPop = { key-> +) : NavEntryDecorator( + onPop = { key -> // Your onPop logic goes in here // [START_EXCLUDE] - Log.v(logTag, "${key} popped. Cleaning up performance markers.") + Log.v(logTag, "$key popped. Cleaning up performance markers.") // [END_EXCLUDE] }, - decorate = {entry -> + decorate = { entry -> // Your decorate logic goes in here val name = entry.contentKey.toString() // [START_EXCLUDE] @@ -60,7 +75,7 @@ class TracingNavEntryDecorator( Log.e(logTag, "Ran into an $e exception") } - onReportJankState(name,true) + onReportJankState(name, true) onDispose { Trace.endSection() @@ -74,7 +89,7 @@ class TracingNavEntryDecorator( val duration = SystemClock.uptimeMillis() - startTime if (duration > 0) { - Log.d(logTag, "$name Composition to Layout took $duration ms" ) + Log.d(logTag, "$name Composition to Layout took $duration ms") } } // [END_EXCLUDE] @@ -102,7 +117,7 @@ class TracingNavEntryDecorator( // [END_EXCLUDE] @Composable -fun rememberTracingNavEntryDecorator( +fun rememberTracingNavEntryDecorator( logTag: String = "NavPerformance", reportJankState: (screenName: String, isVisible: Boolean) -> Unit = { _, _ -> }, ): TracingNavEntryDecorator { @@ -140,6 +155,3 @@ fun CustomDecorators() { ) // [END android_compose_navigation3_custom_decorator_1] } - - - From 2b9456df65ba16f7cf32da76f799c4c55dafa333 Mon Sep 17 00:00:00 2001 From: Srikrishna Sakunia Date: Fri, 14 Nov 2025 12:31:24 +0530 Subject: [PATCH 03/11] Added Code Snippets for Decorators --- .../decorators/DecoratorSnippets.kt | 25 ++- .../decorators/TracingNavEntryDecorator.kt | 157 ------------------ 2 files changed, 19 insertions(+), 163 deletions(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt index a20565e1..0a889b89 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt @@ -16,8 +16,11 @@ package com.example.compose.snippets.navigation3.decorators +import android.util.Log +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.lifecycle.viewmodel.navigation3.rememberViewModelStoreNavEntryDecorator +import androidx.navigation3.runtime.NavEntryDecorator import androidx.navigation3.runtime.NavKey import androidx.navigation3.runtime.entryProvider import androidx.navigation3.runtime.rememberNavBackStack @@ -26,21 +29,31 @@ import androidx.navigation3.ui.NavDisplay import com.example.compose.snippets.navigation3.savingstate.Home import kotlinx.serialization.Serializable -// [START android_compose_navigation3_decorator_1] @Serializable data object Home : NavKey @Composable fun DecoratorsBasic() { - - val backStack = rememberNavBackStack(Home) + // [START android_compose_navigation3_decorator_1] NavDisplay( entryDecorators = listOf( rememberSaveableStateHolderNavEntryDecorator(), rememberViewModelStoreNavEntryDecorator() ), - backStack = backStack, - entryProvider = entryProvider { }, + // [END android_compose_navigation3_decorator_1] + backStack = rememberNavBackStack(Home), + entryProvider = entryProvider { + entry { Text("Welcome to Nav3") } + } ) - // [END android_compose_navigation3_decorator_1] } + +// [START android_compose_navigation3_decorator_2] +class CustomNavEntryDecorator : NavEntryDecorator( + decorate = { entry -> + Log.d("CustomNavEntryDecorator","entry with ${entry.contentKey} entered composition and was decorated") + entry.Content() + }, + onPop = { contentKey -> Log.d("CustomNavEntryDecorator","entry with $contentKey was popped") } +) +// [END android_compose_navigation3_decorator_2] \ No newline at end of file diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/TracingNavEntryDecorator.kt b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/TracingNavEntryDecorator.kt index 5144abc2..e69de29b 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/TracingNavEntryDecorator.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/TracingNavEntryDecorator.kt @@ -1,157 +0,0 @@ -/* - * 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 - * - * https://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.compose.snippets.navigation3.decorators - -import android.os.SystemClock -import android.os.Trace -import android.util.Log -import androidx.compose.runtime.Composable -import androidx.compose.runtime.DisposableEffect -import androidx.compose.runtime.SideEffect -import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberUpdatedState -import androidx.navigation3.runtime.NavEntryDecorator -import androidx.navigation3.runtime.NavKey -import androidx.navigation3.runtime.entryProvider -import androidx.navigation3.runtime.rememberNavBackStack -import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator -import androidx.navigation3.ui.NavDisplay -import kotlinx.serialization.Serializable - -/** - * Decorator that automatically applies performance tracking and lifecycle tracing to every - * [NavEntry] it wraps. - * - * This is a powerful mechanism for managing cross-cutting concerns like logging and tracing - * without cluttering individual screen composables. - * - * Features: - * 1. **System Tracing**: Uses [Trace.beginSection] and [Trace.endSection] within a [DisposableEffect] - * to mark the exact lifespan of the screen in composition. This is viewable in the - * Android Studio Profiler (System Trace). - * 2. **Render Timing**: Uses a [SideEffect] to calculate the duration from the start of the - * composition until the first successful layout, providing an estimate for Time-to-First-Frame (TTFF). - * 3. **Jank State Reporting**: Provides a callback to an external system to signal when the - * current screen becomes active or inactive, which is essential for contextualizing Jank data. - * - * @param logTag The tag used for logging performance metrics (TTFF estimate). - * @param onReportJankState Callback to report screen visibility for external performance tooling. - */ - -// [START android_compose_navigation3_custom_decorator_1] -class TracingNavEntryDecorator( - private val logTag: String, - private val onReportJankState: (String, Boolean) -> Unit -) : NavEntryDecorator( - onPop = { key -> - // Your onPop logic goes in here - // [START_EXCLUDE] - Log.v(logTag, "$key popped. Cleaning up performance markers.") - // [END_EXCLUDE] - }, - decorate = { entry -> - // Your decorate logic goes in here - val name = entry.contentKey.toString() - // [START_EXCLUDE] - - DisposableEffect(entry.contentKey) { - try { - Trace.beginSection(name) - } catch (e: Exception) { - Log.e(logTag, "Ran into an $e exception") - } - - onReportJankState(name, true) - - onDispose { - Trace.endSection() - onReportJankState(name, false) - } - } - - val startTime = remember(entry.contentKey) { SystemClock.uptimeMillis() } - - SideEffect { - val duration = SystemClock.uptimeMillis() - startTime - - if (duration > 0) { - Log.d(logTag, "$name Composition to Layout took $duration ms") - } - } - // [END_EXCLUDE] - - entry.Content() - } -) - -// [START_EXCLUDE] -/** - * Creates and remembers a [TracingNavEntryDecorator] instance. - * - * This function handles creating the decorator and hoisting the [onReportJankState] lambda - * using [rememberUpdatedState] to ensure the latest callback is always used, - * preventing unnecessary recreation of the decorator class itself. - * - * @param logTag The tag used for Logcat output when reporting render timings and cleanup. - * The default value is "NavTrace". - * @param onReportJankState A callback used to report the entry's visibility state to an - * external performance monitoring system (like JankStats or a custom analytics engine). - * The first parameter is the screen's [contentKey] (as a String), and the second is its visibility (`true` for visible, `false` for inactive/disposed). - * @return A new or remembered instance of [TracingNavEntryDecorator]. - */ - -// [END_EXCLUDE] - -@Composable -fun rememberTracingNavEntryDecorator( - logTag: String = "NavPerformance", - reportJankState: (screenName: String, isVisible: Boolean) -> Unit = { _, _ -> }, -): TracingNavEntryDecorator { - - val currentReportJankState = rememberUpdatedState(reportJankState) - - return remember(logTag, currentReportJankState) { - TracingNavEntryDecorator( - // [START_EXCLUDE] - logTag = logTag, - onReportJankState = { name, visible -> - currentReportJankState.value.invoke(name, visible) - } - ) - } -} - -@Serializable -data object FirstScreen : NavKey - -@Composable -fun CustomDecorators() { - - val backStack = rememberNavBackStack(FirstScreen) - // [END_EXCLUDE] - NavDisplay( - entryDecorators = listOf( - rememberSaveableStateHolderNavEntryDecorator(), - rememberTracingNavEntryDecorator() - ), - // [START_EXCLUDE] - backStack = backStack, - entryProvider = entryProvider { }, - // [END_EXCLUDE] - ) - // [END android_compose_navigation3_custom_decorator_1] -} From f414b9a5846ec565c6c68daa8f90641d37fedd54 Mon Sep 17 00:00:00 2001 From: Srikrishna Sakunia Date: Fri, 14 Nov 2025 12:33:57 +0530 Subject: [PATCH 04/11] Added Code Snippets for Decorators --- .../snippets/navigation3/decorators/TracingNavEntryDecorator.kt | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/TracingNavEntryDecorator.kt diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/TracingNavEntryDecorator.kt b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/TracingNavEntryDecorator.kt deleted file mode 100644 index e69de29b..00000000 From 396497866d75c491cf63ae25fe5f3f75d8e5d86e Mon Sep 17 00:00:00 2001 From: srikrishnasakunia <43899917+srikrishnasakunia@users.noreply.github.com> Date: Fri, 14 Nov 2025 07:06:18 +0000 Subject: [PATCH 05/11] Apply Spotless --- .../snippets/navigation3/decorators/DecoratorSnippets.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt index 0a889b89..06701037 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt @@ -49,11 +49,11 @@ fun DecoratorsBasic() { } // [START android_compose_navigation3_decorator_2] -class CustomNavEntryDecorator : NavEntryDecorator( +class CustomNavEntryDecorator : NavEntryDecorator( decorate = { entry -> - Log.d("CustomNavEntryDecorator","entry with ${entry.contentKey} entered composition and was decorated") + Log.d("CustomNavEntryDecorator", "entry with ${entry.contentKey} entered composition and was decorated") entry.Content() }, - onPop = { contentKey -> Log.d("CustomNavEntryDecorator","entry with $contentKey was popped") } + onPop = { contentKey -> Log.d("CustomNavEntryDecorator", "entry with $contentKey was popped") } ) -// [END android_compose_navigation3_decorator_2] \ No newline at end of file +// [END android_compose_navigation3_decorator_2] From 292367c71dc4f568128ef3648e469fff64bbca82 Mon Sep 17 00:00:00 2001 From: Srikrishna Sakunia Date: Fri, 14 Nov 2025 16:17:01 +0530 Subject: [PATCH 06/11] Added Code Snippets for Decorators --- .../snippets/navigation3/decorators/DecoratorSnippets.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt index 06701037..95dc42bb 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt @@ -40,12 +40,14 @@ fun DecoratorsBasic() { rememberSaveableStateHolderNavEntryDecorator(), rememberViewModelStoreNavEntryDecorator() ), - // [END android_compose_navigation3_decorator_1] + //[START_EXCLUDE] backStack = rememberNavBackStack(Home), entryProvider = entryProvider { entry { Text("Welcome to Nav3") } } + //[END_EXCLUDE] ) + // [END android_compose_navigation3_decorator_1] } // [START android_compose_navigation3_decorator_2] From f3c5adc4427d7af98b10470d0be48fcee51fa7af Mon Sep 17 00:00:00 2001 From: srikrishnasakunia <43899917+srikrishnasakunia@users.noreply.github.com> Date: Fri, 14 Nov 2025 10:50:17 +0000 Subject: [PATCH 07/11] Apply Spotless --- .../snippets/navigation3/decorators/DecoratorSnippets.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt index 95dc42bb..1e7268a6 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt @@ -40,12 +40,12 @@ fun DecoratorsBasic() { rememberSaveableStateHolderNavEntryDecorator(), rememberViewModelStoreNavEntryDecorator() ), - //[START_EXCLUDE] + // [START_EXCLUDE] backStack = rememberNavBackStack(Home), entryProvider = entryProvider { entry { Text("Welcome to Nav3") } } - //[END_EXCLUDE] + // [END_EXCLUDE] ) // [END android_compose_navigation3_decorator_1] } From c8a044a4d80001026dcbc776c20df1b2b4b1b956 Mon Sep 17 00:00:00 2001 From: Srikrishna Sakunia Date: Fri, 14 Nov 2025 19:37:41 +0530 Subject: [PATCH 08/11] Added Code Snippets for Decorators --- .../decorators/DecoratorSnippets.kt | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt index 1e7268a6..ced4ddc2 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt @@ -19,7 +19,7 @@ package com.example.compose.snippets.navigation3.decorators import android.util.Log import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.lifecycle.viewmodel.navigation3.rememberViewModelStoreNavEntryDecorator +import androidx.compose.runtime.remember import androidx.navigation3.runtime.NavEntryDecorator import androidx.navigation3.runtime.NavKey import androidx.navigation3.runtime.entryProvider @@ -29,16 +29,35 @@ import androidx.navigation3.ui.NavDisplay import com.example.compose.snippets.navigation3.savingstate.Home import kotlinx.serialization.Serializable + + +// [START android_compose_navigation3_decorator_1] +class CustomNavEntryDecorator : NavEntryDecorator( + decorate = { entry -> + Log.d("CustomNavEntryDecorator", "entry with ${entry.contentKey} entered composition and was decorated") + entry.Content() + }, + onPop = { contentKey -> Log.d("CustomNavEntryDecorator", "entry with $contentKey was popped") } +) +// [END android_compose_navigation3_decorator_1] + +@Composable +fun rememberMyCustomNavEntryDecorator(): CustomNavEntryDecorator{ + return remember{ + CustomNavEntryDecorator() + } +} + @Serializable data object Home : NavKey @Composable fun DecoratorsBasic() { - // [START android_compose_navigation3_decorator_1] + // [START android_compose_navigation3_decorator_2] NavDisplay( entryDecorators = listOf( rememberSaveableStateHolderNavEntryDecorator(), - rememberViewModelStoreNavEntryDecorator() + rememberMyCustomNavEntryDecorator() ), // [START_EXCLUDE] backStack = rememberNavBackStack(Home), @@ -47,15 +66,5 @@ fun DecoratorsBasic() { } // [END_EXCLUDE] ) - // [END android_compose_navigation3_decorator_1] + // [END android_compose_navigation3_decorator_2] } - -// [START android_compose_navigation3_decorator_2] -class CustomNavEntryDecorator : NavEntryDecorator( - decorate = { entry -> - Log.d("CustomNavEntryDecorator", "entry with ${entry.contentKey} entered composition and was decorated") - entry.Content() - }, - onPop = { contentKey -> Log.d("CustomNavEntryDecorator", "entry with $contentKey was popped") } -) -// [END android_compose_navigation3_decorator_2] From e6c852870d1199ca104caa30d8f83eceb0e08876 Mon Sep 17 00:00:00 2001 From: srikrishnasakunia <43899917+srikrishnasakunia@users.noreply.github.com> Date: Fri, 14 Nov 2025 14:10:11 +0000 Subject: [PATCH 09/11] Apply Spotless --- .../snippets/navigation3/decorators/DecoratorSnippets.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt index ced4ddc2..80795dc4 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt @@ -29,8 +29,6 @@ import androidx.navigation3.ui.NavDisplay import com.example.compose.snippets.navigation3.savingstate.Home import kotlinx.serialization.Serializable - - // [START android_compose_navigation3_decorator_1] class CustomNavEntryDecorator : NavEntryDecorator( decorate = { entry -> @@ -42,8 +40,8 @@ class CustomNavEntryDecorator : NavEntryDecorator( // [END android_compose_navigation3_decorator_1] @Composable -fun rememberMyCustomNavEntryDecorator(): CustomNavEntryDecorator{ - return remember{ +fun rememberMyCustomNavEntryDecorator(): CustomNavEntryDecorator { + return remember { CustomNavEntryDecorator() } } From 3756bb290f1ccc847075b40ccf056ea4b9644ead Mon Sep 17 00:00:00 2001 From: Srikrishna Sakunia Date: Mon, 17 Nov 2025 16:00:25 +0530 Subject: [PATCH 10/11] Added import statements as Comments for better clarity --- .../snippets/navigation3/decorators/DecoratorSnippets.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt index 80795dc4..42de5b31 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt @@ -30,6 +30,7 @@ import com.example.compose.snippets.navigation3.savingstate.Home import kotlinx.serialization.Serializable // [START android_compose_navigation3_decorator_1] +// import androidx.navigation3.runtime.NavEntryDecorator class CustomNavEntryDecorator : NavEntryDecorator( decorate = { entry -> Log.d("CustomNavEntryDecorator", "entry with ${entry.contentKey} entered composition and was decorated") @@ -52,6 +53,14 @@ data object Home : NavKey @Composable fun DecoratorsBasic() { // [START android_compose_navigation3_decorator_2] + /* + import androidx.navigation3.ui.NavDisplay + import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator + import androidx.navigation3.runtime.rememberNavBackStack + import androidx.navigation3.runtime.entryProvider + import androidx.compose.material3.Text + */ + NavDisplay( entryDecorators = listOf( rememberSaveableStateHolderNavEntryDecorator(), From b1833cb907a93245b73e560e47d1839782b0981a Mon Sep 17 00:00:00 2001 From: Srikrishna Sakunia Date: Tue, 18 Nov 2025 12:39:00 +0530 Subject: [PATCH 11/11] Resolved Comments --- .../navigation3/decorators/DecoratorSnippets.kt | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt index 42de5b31..4fec8c5d 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/decorators/DecoratorSnippets.kt @@ -40,31 +40,18 @@ class CustomNavEntryDecorator : NavEntryDecorator( ) // [END android_compose_navigation3_decorator_1] -@Composable -fun rememberMyCustomNavEntryDecorator(): CustomNavEntryDecorator { - return remember { - CustomNavEntryDecorator() - } -} - @Serializable data object Home : NavKey @Composable fun DecoratorsBasic() { // [START android_compose_navigation3_decorator_2] - /* - import androidx.navigation3.ui.NavDisplay - import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator - import androidx.navigation3.runtime.rememberNavBackStack - import androidx.navigation3.runtime.entryProvider - import androidx.compose.material3.Text - */ + // import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator NavDisplay( entryDecorators = listOf( rememberSaveableStateHolderNavEntryDecorator(), - rememberMyCustomNavEntryDecorator() + remember { CustomNavEntryDecorator() } ), // [START_EXCLUDE] backStack = rememberNavBackStack(Home),