<!-- llms-explorer concept facts · https://llms-explorer.com/tree/compose-multiplatform-patterns/ · pack 2026-09-08 · ~2202 tokens -->

# Compose Multiplatform Patterns

> 使用 Compose Multiplatform 和 Jetpack Compose 构建跨 Android、iOS、桌面和 Web 的共享 UI 的模式。涵盖状态管理、导航、主题和性能。

Parent: [Programming Languages](https://llms-explorer.com/tree/programming-languages/) · 13 facets · 31 facts · page: https://llms-explorer.com/tree/compose-multiplatform-patterns/

## Compose 多平台模式

- 使用 Compose Multiplatform 和 Jetpack Compose 构建跨 Android、iOS、桌面和 Web 的共享 UI 的模式。涵盖状态管理、导航、主题和性能。 — [source](https://llms-explorer.com/sources/mdb-context-hub/compose-multiplatform-patterns/#compose-多平台模式)

## 何时启用

- 构建 Compose UI（Jetpack Compose 或 Compose Multiplatform） — [source](https://llms-explorer.com/sources/mdb-context-hub/compose-multiplatform-patterns/#何时启用)
- 使用 ViewModel 和 Compose 状态管理 UI 状态 — [source](https://llms-explorer.com/sources/mdb-context-hub/compose-multiplatform-patterns/#何时启用)
- 在 KMP 或 Android 项目中实现导航 — [source](https://llms-explorer.com/sources/mdb-context-hub/compose-multiplatform-patterns/#何时启用)

## ViewModel + 单一状态对象

- 使用单个数据类表示屏幕状态。将其暴露为 StateFlow 并在 Compose 中收集： — [source](https://llms-explorer.com/sources/mdb-context-hub/compose-multiplatform-patterns/#viewmodel-单一状态对象)

## 事件接收器模式

- 对于复杂屏幕，使用密封接口表示事件，而非多个回调 lambda： — [source](https://llms-explorer.com/sources/mdb-context-hub/compose-multiplatform-patterns/#事件接收器模式)

## 类型安全导航（Compose Navigation 2.8+）

- 将路由定义为 @Serializable 对象： — [source](https://llms-explorer.com/sources/mdb-context-hub/compose-multiplatform-patterns/#类型安全导航compose-navigation-28)

## 对话框和底部抽屉导航

- 使用 dialog() 和覆盖层模式，而非命令式的显示/隐藏： — [source](https://llms-explorer.com/sources/mdb-context-hub/compose-multiplatform-patterns/#对话框和底部抽屉导航)

## 用于可跳过重组的稳定类型

- 当所有属性都稳定时，将类标记为 @Stable 或 @Immutable： — [source](https://llms-explorer.com/sources/mdb-context-hub/compose-multiplatform-patterns/#用于可跳过重组的稳定类型)

## 应避免的反模式

- 在 ViewModel 中使用 mutableStateOf，而 MutableStateFlow 配合 collectAsStateWithLifecycle 对生命周期更安全 — [source](https://llms-explorer.com/sources/mdb-context-hub/compose-multiplatform-patterns/#应避免的反模式)
- 将 NavController 深入传递到可组合项中 —— 应传递 lambda 回调 — [source](https://llms-explorer.com/sources/mdb-context-hub/compose-multiplatform-patterns/#应避免的反模式)
- 在 @Composable 函数中进行繁重计算 —— 应移至 ViewModel 或 remember {} — [source](https://llms-explorer.com/sources/mdb-context-hub/compose-multiplatform-patterns/#应避免的反模式)
- 使用 LaunchedEffect(Unit) 作为 ViewModel 初始化的替代 —— 在某些设置中，它会在配置更改时重新运行 — [source](https://llms-explorer.com/sources/mdb-context-hub/compose-multiplatform-patterns/#应避免的反模式)
- 在可组合项参数中创建新的对象实例 —— 会导致不必要的重组 — [source](https://llms-explorer.com/sources/mdb-context-hub/compose-multiplatform-patterns/#应避免的反模式)

## 参考资料

- 查看技能：android-clean-architecture 了解模块结构和分层。 查看技能：kotlin-coroutines-flows 了解协程和 Flow 模式。 — [source](https://llms-explorer.com/sources/mdb-context-hub/compose-multiplatform-patterns/#参考资料)

## Where this helps

- Building a single Kotlin codebase that ships a genuinely shared UI layer across Android, iOS, desktop, and web instead of maintaining parallel native UI implementations per platform. — [source](https://llms-explorer.com/tree/compose-multiplatform-patterns/) *(AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.)*
- Migrating an existing Jetpack Compose Android app toward multiplatform without rewriting the ViewModel/state layer, since the StateFlow plus single-state-object pattern already carries over. — [source](https://llms-explorer.com/tree/compose-multiplatform-patterns/) *(AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.)*
- Screens with complex, branching UI logic where a sealed-interface event model keeps the ViewModel's public surface small and exhaustive instead of accumulating ad-hoc callback lambdas. — [source](https://llms-explorer.com/tree/compose-multiplatform-patterns/) *(AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.)*
- Apps that need type-safe deep linking and back-stack management across platforms, where @Serializable route objects replace error-prone string-based navigation arguments. — [source](https://llms-explorer.com/tree/compose-multiplatform-patterns/) *(AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.)*

## Project ideas

- Build a small cross-platform note-taking or task app that shares its entire UI and ViewModel layer between Android and desktop, using a single state data class exposed as StateFlow. — [source](https://llms-explorer.com/tree/compose-multiplatform-patterns/) *(AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.)*
- Refactor an existing screen's navigation from string-route Compose Navigation to typed @Serializable route objects, and measure how many argument-parsing bugs it eliminates. — [source](https://llms-explorer.com/tree/compose-multiplatform-patterns/) *(AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.)*
- Prototype a dialog and bottom-sheet navigation layer using the dialog() plus overlay pattern instead of imperative show/hide booleans, and compare state-restoration behavior across configuration changes. — [source](https://llms-explorer.com/tree/compose-multiplatform-patterns/) *(AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.)*
- Add @Stable and @Immutable annotations to a screen's model types and use recomposition counts to verify skippable recomposition actually improved. — [source](https://llms-explorer.com/tree/compose-multiplatform-patterns/) *(AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.)*

## Common mistakes

- Deep-passing a NavController into child composables instead of passing lambda callbacks, which couples reusable composables to a specific navigation graph. — [source](https://llms-explorer.com/tree/compose-multiplatform-patterns/) *(AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.)*
- Doing heavy computation directly inside a @Composable function body instead of moving it into the ViewModel or wrapping it in remember {}, causing the work to re-run on every recomposition. — [source](https://llms-explorer.com/tree/compose-multiplatform-patterns/) *(AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.)*
- Creating new object instances as composable parameters on every call (new lambdas or data class instances built inline), which defeats Compose's ability to skip unchanged composables. — [source](https://llms-explorer.com/tree/compose-multiplatform-patterns/) *(AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.)*
- Substituting LaunchedEffect(Unit) for proper ViewModel initialization, which can re-run on configuration changes in some setups instead of running exactly once per ViewModel lifetime. — [source](https://llms-explorer.com/tree/compose-multiplatform-patterns/) *(AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.)*

## Known issues

- Using mutableStateOf directly inside a ViewModel is less lifecycle-safe than MutableStateFlow collected with collectAsStateWithLifecycle, so the safer pattern requires more boilerplate up front. — [source](https://llms-explorer.com/tree/compose-multiplatform-patterns/) *(AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.)*
- Type-safe navigation with @Serializable routes requires Compose Navigation 2.8+, so older multiplatform setups may need a version bump before adopting the pattern. — [source](https://llms-explorer.com/tree/compose-multiplatform-patterns/) *(AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.)*
- Marking a class @Stable is a promise to the compiler, not a guarantee it checks; an incorrectly annotated type can cause silent visual bugs that are hard to trace back to a stability violation. — [source](https://llms-explorer.com/tree/compose-multiplatform-patterns/) *(AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.)*
- Sharing UI across Android, iOS, desktop, and Web still leaves platform-specific concerns (permissions, notifications, file pickers) unshared, so shared UI does not mean shared app end to end. — [source](https://llms-explorer.com/tree/compose-multiplatform-patterns/) *(AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.)*

## Context files

- [Compose Multiplatform Patterns](https://llms-explorer.com/downloads/sources/mdb-context-hub/compose-multiplatform-patterns.md)
