reis-mobile 0.3.6 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +24 -0
- package/README.md +175 -168
- package/THIRD_PARTY_NOTICES.md +224 -4
- package/agents/android-architect.md +89 -0
- package/agents/android-performance-engineer.md +92 -0
- package/agents/android-test-engineer.md +97 -0
- package/agents/flutter-test-engineer.md +2 -0
- package/agents/ios-architect.md +93 -0
- package/agents/ios-performance-engineer.md +92 -0
- package/agents/ios-test-engineer.md +95 -0
- package/agents/lead-mobile.md +10 -1
- package/agents/mobile-staff-engineer.md +1 -1
- package/agents/rn-architect.md +94 -0
- package/agents/rn-performance-engineer.md +92 -0
- package/agents/rn-test-engineer.md +98 -0
- package/bin/reis-mobile.mjs +59 -17
- package/commands/debate.md +10 -1
- package/commands/debug.md +60 -0
- package/commands/reis-mobile.md +7 -2
- package/core/config/project.mjs +59 -0
- package/core/registry/frontmatter.mjs +15 -4
- package/core/registry/registry.mjs +21 -1
- package/core/router/intents.mjs +2 -0
- package/core/router/router.mjs +10 -5
- package/package.json +1 -1
- package/skills/android-adaptive/SKILL.md +304 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/flexbox/container-behavior.md +112 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/flexbox/get-started.md +69 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/flexbox/index.md +81 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/flexbox/item-behavior.md +170 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/grid/container-properties.md +415 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/grid/get-started.md +51 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/grid/index.md +73 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/grid/item-properties.md +170 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/mediaquery/index.md +333 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/tooling/debug.md +114 -0
- package/skills/android-adaptive/references/android/guide/navigation/navigation-3/recipes/material-listdetail.md +141 -0
- package/skills/android-agp-9-upgrade/SKILL.md +106 -0
- package/skills/android-agp-9-upgrade/references/android/build/migrate-to-built-in-kotlin.md +416 -0
- package/skills/android-agp-9-upgrade/references/android/build/releases/agp-9-0-0-release-notes.md +554 -0
- package/skills/android-agp-9-upgrade/references/buildconfig.md +54 -0
- package/skills/android-agp-9-upgrade/references/ksp-kapt.md +39 -0
- package/skills/android-agp-9-upgrade/references/paparazzi-gradle-9.md +30 -0
- package/skills/android-agp-9-upgrade/references/recipes.md +62 -0
- package/skills/android-appfunctions/SKILL.md +74 -0
- package/skills/android-appfunctions/references/adb-interaction-testing.md +95 -0
- package/skills/android-appfunctions/references/context.md +26 -0
- package/skills/android-appfunctions/references/feature-discovery-analysis.md +71 -0
- package/skills/android-appfunctions/references/implementation-configuration.md +282 -0
- package/skills/android-appfunctions/references/kdoc-refinement-optimization.md +75 -0
- package/skills/android-appfunctions/references/migrate-to-service-entry-point.md +226 -0
- package/skills/android-camerax/SKILL.md +135 -0
- package/skills/android-camerax/references/camera1-to-camerax.md +198 -0
- package/skills/android-camerax/references/camera2-to-camerax.md +193 -0
- package/skills/android-camerax/references/expert-blueprints.md +58 -0
- package/skills/android-camerax/references/foldables.md +83 -0
- package/skills/android-camerax/references/immutability.md +60 -0
- package/skills/android-camerax/references/low-light.md +124 -0
- package/skills/android-camerax/references/mlkit-spatial.md +75 -0
- package/skills/android-camerax/references/modern-apis.md +42 -0
- package/skills/android-camerax/references/testing.md +69 -0
- package/skills/android-camerax/references/thermals.md +85 -0
- package/skills/android-camerax/references/wear-os.md +76 -0
- package/skills/android-camerax/references/xr.md +54 -0
- package/skills/android-cli/SKILL.md +474 -0
- package/skills/android-cli/references/interact.md +113 -0
- package/skills/android-cli/references/journeys.md +120 -0
- package/skills/android-code-review/SKILL.md +58 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/SKILL.md +340 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/design/ui/ai-glasses/guides/interaction/inputs.md +67 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/access-hardware-projected-context.md +388 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/buttons.md +139 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/cards.md +148 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/focus.md +107 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/icons.md +90 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/text.md +69 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/title-chips.md +82 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/request-hardware-permissions.md +213 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/button-samples-source.md +176 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/button-source.md +203 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/card-samples-source.md +296 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/card-source.md +515 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/deptheffect-source.md +224 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/deptheffectlevels-source.md +105 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/glimmersansflextypography-source.md +270 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/glimmertheme-source.md +182 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/icon-source.md +388 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/iconbutton-source.md +126 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/iconsizes-source.md +78 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/list-source.md +27 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/listitem-source.md +272 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/liststate-source.md +427 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/material-hct-source.md +217 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/projectedcontext-source.md +265 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/stack-source.md +368 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/stackitemscope-source.md +440 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/stackstate-source.md +325 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/surface-source.md +1211 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/titlechip-samples-source.md +101 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/titlechip-source.md +131 -0
- package/skills/android-edge-to-edge/SKILL.md +429 -0
- package/skills/android-engage-sdk-integration/SKILL.md +130 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/faq.md +439 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/food.md +1149 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/healthandfitness.md +1055 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/listen.md +1050 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/otherverticals.md +1301 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/read.md +910 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/shopping.md +1224 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/social.md +719 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/travel.md +1413 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/tv/continue-watching/index.md +19 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/tv/entitlements.md +353 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/tv/getting-started.md +202 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/tv/recommendations.md +471 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/watch.md +1081 -0
- package/skills/android-engage-sdk-integration/references/clusters.md +154 -0
- package/skills/android-engage-sdk-integration/references/common.md +519 -0
- package/skills/android-engage-sdk-integration/references/patterns.md +527 -0
- package/skills/android-engage-sdk-integration/references/requests.md +260 -0
- package/skills/android-engage-sdk-integration/references/schemas/food.md +509 -0
- package/skills/android-engage-sdk-integration/references/schemas/listen.md +842 -0
- package/skills/android-engage-sdk-integration/references/schemas/other.md +220 -0
- package/skills/android-engage-sdk-integration/references/schemas/read.md +412 -0
- package/skills/android-engage-sdk-integration/references/schemas/shopping.md +357 -0
- package/skills/android-engage-sdk-integration/references/schemas/social.md +228 -0
- package/skills/android-engage-sdk-integration/references/schemas/travel.md +923 -0
- package/skills/android-engage-sdk-integration/references/schemas/tv.md +1226 -0
- package/skills/android-engage-sdk-integration/references/schemas/watch.md +1137 -0
- package/skills/android-engage-sdk-integration/references/troubleshooting.md +39 -0
- package/skills/android-gradle-build-debug/SKILL.md +71 -0
- package/skills/android-intent-security/SKILL.md +550 -0
- package/skills/android-leanback-to-compose-tv-migration/SKILL.md +743 -0
- package/skills/android-leanback-to-compose-tv-migration/references/android/training/tv/get-started/navigation.md +372 -0
- package/skills/android-leanback-to-compose-tv-migration/references/android/training/tv/playback/compose/browse.md +243 -0
- package/skills/android-leanback-to-compose-tv-migration/references/android/training/tv/playback/compose/index.md +153 -0
- package/skills/android-media3-cast-integration/SKILL.md +236 -0
- package/skills/android-media3-cast-integration/references/android/media/media3/cast/create-castplayer.md +390 -0
- package/skills/android-media3-cast-integration/references/android/media/media3/cast/customize-castoptions.md +93 -0
- package/skills/android-media3-cast-integration/references/android/media/media3/cast/index.md +21 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/SKILL.md +127 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/references/analysis-of-the-project-and-layout.md +42 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/references/android/develop/ui/compose/designsystems/migrate-xml-theme-to-compose.md +171 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/references/android/develop/ui/compose/migrate/interoperability-apis/compose-in-views.md +299 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/references/android/develop/ui/compose/migrate/interoperability-apis/views-in-compose.md +286 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/references/android/develop/ui/compose/setup-compose-dependencies-and-compiler.md +197 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/references/identify-optimal-xml-candidate.md +31 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/references/xml-layout-migration.md +86 -0
- package/skills/android-ml-kit-genai-prompt-api/SKILL.md +124 -0
- package/skills/android-ml-kit-genai-prompt-api/references/get-started.md +272 -0
- package/skills/android-ml-kit-genai-prompt-api/references/prefix-caching.md +146 -0
- package/skills/android-ml-kit-genai-prompt-api/references/prompt-design.md +55 -0
- package/skills/android-ml-kit-genai-prompt-api/references/prompt-optimization.md +74 -0
- package/skills/android-ml-kit-genai-prompt-api/references/structured-output.md +219 -0
- package/skills/android-ml-kit-genai-prompt-api/references/system-instructions.md +71 -0
- package/skills/android-navigation-3/SKILL.md +122 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/index.md +51 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/migration-guide.md +670 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/animations.md +147 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/basic.md +89 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/basicdsl.md +85 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/basicsaveable.md +90 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/bottomsheet.md +195 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/common-ui.md +200 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/conditional-transitions.md +182 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/conditional.md +230 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/deeplinks-custommatcher.md +176 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/deeplinks-staticuri.md +140 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/deeplinks-syntheticbackstack.md +184 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/dialog.md +107 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/lifecycle-owner.md +185 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/material-listdetail.md +141 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/material-supportingpane.md +145 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/modular-hilt.md +283 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/modular-koin.md +287 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/multiple-backstacks.md +468 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/passingarguments.md +371 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/results-event.md +273 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/results-state.md +266 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/scenes-listdetail.md +435 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/scenes-twopane.md +244 -0
- package/skills/android-navigation-3/references/android/guide/navigation/type-safe-destinations.md +129 -0
- package/skills/android-navigation-event/SKILL.md +312 -0
- package/skills/android-navigation-event/references/android/guide/navigation/navigation-event/dispatcher.md +134 -0
- package/skills/android-navigation-event/references/android/guide/navigation/navigation-event/handle-back.md +217 -0
- package/skills/android-navigation-event/references/android/guide/navigation/navigation-event/index.md +83 -0
- package/skills/android-navigation-event/references/android/guide/navigation/navigation-event/setup.md +32 -0
- package/skills/android-play-billing-library-version-upgrade/SKILL.md +96 -0
- package/skills/android-play-billing-library-version-upgrade/references/android/google/play/billing/release-notes.md +1240 -0
- package/skills/android-play-billing-library-version-upgrade/references/migration-logic.md +78 -0
- package/skills/android-play-billing-library-version-upgrade/references/version-checklist.md +54 -0
- package/skills/android-play-policy-insights/SKILL.md +172 -0
- package/skills/android-play-policy-insights/resources/common_mandates.md +100 -0
- package/skills/android-play-policy-insights/resources/compliance_report_template.md +59 -0
- package/skills/android-play-policy-insights/resources/critic.md +86 -0
- package/skills/android-play-policy-insights/resources/goal_data_safety.md +212 -0
- package/skills/android-play-policy-insights/resources/goal_permissions_and_apis.md +459 -0
- package/skills/android-play-policy-insights/resources/goal_user_account.md +106 -0
- package/skills/android-play-policy-insights/resources/policies.json +321 -0
- package/skills/android-play-policy-insights/resources/scanner_config.json +843 -0
- package/skills/android-play-policy-insights/scripts/generate_report.py +860 -0
- package/skills/android-play-policy-insights/scripts/orchestrator.py +1313 -0
- package/skills/android-play-policy-insights/scripts/play_store_scraper.py +410 -0
- package/skills/android-play-policy-insights/scripts/scanner.py +261 -0
- package/skills/android-play-policy-insights/scripts/template_engine.py +243 -0
- package/skills/android-profiler/SKILL.md +60 -0
- package/skills/android-profiler/analysis/analysis_orchestrator.md +32 -0
- package/skills/android-profiler/analysis/workflows/perfetto-sql/perfetto_sql.md +28 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/perfetto_trace_analysis.md +121 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/guiding_principles.md +51 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/domain_hints_template.md +7 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_cpu.md +56 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_graphics.md +51 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_io.md +46 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_ipc.md +41 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_memory.md +55 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_power.md +33 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/per_candidate_analysis.md +172 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/triage.md +94 -0
- package/skills/android-profiler/recording/recording_orchestrator.md +36 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/perfetto_trace_recording.md +148 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/app_jank.pftxt +43 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/cpu_profile.pftxt +35 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/java_heap_dump.pftxt +21 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/long_background.pftxt +37 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/memory_counters.pftxt +45 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/native_heap.pftxt +21 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/sched_cpu.pftxt +33 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/trace_config_reference.md +102 -0
- package/skills/android-profiler/references/env_setup.md +15 -0
- package/skills/android-profiler/references/perfetto/setup.md +29 -0
- package/skills/android-profiler/references/perfetto/sql.md +327 -0
- package/skills/android-r8-analyzer/SKILL.md +72 -0
- package/skills/android-r8-analyzer/references/CONFIGURATION-ANALYZER.md +287 -0
- package/skills/android-r8-analyzer/references/CONFIGURATION.md +44 -0
- package/skills/android-r8-analyzer/references/KEEP-RULES-IMPACT-HIERARCHY.md +83 -0
- package/skills/android-r8-analyzer/references/REDUNDANT-RULES.md +222 -0
- package/skills/android-r8-analyzer/references/REFLECTION-GUIDE.md +139 -0
- package/skills/android-r8-analyzer/references/REPORT_FORMAT.md +51 -0
- package/skills/android-r8-analyzer/references/android/topic/performance/app-optimization/enable-app-optimization.md +252 -0
- package/skills/android-r8-analyzer/references/android/training/testing/other-components/ui-automator.md +312 -0
- package/skills/android-restore-credentials/SKILL.md +359 -0
- package/skills/android-restore-credentials/references/android/guide/topics/manifest/application-element.md +832 -0
- package/skills/android-restore-credentials/references/android/identity/passkeys/create-passkeys.md +327 -0
- package/skills/android-restore-credentials/references/android/identity/passkeys/sign-in-with-passkeys.md +219 -0
- package/skills/android-styles/SKILL.md +229 -0
- package/skills/android-styles/references/android/develop/ui/compose/designsystems/custom.md +459 -0
- package/skills/android-styles/references/android/develop/ui/compose/styles/fundamentals.md +421 -0
- package/skills/android-styles/references/android/develop/ui/compose/styles/state-animations.md +461 -0
- package/skills/android-styles/references/android/develop/ui/compose/styles/styles-vs-modifiers.md +48 -0
- package/skills/android-styles/references/android/develop/ui/compose/styles/theming.md +269 -0
- package/skills/android-verified-email/SKILL.md +432 -0
- package/skills/android-verified-email/references/android/identity/credential-manager/index.md +67 -0
- package/skills/android-verified-email/references/android/identity/digital-credentials/credential-verifier.md +166 -0
- package/skills/android-verified-email/references/android/identity/digital-credentials/email-verification-implementation.md +313 -0
- package/skills/android-verified-email/references/android/identity/digital-credentials/email-verification.md +158 -0
- package/skills/android-verified-email/references/android/identity/digital-credentials/index.md +112 -0
- package/skills/android-verified-email/references/android/identity/passkeys/create-passkeys.md +327 -0
- package/skills/android-verified-email/references/android/identity/sign-in/credential-manager-webview.md +84 -0
- package/skills/android-wear-compose-m3/SKILL.md +365 -0
- package/skills/android-wear-compose-m3/references/android/training/wearables/compose/migrate-to-material3.md +677 -0
- package/skills/android-wear-compose-m3/references/foundation/AmbientModeSample.kt.md +123 -0
- package/skills/android-wear-compose-m3/references/foundation/AmbientModeSample.kt.md.txt +123 -0
- package/skills/android-wear-compose-m3/references/foundation/CurvedWorldSample.kt.md +430 -0
- package/skills/android-wear-compose-m3/references/foundation/CurvedWorldSample.kt.md.txt +430 -0
- package/skills/android-wear-compose-m3/references/foundation/ExpandableSample.kt.md +99 -0
- package/skills/android-wear-compose-m3/references/foundation/ExpandableSample.kt.md.txt +99 -0
- package/skills/android-wear-compose-m3/references/foundation/HierarchicalFocusSample.kt.md +141 -0
- package/skills/android-wear-compose-m3/references/foundation/HierarchicalFocusSample.kt.md.txt +141 -0
- package/skills/android-wear-compose-m3/references/foundation/PagerSamples.kt.md +56 -0
- package/skills/android-wear-compose-m3/references/foundation/PagerSamples.kt.md.txt +56 -0
- package/skills/android-wear-compose-m3/references/foundation/RotarySamples.kt.md +153 -0
- package/skills/android-wear-compose-m3/references/foundation/RotarySamples.kt.md.txt +153 -0
- package/skills/android-wear-compose-m3/references/foundation/ScalingLazyColumnSample.kt.md +131 -0
- package/skills/android-wear-compose-m3/references/foundation/ScalingLazyColumnSample.kt.md.txt +131 -0
- package/skills/android-wear-compose-m3/references/foundation/SwipeToDismissBoxSample.kt.md +169 -0
- package/skills/android-wear-compose-m3/references/foundation/SwipeToDismissBoxSample.kt.md.txt +169 -0
- package/skills/android-wear-compose-m3/references/foundation/SwipeToRevealSample.kt.md +282 -0
- package/skills/android-wear-compose-m3/references/foundation/SwipeToRevealSample.kt.md.txt +282 -0
- package/skills/android-wear-compose-m3/references/foundation/TransformingLazyColumnSample.kt.md +335 -0
- package/skills/android-wear-compose-m3/references/foundation/TransformingLazyColumnSample.kt.md.txt +335 -0
- package/skills/android-wear-compose-m3/references/material3/AlertDialogSample.kt.md +377 -0
- package/skills/android-wear-compose-m3/references/material3/AlertDialogSample.kt.md.txt +377 -0
- package/skills/android-wear-compose-m3/references/material3/AnimatedTextSample.kt.md +165 -0
- package/skills/android-wear-compose-m3/references/material3/AnimatedTextSample.kt.md.txt +165 -0
- package/skills/android-wear-compose-m3/references/material3/ButtonGroupSample.kt.md +91 -0
- package/skills/android-wear-compose-m3/references/material3/ButtonGroupSample.kt.md.txt +91 -0
- package/skills/android-wear-compose-m3/references/material3/ButtonSample.kt.md +496 -0
- package/skills/android-wear-compose-m3/references/material3/ButtonSample.kt.md.txt +496 -0
- package/skills/android-wear-compose-m3/references/material3/CardSample.kt.md +470 -0
- package/skills/android-wear-compose-m3/references/material3/CardSample.kt.md.txt +470 -0
- package/skills/android-wear-compose-m3/references/material3/CheckboxButtonSample.kt.md +67 -0
- package/skills/android-wear-compose-m3/references/material3/CheckboxButtonSample.kt.md.txt +67 -0
- package/skills/android-wear-compose-m3/references/material3/ConfirmationDialogSample.kt.md +162 -0
- package/skills/android-wear-compose-m3/references/material3/ConfirmationDialogSample.kt.md.txt +162 -0
- package/skills/android-wear-compose-m3/references/material3/CurvedTextSamples.kt.md +78 -0
- package/skills/android-wear-compose-m3/references/material3/CurvedTextSamples.kt.md.txt +78 -0
- package/skills/android-wear-compose-m3/references/material3/DatePickerSample.kt.md +131 -0
- package/skills/android-wear-compose-m3/references/material3/DatePickerSample.kt.md.txt +131 -0
- package/skills/android-wear-compose-m3/references/material3/DynamicColorSchemeSample.kt.md +74 -0
- package/skills/android-wear-compose-m3/references/material3/DynamicColorSchemeSample.kt.md.txt +74 -0
- package/skills/android-wear-compose-m3/references/material3/EdgeButtonSample.kt.md +63 -0
- package/skills/android-wear-compose-m3/references/material3/EdgeButtonSample.kt.md.txt +63 -0
- package/skills/android-wear-compose-m3/references/material3/FadingExpandingLabelSample.kt.md +60 -0
- package/skills/android-wear-compose-m3/references/material3/FadingExpandingLabelSample.kt.md.txt +60 -0
- package/skills/android-wear-compose-m3/references/material3/IconButtonSample.kt.md +125 -0
- package/skills/android-wear-compose-m3/references/material3/IconButtonSample.kt.md.txt +125 -0
- package/skills/android-wear-compose-m3/references/material3/IconToggleButtonSample.kt.md +116 -0
- package/skills/android-wear-compose-m3/references/material3/IconToggleButtonSample.kt.md.txt +116 -0
- package/skills/android-wear-compose-m3/references/material3/LevelIndicatorSample.kt.md +68 -0
- package/skills/android-wear-compose-m3/references/material3/LevelIndicatorSample.kt.md.txt +68 -0
- package/skills/android-wear-compose-m3/references/material3/LinearProgressIndicatorSample.kt.md +50 -0
- package/skills/android-wear-compose-m3/references/material3/LinearProgressIndicatorSample.kt.md.txt +50 -0
- package/skills/android-wear-compose-m3/references/material3/ListHeaderSample.kt.md +177 -0
- package/skills/android-wear-compose-m3/references/material3/ListHeaderSample.kt.md.txt +177 -0
- package/skills/android-wear-compose-m3/references/material3/OneHandedGestureSamples.kt.md +651 -0
- package/skills/android-wear-compose-m3/references/material3/OneHandedGestureSamples.kt.md.txt +651 -0
- package/skills/android-wear-compose-m3/references/material3/OpenOnPhoneDialogSample.kt.md +57 -0
- package/skills/android-wear-compose-m3/references/material3/OpenOnPhoneDialogSample.kt.md.txt +57 -0
- package/skills/android-wear-compose-m3/references/material3/PageIndicatorSample.kt.md +110 -0
- package/skills/android-wear-compose-m3/references/material3/PageIndicatorSample.kt.md.txt +110 -0
- package/skills/android-wear-compose-m3/references/material3/PagerScaffoldSample.kt.md +204 -0
- package/skills/android-wear-compose-m3/references/material3/PagerScaffoldSample.kt.md.txt +204 -0
- package/skills/android-wear-compose-m3/references/material3/PickerGroupSample.kt.md +139 -0
- package/skills/android-wear-compose-m3/references/material3/PickerGroupSample.kt.md.txt +139 -0
- package/skills/android-wear-compose-m3/references/material3/PickerSample.kt.md +111 -0
- package/skills/android-wear-compose-m3/references/material3/PickerSample.kt.md.txt +111 -0
- package/skills/android-wear-compose-m3/references/material3/PlaceholderSample.kt.md +184 -0
- package/skills/android-wear-compose-m3/references/material3/PlaceholderSample.kt.md.txt +184 -0
- package/skills/android-wear-compose-m3/references/material3/ProgressIndicatorSample.kt.md +263 -0
- package/skills/android-wear-compose-m3/references/material3/ProgressIndicatorSample.kt.md.txt +263 -0
- package/skills/android-wear-compose-m3/references/material3/RadioButtonSample.kt.md +105 -0
- package/skills/android-wear-compose-m3/references/material3/RadioButtonSample.kt.md.txt +105 -0
- package/skills/android-wear-compose-m3/references/material3/ScaffoldSample.kt.md +146 -0
- package/skills/android-wear-compose-m3/references/material3/ScaffoldSample.kt.md.txt +146 -0
- package/skills/android-wear-compose-m3/references/material3/ScrollAwaySample.kt.md +97 -0
- package/skills/android-wear-compose-m3/references/material3/ScrollAwaySample.kt.md.txt +97 -0
- package/skills/android-wear-compose-m3/references/material3/ScrollIndicatorSample.kt.md +66 -0
- package/skills/android-wear-compose-m3/references/material3/ScrollIndicatorSample.kt.md.txt +66 -0
- package/skills/android-wear-compose-m3/references/material3/SliderSample.kt.md +86 -0
- package/skills/android-wear-compose-m3/references/material3/SliderSample.kt.md.txt +86 -0
- package/skills/android-wear-compose-m3/references/material3/StepperSample.kt.md +148 -0
- package/skills/android-wear-compose-m3/references/material3/StepperSample.kt.md.txt +148 -0
- package/skills/android-wear-compose-m3/references/material3/SurfaceTransformationSample.kt.md +166 -0
- package/skills/android-wear-compose-m3/references/material3/SurfaceTransformationSample.kt.md.txt +166 -0
- package/skills/android-wear-compose-m3/references/material3/SwipeToDismissBoxSample.kt.md +172 -0
- package/skills/android-wear-compose-m3/references/material3/SwipeToDismissBoxSample.kt.md.txt +172 -0
- package/skills/android-wear-compose-m3/references/material3/SwipeToRevealSample.kt.md +367 -0
- package/skills/android-wear-compose-m3/references/material3/SwipeToRevealSample.kt.md.txt +367 -0
- package/skills/android-wear-compose-m3/references/material3/SwitchButtonSample.kt.md +66 -0
- package/skills/android-wear-compose-m3/references/material3/SwitchButtonSample.kt.md.txt +66 -0
- package/skills/android-wear-compose-m3/references/material3/TextButtonSample.kt.md +115 -0
- package/skills/android-wear-compose-m3/references/material3/TextButtonSample.kt.md.txt +115 -0
- package/skills/android-wear-compose-m3/references/material3/TextToggleButtonSample.kt.md +71 -0
- package/skills/android-wear-compose-m3/references/material3/TextToggleButtonSample.kt.md.txt +71 -0
- package/skills/android-wear-compose-m3/references/material3/TimePickerSample.kt.md +151 -0
- package/skills/android-wear-compose-m3/references/material3/TimePickerSample.kt.md.txt +151 -0
- package/skills/android-wear-compose-m3/references/material3/TimeTextSample.kt.md +65 -0
- package/skills/android-wear-compose-m3/references/material3/TimeTextSample.kt.md.txt +65 -0
- package/skills/android-wear-compose-m3/references/material3/TransformationSpecSample.kt.md +246 -0
- package/skills/android-wear-compose-m3/references/material3/TransformationSpecSample.kt.md.txt +246 -0
- package/skills/android-wear-compose-m3/references/material3/TransformingLazyColumnNotificationsSample.kt.md +89 -0
- package/skills/android-wear-compose-m3/references/material3/TransformingLazyColumnNotificationsSample.kt.md.txt +89 -0
- package/skills/android-wear-compose-m3/references/material3/TransformingLazyColumnSample.kt.md +309 -0
- package/skills/android-wear-compose-m3/references/material3/TransformingLazyColumnSample.kt.md.txt +309 -0
- package/skills/android-wear-compose-m3/references/navigation3/SwipeDismissableSceneStrategySample.kt.md +205 -0
- package/skills/android-wear-compose-m3/references/navigation3/SwipeDismissableSceneStrategySample.kt.md.txt +205 -0
- package/skills/{architecture-feature-first → flutter-architecture-feature-first}/SKILL.md +1 -1
- package/skills/{bloc → flutter-bloc}/SKILL.md +1 -1
- package/skills/flutter-build-debug/SKILL.md +66 -0
- package/skills/{code-review → flutter-code-review}/SKILL.md +1 -1
- package/skills/{dart-3-updates → flutter-dart-3-updates}/SKILL.md +1 -1
- package/skills/{dart-fix-runtime-errors → flutter-dart-fix-runtime-errors}/SKILL.md +1 -1
- package/skills/{dart-resolve-package-conflicts → flutter-dart-resolve-package-conflicts}/SKILL.md +1 -1
- package/skills/{dart-run-static-analysis → flutter-dart-run-static-analysis}/SKILL.md +1 -1
- package/skills/{dart-use-pattern-matching → flutter-dart-use-pattern-matching}/SKILL.md +1 -1
- package/skills/{effective-dart → flutter-effective-dart}/SKILL.md +1 -1
- package/skills/{provider → flutter-provider}/SKILL.md +1 -1
- package/skills/{riverpod → flutter-riverpod}/SKILL.md +1 -1
- package/skills/ios-cocoapods-debug/SKILL.md +65 -0
- package/skills/ios-code-review/SKILL.md +56 -0
- package/skills/ios-xcode-build-debug/SKILL.md +66 -0
- package/skills/{detect-mobile-stack → mobile-detect-stack}/SKILL.md +1 -1
- package/skills/mobile-firebase/SKILL.md +54 -0
- package/skills/mobile-firebase/references/android/ai-logic.md +31 -0
- package/skills/mobile-firebase/references/android/analytics.md +33 -0
- package/skills/mobile-firebase/references/android/app-check.md +36 -0
- package/skills/mobile-firebase/references/android/auth.md +44 -0
- package/skills/mobile-firebase/references/android/crashlytics.md +31 -0
- package/skills/mobile-firebase/references/android/firestore.md +44 -0
- package/skills/mobile-firebase/references/android/functions.md +33 -0
- package/skills/mobile-firebase/references/android/in-app-messaging.md +28 -0
- package/skills/mobile-firebase/references/android/messaging.md +41 -0
- package/skills/mobile-firebase/references/android/realtime-database.md +50 -0
- package/skills/mobile-firebase/references/android/remote-config.md +43 -0
- package/skills/mobile-firebase/references/android/sql-connect.md +31 -0
- package/skills/mobile-firebase/references/android/storage.md +39 -0
- package/skills/mobile-firebase/references/android.md +30 -0
- package/skills/{firebase-ai/SKILL.md → mobile-firebase/references/flutter/ai-logic.md} +2 -8
- package/skills/{firebase-analytics/SKILL.md → mobile-firebase/references/flutter/analytics.md} +2 -8
- package/skills/{firebase-app-check/SKILL.md → mobile-firebase/references/flutter/app-check.md} +2 -8
- package/skills/{firebase-auth/SKILL.md → mobile-firebase/references/flutter/auth.md} +2 -8
- package/skills/{firebase-crashlytics/SKILL.md → mobile-firebase/references/flutter/crashlytics.md} +2 -8
- package/skills/{firebase-cloud-firestore/SKILL.md → mobile-firebase/references/flutter/firestore.md} +2 -8
- package/skills/{firebase-cloud-functions/SKILL.md → mobile-firebase/references/flutter/functions.md} +2 -8
- package/skills/{firebase-in-app-messaging/SKILL.md → mobile-firebase/references/flutter/in-app-messaging.md} +2 -8
- package/skills/{firebase-messaging/SKILL.md → mobile-firebase/references/flutter/messaging.md} +2 -8
- package/skills/{firebase-database/SKILL.md → mobile-firebase/references/flutter/realtime-database.md} +2 -8
- package/skills/{firebase-remote-config/SKILL.md → mobile-firebase/references/flutter/remote-config.md} +2 -8
- package/skills/{flutterfire-configure/SKILL.md → mobile-firebase/references/flutter/setup-flutterfire.md} +1 -8
- package/skills/{firebase-data-connect/SKILL.md → mobile-firebase/references/flutter/sql-connect.md} +2 -8
- package/skills/{firebase-storage/SKILL.md → mobile-firebase/references/flutter/storage.md} +2 -8
- package/skills/mobile-firebase/references/flutter.md +36 -0
- package/skills/mobile-firebase/references/ios/ai-logic.md +30 -0
- package/skills/mobile-firebase/references/ios/analytics.md +33 -0
- package/skills/mobile-firebase/references/ios/app-check.md +36 -0
- package/skills/mobile-firebase/references/ios/auth.md +48 -0
- package/skills/mobile-firebase/references/ios/crashlytics.md +34 -0
- package/skills/mobile-firebase/references/ios/firestore.md +53 -0
- package/skills/mobile-firebase/references/ios/functions.md +35 -0
- package/skills/mobile-firebase/references/ios/in-app-messaging.md +26 -0
- package/skills/mobile-firebase/references/ios/messaging.md +45 -0
- package/skills/mobile-firebase/references/ios/realtime-database.md +49 -0
- package/skills/mobile-firebase/references/ios/remote-config.md +44 -0
- package/skills/mobile-firebase/references/ios/sql-connect.md +33 -0
- package/skills/mobile-firebase/references/ios/storage.md +36 -0
- package/skills/mobile-firebase/references/ios.md +28 -0
- package/skills/mobile-firebase/references/react-native/ai-logic.md +32 -0
- package/skills/mobile-firebase/references/react-native/analytics.md +43 -0
- package/skills/mobile-firebase/references/react-native/app-check.md +35 -0
- package/skills/mobile-firebase/references/react-native/auth.md +50 -0
- package/skills/mobile-firebase/references/react-native/crashlytics.md +36 -0
- package/skills/mobile-firebase/references/react-native/firestore.md +45 -0
- package/skills/mobile-firebase/references/react-native/functions.md +28 -0
- package/skills/mobile-firebase/references/react-native/in-app-messaging.md +27 -0
- package/skills/mobile-firebase/references/react-native/messaging.md +46 -0
- package/skills/mobile-firebase/references/react-native/realtime-database.md +46 -0
- package/skills/mobile-firebase/references/react-native/remote-config.md +32 -0
- package/skills/mobile-firebase/references/react-native/sql-connect.md +11 -0
- package/skills/mobile-firebase/references/react-native/storage.md +30 -0
- package/skills/mobile-firebase/references/react-native.md +29 -0
- package/skills/mobile-test/SKILL.md +63 -0
- package/skills/mobile-test/references/android/setup/GUIDE.md +183 -0
- package/skills/mobile-test/references/android/setup/references/android/develop/ui/compose/testing/common-patterns.md +181 -0
- package/skills/mobile-test/references/android/setup/references/android/studio/preview/compose-screenshot-testing.md +255 -0
- package/skills/mobile-test/references/android/setup/references/android/training/dependency-injection/hilt-testing.md +447 -0
- package/skills/mobile-test/references/android.md +83 -0
- package/skills/{dart-collect-coverage/SKILL.md → mobile-test/references/flutter/coverage.md} +2 -11
- package/skills/{dart-generate-test-mocks/SKILL.md → mobile-test/references/flutter/generate-mocks.md} +2 -11
- package/skills/{flutter-add-integration-test/SKILL.md → mobile-test/references/flutter/integration-tests.md} +2 -11
- package/skills/{dart-migrate-to-checks-package/SKILL.md → mobile-test/references/flutter/migrate-to-checks.md} +2 -13
- package/skills/{mockito/SKILL.md → mobile-test/references/flutter/mockito.md} +1 -8
- package/skills/{mocktail/SKILL.md → mobile-test/references/flutter/mocktail.md} +1 -8
- package/skills/{patrol-e2e-testing/SKILL.md → mobile-test/references/flutter/patrol.md} +1 -8
- package/skills/{testing/SKILL.md → mobile-test/references/flutter/testing-guidelines.md} +1 -8
- package/skills/{dart-add-unit-test/SKILL.md → mobile-test/references/flutter/unit-tests.md} +2 -11
- package/skills/{flutter-add-widget-test/SKILL.md → mobile-test/references/flutter/widget-tests.md} +2 -11
- package/skills/mobile-test/references/flutter.md +44 -0
- package/skills/mobile-test/references/ios.md +79 -0
- package/skills/mobile-test/references/react-native.md +62 -0
- /package/skills/{dart-use-pattern-matching → flutter-dart-use-pattern-matching}/examples/json_patterns.dart +0 -0
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# Returning a Result (State-Based)
|
|
2
|
+
|
|
3
|
+
This recipe demonstrates how to return a result from one screen to a previous screen using a state-based approach.
|
|
4
|
+
|
|
5
|
+
## How it works
|
|
6
|
+
|
|
7
|
+
This example uses a `ResultEventBus` to manage the result as state.
|
|
8
|
+
|
|
9
|
+
1. **ResultEventBusNavEntryDecorator** : A `NavEntryDecorator` that provides a `ResultEventBus` via `LocalResultEventBus`.
|
|
10
|
+
2. **`ResultEventBus`** : A `ResultEventBus` is created and made available to the composables via `LocalResultEventBus`. This EventBus sends and receives the results.
|
|
11
|
+
3. **Setting the result** : The screen that produces the result calls `resultBus.sendResult(person)` to send the data back.
|
|
12
|
+
4. **Observing the result** : The screen that needs the result calls `resultBus.conflateAsState<Person?>()` to get a `State` object representing the result. The UI then observes this state and recomposes whenever the result changes.
|
|
13
|
+
|
|
14
|
+
This approach is suitable when only the latest result is required. The result state does not survive configuration change or process death.
|
|
15
|
+
[ Explore View the full recipe on GitHub.](https://github.com/android/nav3-recipes/tree/main/app/src/main/java/com/example/nav3recipes/results/state)
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
/*
|
|
19
|
+
* Copyright 2025 The Android Open Source Project
|
|
20
|
+
*
|
|
21
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
22
|
+
* you may not use this file except in compliance with the License.
|
|
23
|
+
* You may obtain a copy of the License at
|
|
24
|
+
*
|
|
25
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
26
|
+
*
|
|
27
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
28
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
29
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
30
|
+
* See the License for the specific language governing permissions and
|
|
31
|
+
* limitations under the License.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
package com.example.nav3recipes.results.common
|
|
35
|
+
|
|
36
|
+
import androidx.compose.runtime.getValue
|
|
37
|
+
import androidx.compose.runtime.mutableStateOf
|
|
38
|
+
import androidx.compose.runtime.setValue
|
|
39
|
+
import androidx.lifecycle.ViewModel
|
|
40
|
+
|
|
41
|
+
class HomeViewModel : ViewModel() {
|
|
42
|
+
var person by mutableStateOf<Person?>(null)
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
/*
|
|
48
|
+
* Copyright 2025 The Android Open Source Project
|
|
49
|
+
*
|
|
50
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
51
|
+
* you may not use this file except in compliance with the License.
|
|
52
|
+
* You may obtain a copy of the License at
|
|
53
|
+
*
|
|
54
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
55
|
+
*
|
|
56
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
57
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
58
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
59
|
+
* See the License for the specific language governing permissions and
|
|
60
|
+
* limitations under the License.
|
|
61
|
+
*/
|
|
62
|
+
|
|
63
|
+
package com.example.nav3recipes.results.common
|
|
64
|
+
|
|
65
|
+
import androidx.navigation3.runtime.NavKey
|
|
66
|
+
import kotlinx.serialization.Serializable
|
|
67
|
+
|
|
68
|
+
@Serializable
|
|
69
|
+
data object Home : NavKey
|
|
70
|
+
|
|
71
|
+
@Serializable
|
|
72
|
+
class PersonDetailsForm : NavKey
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
/*
|
|
77
|
+
* Copyright 2025 The Android Open Source Project
|
|
78
|
+
*
|
|
79
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
80
|
+
* you may not use this file except in compliance with the License.
|
|
81
|
+
* You may obtain a copy of the License at
|
|
82
|
+
*
|
|
83
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
84
|
+
*
|
|
85
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
86
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
87
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
88
|
+
* See the License for the specific language governing permissions and
|
|
89
|
+
* limitations under the License.
|
|
90
|
+
*/
|
|
91
|
+
|
|
92
|
+
package com.example.nav3recipes.results.common
|
|
93
|
+
|
|
94
|
+
import kotlinx.serialization.Serializable
|
|
95
|
+
|
|
96
|
+
@Serializable
|
|
97
|
+
data class Person(val name: String, val favoriteColor: String)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
/*
|
|
102
|
+
* Copyright 2025 The Android Open Source Project
|
|
103
|
+
*
|
|
104
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
105
|
+
* you may not use this file except in compliance with the License.
|
|
106
|
+
* You may obtain a copy of the License at
|
|
107
|
+
*
|
|
108
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
109
|
+
*
|
|
110
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
111
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
112
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
113
|
+
* See the License for the specific language governing permissions and
|
|
114
|
+
* limitations under the License.
|
|
115
|
+
*/
|
|
116
|
+
|
|
117
|
+
package com.example.nav3recipes.results.common
|
|
118
|
+
|
|
119
|
+
import androidx.compose.foundation.layout.Spacer
|
|
120
|
+
import androidx.compose.foundation.layout.height
|
|
121
|
+
import androidx.compose.foundation.text.input.rememberTextFieldState
|
|
122
|
+
import androidx.compose.material3.Button
|
|
123
|
+
import androidx.compose.material3.OutlinedTextField
|
|
124
|
+
import androidx.compose.material3.Text
|
|
125
|
+
import androidx.compose.runtime.Composable
|
|
126
|
+
import androidx.compose.ui.Modifier
|
|
127
|
+
import androidx.compose.ui.unit.dp
|
|
128
|
+
import androidx.lifecycle.compose.dropUnlessResumed
|
|
129
|
+
import com.example.nav3recipes.content.ContentBlue
|
|
130
|
+
import com.example.nav3recipes.content.ContentGreen
|
|
131
|
+
|
|
132
|
+
@Composable
|
|
133
|
+
fun HomeScreen(
|
|
134
|
+
person: Person?,
|
|
135
|
+
onNext: () -> Unit
|
|
136
|
+
) {
|
|
137
|
+
ContentBlue("Hello ${person?.name ?: "unknown person"}") {
|
|
138
|
+
|
|
139
|
+
if (person != null) {
|
|
140
|
+
Text("Your favorite color is ${person.favoriteColor}")
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
Spacer(Modifier.height(16.dp))
|
|
144
|
+
Button(onClick = dropUnlessResumed(block = onNext)) {
|
|
145
|
+
Text("Tell us about yourself")
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@Composable
|
|
151
|
+
fun PersonDetailsScreen(
|
|
152
|
+
onSubmit: (Person) -> Unit
|
|
153
|
+
) {
|
|
154
|
+
ContentGreen("About you") {
|
|
155
|
+
|
|
156
|
+
val nameTextState = rememberTextFieldState()
|
|
157
|
+
OutlinedTextField(
|
|
158
|
+
state = nameTextState,
|
|
159
|
+
label = { Text("Please enter your name") }
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
val favoriteColorTextState = rememberTextFieldState()
|
|
163
|
+
OutlinedTextField(
|
|
164
|
+
state = favoriteColorTextState,
|
|
165
|
+
label = { Text("Please enter your favorite color") }
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
Button(
|
|
169
|
+
onClick = dropUnlessResumed {
|
|
170
|
+
val person = Person(
|
|
171
|
+
name = nameTextState.text.toString(),
|
|
172
|
+
favoriteColor = favoriteColorTextState.text.toString()
|
|
173
|
+
)
|
|
174
|
+
onSubmit(person)
|
|
175
|
+
},
|
|
176
|
+
enabled = nameTextState.text.isNotBlank() &&
|
|
177
|
+
favoriteColorTextState.text.isNotBlank()
|
|
178
|
+
) {
|
|
179
|
+
Text("Submit")
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
/*
|
|
187
|
+
* Copyright 2025 The Android Open Source Project
|
|
188
|
+
*
|
|
189
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
190
|
+
* you may not use this file except in compliance with the License.
|
|
191
|
+
* You may obtain a copy of the License at
|
|
192
|
+
*
|
|
193
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
194
|
+
*
|
|
195
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
196
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
197
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
198
|
+
* See the License for the specific language governing permissions and
|
|
199
|
+
* limitations under the License.
|
|
200
|
+
*/
|
|
201
|
+
|
|
202
|
+
package com.example.nav3recipes.results.state
|
|
203
|
+
|
|
204
|
+
import android.os.Bundle
|
|
205
|
+
import androidx.activity.ComponentActivity
|
|
206
|
+
import androidx.activity.compose.setContent
|
|
207
|
+
import androidx.compose.foundation.layout.padding
|
|
208
|
+
import androidx.compose.material3.Scaffold
|
|
209
|
+
import androidx.compose.ui.Modifier
|
|
210
|
+
import androidx.navigation3.runtime.entryProvider
|
|
211
|
+
import androidx.navigation3.runtime.rememberNavBackStack
|
|
212
|
+
import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator
|
|
213
|
+
import androidx.navigation3.runtime.result.LocalResultEventBus
|
|
214
|
+
import androidx.navigation3.runtime.result.rememberResultEventBusNavEntryDecorator
|
|
215
|
+
import androidx.navigation3.ui.NavDisplay
|
|
216
|
+
import com.example.nav3recipes.results.common.Home
|
|
217
|
+
import com.example.nav3recipes.results.common.HomeScreen
|
|
218
|
+
import com.example.nav3recipes.results.common.Person
|
|
219
|
+
import com.example.nav3recipes.results.common.PersonDetailsForm
|
|
220
|
+
import com.example.nav3recipes.results.common.PersonDetailsScreen
|
|
221
|
+
import com.example.nav3recipes.ui.setEdgeToEdgeConfig
|
|
222
|
+
|
|
223
|
+
class ResultStateActivity : ComponentActivity() {
|
|
224
|
+
|
|
225
|
+
override fun onCreate(savedInstanceState: Bundle?) {
|
|
226
|
+
setEdgeToEdgeConfig()
|
|
227
|
+
super.onCreate(savedInstanceState)
|
|
228
|
+
|
|
229
|
+
setContent {
|
|
230
|
+
Scaffold { paddingValues ->
|
|
231
|
+
val backStack = rememberNavBackStack(Home)
|
|
232
|
+
NavDisplay(
|
|
233
|
+
backStack = backStack,
|
|
234
|
+
modifier = Modifier.padding(paddingValues),
|
|
235
|
+
onBack = { backStack.removeLastOrNull() },
|
|
236
|
+
entryDecorators = listOf(
|
|
237
|
+
rememberSaveableStateHolderNavEntryDecorator(),
|
|
238
|
+
rememberResultEventBusNavEntryDecorator()
|
|
239
|
+
),
|
|
240
|
+
entryProvider = entryProvider {
|
|
241
|
+
entry<Home> {
|
|
242
|
+
val resultState = LocalResultEventBus
|
|
243
|
+
.current
|
|
244
|
+
.conflateAsState<Person?>(null)
|
|
245
|
+
val person = resultState.value
|
|
246
|
+
HomeScreen(
|
|
247
|
+
person = person,
|
|
248
|
+
onNext = { backStack.add(PersonDetailsForm()) }
|
|
249
|
+
)
|
|
250
|
+
}
|
|
251
|
+
entry<PersonDetailsForm> {
|
|
252
|
+
val resultBus = LocalResultEventBus.current
|
|
253
|
+
PersonDetailsScreen(
|
|
254
|
+
onSubmit = { person ->
|
|
255
|
+
resultBus.sendResult(result = person)
|
|
256
|
+
backStack.removeLastOrNull()
|
|
257
|
+
}
|
|
258
|
+
)
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
)
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
```
|
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
# List-Detail Scene Recipe
|
|
2
|
+
|
|
3
|
+
This example shows how to create a list-detail layout using the Scenes API.
|
|
4
|
+
|
|
5
|
+
A `ListDetailSceneStrategy` will return a `ListDetailScene` if:
|
|
6
|
+
|
|
7
|
+
- the window width is over 600dp
|
|
8
|
+
- A `Detail` entry is the last item in the back stack
|
|
9
|
+
- A `List` entry is in the back stack
|
|
10
|
+
|
|
11
|
+
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.
|
|
12
|
+
|
|
13
|
+
See `ListDetailScene.kt` for more implementation details.
|
|
14
|
+
[ Explore View the full recipe on GitHub.](https://github.com/android/nav3-recipes/tree/main/app/src/main/java/com/example/nav3recipes/scenes/listdetail)
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
/*
|
|
18
|
+
* Copyright 2025 The Android Open Source Project
|
|
19
|
+
*
|
|
20
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
21
|
+
* you may not use this file except in compliance with the License.
|
|
22
|
+
* You may obtain a copy of the License at
|
|
23
|
+
*
|
|
24
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
25
|
+
*
|
|
26
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
27
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
28
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
29
|
+
* See the License for the specific language governing permissions and
|
|
30
|
+
* limitations under the License.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
package com.example.nav3recipes.scenes.listdetail
|
|
34
|
+
|
|
35
|
+
import androidx.compose.animation.AnimatedContent
|
|
36
|
+
import androidx.compose.animation.slideInHorizontally
|
|
37
|
+
import androidx.compose.animation.slideOutHorizontally
|
|
38
|
+
import androidx.compose.animation.togetherWith
|
|
39
|
+
import androidx.compose.foundation.layout.Column
|
|
40
|
+
import androidx.compose.foundation.layout.Row
|
|
41
|
+
import androidx.compose.foundation.layout.fillMaxSize
|
|
42
|
+
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfoV2
|
|
43
|
+
import androidx.compose.runtime.Composable
|
|
44
|
+
import androidx.compose.runtime.CompositionLocalProvider
|
|
45
|
+
import androidx.compose.runtime.compositionLocalOf
|
|
46
|
+
import androidx.compose.runtime.remember
|
|
47
|
+
import androidx.compose.ui.Modifier
|
|
48
|
+
import androidx.navigation3.runtime.NavEntry
|
|
49
|
+
import androidx.navigation3.runtime.NavMetadataKey
|
|
50
|
+
import androidx.navigation3.runtime.contains
|
|
51
|
+
import androidx.navigation3.runtime.metadata
|
|
52
|
+
import androidx.navigation3.scene.Scene
|
|
53
|
+
import androidx.navigation3.scene.SceneStrategy
|
|
54
|
+
import androidx.navigation3.scene.SceneStrategyScope
|
|
55
|
+
import androidx.window.core.layout.WindowSizeClass
|
|
56
|
+
import androidx.window.core.layout.WindowSizeClass.Companion.WIDTH_DP_MEDIUM_LOWER_BOUND
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* A [Scene] that displays a list and a detail [NavEntry] side-by-side in a 40/60 split.
|
|
60
|
+
*
|
|
61
|
+
*/
|
|
62
|
+
data class ListDetailScene<T : Any>(
|
|
63
|
+
override val key: Any,
|
|
64
|
+
override val previousEntries: List<NavEntry<T>>,
|
|
65
|
+
val listEntry: NavEntry<T>,
|
|
66
|
+
val detailEntry: NavEntry<T>,
|
|
67
|
+
) : Scene<T> {
|
|
68
|
+
override val entries: List<NavEntry<T>> = listOf(listEntry, detailEntry)
|
|
69
|
+
override val content: @Composable (() -> Unit) = {
|
|
70
|
+
Row(modifier = Modifier.fillMaxSize()) {
|
|
71
|
+
Column(modifier = Modifier.weight(0.4f)) {
|
|
72
|
+
listEntry.Content()
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Let the detail entry know not to display a back button.
|
|
76
|
+
CompositionLocalProvider(LocalBackButtonVisibility provides false) {
|
|
77
|
+
Column(modifier = Modifier.weight(0.6f)) {
|
|
78
|
+
AnimatedContent(
|
|
79
|
+
targetState = detailEntry,
|
|
80
|
+
contentKey = { entry -> entry.contentKey },
|
|
81
|
+
transitionSpec = {
|
|
82
|
+
slideInHorizontally(
|
|
83
|
+
initialOffsetX = { it }
|
|
84
|
+
) togetherWith
|
|
85
|
+
slideOutHorizontally(targetOffsetX = { -it })
|
|
86
|
+
}
|
|
87
|
+
) { entry ->
|
|
88
|
+
entry.Content()
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
companion object {
|
|
96
|
+
/**
|
|
97
|
+
* Helper function to add metadata to a [NavEntry] indicating it can be displayed
|
|
98
|
+
* in the list pane of a [ListDetailScene].
|
|
99
|
+
*/
|
|
100
|
+
fun listPane() = metadata {
|
|
101
|
+
put(ListKey, true)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Helper function to add metadata to a [NavEntry] indicating it can be displayed
|
|
106
|
+
* in the detail pane of a the [ListDetailScene].
|
|
107
|
+
*/
|
|
108
|
+
fun detailPane() = metadata {
|
|
109
|
+
put(DetailKey, true)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
object ListKey : NavMetadataKey<Boolean>
|
|
114
|
+
object DetailKey : NavMetadataKey<Boolean>
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* This `CompositionLocal` can be used by a detail `NavEntry` to decide whether to display
|
|
119
|
+
* a back button. Default is `true`. It is set to `false` for a detail `NavEntry` when being
|
|
120
|
+
* displayed in a `ListDetailScene`.
|
|
121
|
+
*/
|
|
122
|
+
val LocalBackButtonVisibility = compositionLocalOf { true }
|
|
123
|
+
|
|
124
|
+
@Composable
|
|
125
|
+
fun <T : Any> rememberListDetailSceneStrategy(): ListDetailSceneStrategy<T> {
|
|
126
|
+
val windowSizeClass = currentWindowAdaptiveInfoV2().windowSizeClass
|
|
127
|
+
|
|
128
|
+
return remember(windowSizeClass) {
|
|
129
|
+
ListDetailSceneStrategy(windowSizeClass)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* A [SceneStrategy] that returns a [ListDetailScene] if:
|
|
136
|
+
*
|
|
137
|
+
* - the window width is over 600dp
|
|
138
|
+
* - A `Detail` entry is the last item in the back stack
|
|
139
|
+
* - A `List` entry is in the back stack
|
|
140
|
+
*
|
|
141
|
+
* Notably, when the detail entry changes the scene's key does not change. This allows the scene,
|
|
142
|
+
* rather than the NavDisplay, to handle animations when the detail entry changes.
|
|
143
|
+
*/
|
|
144
|
+
class ListDetailSceneStrategy<T : Any>(val windowSizeClass: WindowSizeClass) : SceneStrategy<T> {
|
|
145
|
+
|
|
146
|
+
override fun SceneStrategyScope<T>.calculateScene(entries: List<NavEntry<T>>): Scene<T>? {
|
|
147
|
+
|
|
148
|
+
if (!windowSizeClass.isWidthAtLeastBreakpoint(WIDTH_DP_MEDIUM_LOWER_BOUND)) {
|
|
149
|
+
return null
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
val detailEntry =
|
|
153
|
+
entries.lastOrNull()?.takeIf { it.metadata.contains(ListDetailScene.DetailKey) }
|
|
154
|
+
?: return null
|
|
155
|
+
val listEntry =
|
|
156
|
+
entries.findLast { it.metadata.contains(ListDetailScene.ListKey) } ?: return null
|
|
157
|
+
|
|
158
|
+
// We use the list's contentKey to uniquely identify the scene.
|
|
159
|
+
// This allows the detail panes to be animated in and out by the scene, rather than
|
|
160
|
+
// having NavDisplay animate the whole scene out when the selected detail item changes.
|
|
161
|
+
val sceneKey = listEntry.contentKey
|
|
162
|
+
|
|
163
|
+
return ListDetailScene(
|
|
164
|
+
key = sceneKey,
|
|
165
|
+
previousEntries = entries.dropLast(1),
|
|
166
|
+
listEntry = listEntry,
|
|
167
|
+
detailEntry = detailEntry
|
|
168
|
+
)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
/*
|
|
175
|
+
* Copyright 2025 The Android Open Source Project
|
|
176
|
+
*
|
|
177
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
178
|
+
* you may not use this file except in compliance with the License.
|
|
179
|
+
* You may obtain a copy of the License at
|
|
180
|
+
*
|
|
181
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
182
|
+
*
|
|
183
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
184
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
185
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
186
|
+
* See the License for the specific language governing permissions and
|
|
187
|
+
* limitations under the License.
|
|
188
|
+
*/
|
|
189
|
+
|
|
190
|
+
package com.example.nav3recipes.scenes.listdetail
|
|
191
|
+
|
|
192
|
+
import android.os.Bundle
|
|
193
|
+
import androidx.activity.ComponentActivity
|
|
194
|
+
import androidx.activity.compose.setContent
|
|
195
|
+
import androidx.compose.animation.ExperimentalSharedTransitionApi
|
|
196
|
+
import androidx.compose.animation.SharedTransitionLayout
|
|
197
|
+
import androidx.compose.foundation.layout.padding
|
|
198
|
+
import androidx.compose.material3.Scaffold
|
|
199
|
+
import androidx.compose.ui.Modifier
|
|
200
|
+
import androidx.navigation3.runtime.NavBackStack
|
|
201
|
+
import androidx.navigation3.runtime.NavKey
|
|
202
|
+
import androidx.navigation3.runtime.entryProvider
|
|
203
|
+
import androidx.navigation3.runtime.rememberNavBackStack
|
|
204
|
+
import androidx.navigation3.ui.NavDisplay
|
|
205
|
+
import com.example.nav3recipes.ui.setEdgeToEdgeConfig
|
|
206
|
+
import kotlinx.serialization.Serializable
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* This example shows how to create a list-detail layout using the Scenes API.
|
|
210
|
+
*
|
|
211
|
+
* A `ListDetailScene` will render content in two panes if:
|
|
212
|
+
*
|
|
213
|
+
* - the window width is over 600dp
|
|
214
|
+
* - A `Detail` entry is the last item in the back stack
|
|
215
|
+
* - A `List` entry is in the back stack
|
|
216
|
+
*
|
|
217
|
+
* @see `ListDetailScene`
|
|
218
|
+
*/
|
|
219
|
+
@Serializable
|
|
220
|
+
data object ConversationList : NavKey
|
|
221
|
+
|
|
222
|
+
@Serializable
|
|
223
|
+
data class ConversationDetail(
|
|
224
|
+
val id: Int,
|
|
225
|
+
val colorId: Int
|
|
226
|
+
) : NavKey
|
|
227
|
+
|
|
228
|
+
@Serializable
|
|
229
|
+
data object Profile : NavKey
|
|
230
|
+
|
|
231
|
+
class ListDetailActivity : ComponentActivity() {
|
|
232
|
+
|
|
233
|
+
@OptIn(ExperimentalSharedTransitionApi::class)
|
|
234
|
+
override fun onCreate(savedInstanceState: Bundle?) {
|
|
235
|
+
setEdgeToEdgeConfig()
|
|
236
|
+
super.onCreate(savedInstanceState)
|
|
237
|
+
|
|
238
|
+
setContent {
|
|
239
|
+
|
|
240
|
+
Scaffold { paddingValues ->
|
|
241
|
+
|
|
242
|
+
val backStack = rememberNavBackStack(ConversationList)
|
|
243
|
+
val listDetailStrategy = rememberListDetailSceneStrategy<NavKey>()
|
|
244
|
+
|
|
245
|
+
SharedTransitionLayout {
|
|
246
|
+
NavDisplay(
|
|
247
|
+
backStack = backStack,
|
|
248
|
+
onBack = { backStack.removeLastOrNull() },
|
|
249
|
+
sceneStrategies = listOf(listDetailStrategy),
|
|
250
|
+
sharedTransitionScope = this,
|
|
251
|
+
modifier = Modifier.padding(paddingValues),
|
|
252
|
+
entryProvider = entryProvider {
|
|
253
|
+
entry<ConversationList>(
|
|
254
|
+
metadata = ListDetailScene.listPane()
|
|
255
|
+
) {
|
|
256
|
+
ConversationListScreen(
|
|
257
|
+
onConversationClicked = { detailRoute ->
|
|
258
|
+
backStack.addDetail(detailRoute)
|
|
259
|
+
}
|
|
260
|
+
)
|
|
261
|
+
}
|
|
262
|
+
entry<ConversationDetail>(
|
|
263
|
+
metadata = ListDetailScene.detailPane()
|
|
264
|
+
) { conversationDetail ->
|
|
265
|
+
ConversationDetailScreen(
|
|
266
|
+
conversationDetail = conversationDetail,
|
|
267
|
+
onBack = { backStack.removeLastOrNull() },
|
|
268
|
+
onProfileClicked = { backStack.add(Profile) }
|
|
269
|
+
)
|
|
270
|
+
}
|
|
271
|
+
entry<Profile> {
|
|
272
|
+
ProfileScreen()
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
)
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
private fun NavBackStack<NavKey>.addDetail(detailRoute: ConversationDetail) {
|
|
283
|
+
|
|
284
|
+
// Remove any existing detail routes before adding this detail route.
|
|
285
|
+
// In certain scenarios, such as when multiple detail panes can be shown at once, it may
|
|
286
|
+
// be desirable to keep existing detail routes on the back stack.
|
|
287
|
+
removeIf { it is ConversationDetail }
|
|
288
|
+
add(detailRoute)
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
```
|
|
293
|
+
/*
|
|
294
|
+
* Copyright 2025 The Android Open Source Project
|
|
295
|
+
*
|
|
296
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
297
|
+
* you may not use this file except in compliance with the License.
|
|
298
|
+
* You may obtain a copy of the License at
|
|
299
|
+
*
|
|
300
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
301
|
+
*
|
|
302
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
303
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
304
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
305
|
+
* See the License for the specific language governing permissions and
|
|
306
|
+
* limitations under the License.
|
|
307
|
+
*/
|
|
308
|
+
|
|
309
|
+
package com.example.nav3recipes.scenes.listdetail
|
|
310
|
+
|
|
311
|
+
import androidx.compose.foundation.background
|
|
312
|
+
import androidx.compose.foundation.clickable
|
|
313
|
+
import androidx.compose.foundation.layout.Arrangement
|
|
314
|
+
import androidx.compose.foundation.layout.Box
|
|
315
|
+
import androidx.compose.foundation.layout.Column
|
|
316
|
+
import androidx.compose.foundation.layout.Spacer
|
|
317
|
+
import androidx.compose.foundation.layout.fillMaxSize
|
|
318
|
+
import androidx.compose.foundation.layout.fillMaxWidth
|
|
319
|
+
import androidx.compose.foundation.layout.height
|
|
320
|
+
import androidx.compose.foundation.layout.padding
|
|
321
|
+
import androidx.compose.foundation.lazy.LazyColumn
|
|
322
|
+
import androidx.compose.material.icons.Icons
|
|
323
|
+
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
|
324
|
+
import androidx.compose.material3.Button
|
|
325
|
+
import androidx.compose.material3.Icon
|
|
326
|
+
import androidx.compose.material3.IconButton
|
|
327
|
+
import androidx.compose.material3.ListItem
|
|
328
|
+
import androidx.compose.material3.ListItemDefaults
|
|
329
|
+
import androidx.compose.material3.MaterialTheme
|
|
330
|
+
import androidx.compose.material3.Text
|
|
331
|
+
import androidx.compose.runtime.Composable
|
|
332
|
+
import androidx.compose.ui.Alignment
|
|
333
|
+
import androidx.compose.ui.Modifier
|
|
334
|
+
import androidx.compose.ui.unit.dp
|
|
335
|
+
import androidx.lifecycle.compose.dropUnlessResumed
|
|
336
|
+
import com.example.nav3recipes.ui.theme.colors
|
|
337
|
+
|
|
338
|
+
@Composable
|
|
339
|
+
fun ConversationListScreen(
|
|
340
|
+
onConversationClicked: (ConversationDetail) -> Unit
|
|
341
|
+
) {
|
|
342
|
+
LazyColumn(
|
|
343
|
+
modifier = Modifier
|
|
344
|
+
.fillMaxSize()
|
|
345
|
+
.background(MaterialTheme.colorScheme.surface),
|
|
346
|
+
) {
|
|
347
|
+
items(10) { index ->
|
|
348
|
+
val conversationId = index + 1
|
|
349
|
+
val conversationDetail = ConversationDetail(
|
|
350
|
+
id = conversationId,
|
|
351
|
+
colorId = conversationId % colors.size
|
|
352
|
+
)
|
|
353
|
+
val backgroundColor = colors[conversationDetail.colorId]
|
|
354
|
+
ListItem(
|
|
355
|
+
modifier = Modifier
|
|
356
|
+
.fillMaxWidth()
|
|
357
|
+
.clickable(onClick = dropUnlessResumed {
|
|
358
|
+
onConversationClicked(conversationDetail)
|
|
359
|
+
}),
|
|
360
|
+
headlineContent = {
|
|
361
|
+
Text(
|
|
362
|
+
text = "Conversation $conversationId",
|
|
363
|
+
style = MaterialTheme.typography.headlineSmall,
|
|
364
|
+
color = MaterialTheme.colorScheme.onSurface
|
|
365
|
+
)
|
|
366
|
+
},
|
|
367
|
+
colors = ListItemDefaults.colors(
|
|
368
|
+
containerColor = backgroundColor // Set container color directly
|
|
369
|
+
)
|
|
370
|
+
)
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
@Composable
|
|
376
|
+
fun ConversationDetailScreen(
|
|
377
|
+
conversationDetail: ConversationDetail,
|
|
378
|
+
onBack: () -> Unit,
|
|
379
|
+
onProfileClicked: () -> Unit
|
|
380
|
+
) {
|
|
381
|
+
Box(
|
|
382
|
+
modifier = Modifier
|
|
383
|
+
.fillMaxSize()
|
|
384
|
+
.background(colors[conversationDetail.colorId])
|
|
385
|
+
.padding(16.dp)
|
|
386
|
+
) {
|
|
387
|
+
if (LocalBackButtonVisibility.current) {
|
|
388
|
+
IconButton(
|
|
389
|
+
onClick = onBack,
|
|
390
|
+
modifier = Modifier.align(Alignment.TopStart)
|
|
391
|
+
) {
|
|
392
|
+
Icon(
|
|
393
|
+
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
|
|
394
|
+
contentDescription = "Back"
|
|
395
|
+
)
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
Column(
|
|
399
|
+
modifier = Modifier
|
|
400
|
+
.fillMaxSize(),
|
|
401
|
+
horizontalAlignment = Alignment.CenterHorizontally,
|
|
402
|
+
verticalArrangement = Arrangement.Center
|
|
403
|
+
) {
|
|
404
|
+
Text(
|
|
405
|
+
text = "Conversation Detail Screen: ${conversationDetail.id}",
|
|
406
|
+
style = MaterialTheme.typography.headlineMedium,
|
|
407
|
+
color = MaterialTheme.colorScheme.onSurface
|
|
408
|
+
)
|
|
409
|
+
Spacer(modifier = Modifier.height(16.dp))
|
|
410
|
+
Button(onClick = dropUnlessResumed(block = onProfileClicked)) {
|
|
411
|
+
Text("View Profile")
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
@Composable
|
|
418
|
+
fun ProfileScreen() {
|
|
419
|
+
val profileColor = MaterialTheme.colorScheme.surfaceVariant
|
|
420
|
+
Column(
|
|
421
|
+
modifier = Modifier
|
|
422
|
+
.fillMaxSize()
|
|
423
|
+
.background(profileColor)
|
|
424
|
+
.padding(16.dp),
|
|
425
|
+
horizontalAlignment = Alignment.CenterHorizontally,
|
|
426
|
+
verticalArrangement = Arrangement.Center
|
|
427
|
+
) {
|
|
428
|
+
Text(
|
|
429
|
+
text = "Profile Screen",
|
|
430
|
+
style = MaterialTheme.typography.headlineMedium,
|
|
431
|
+
color = MaterialTheme.colorScheme.onSurface
|
|
432
|
+
)
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
```
|