Provides Compose Multiplatform patterns for state management, navigation, theming, and performance optimization across Android, iOS, Desktop, and Web.
How this skill is triggered — by the user, by Claude, or both
Slash command
/everything-claude-code:compose-multiplatform-patternsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
使用 Compose Multiplatform 和 Jetpack Compose 在 Android、iOS、Desktop 和 Web 之间构建共享 UI 的模式。涵盖状态管理、导航、主题和性能。
使用 Compose Multiplatform 和 Jetpack Compose 在 Android、iOS、Desktop 和 Web 之间构建共享 UI 的模式。涵盖状态管理、导航、主题和性能。
使用单一数据类作为屏幕状态。将其暴露为 StateFlow 并在 Compose 中收集:
data class ItemListState(
val items: List<Item> = emptyList(),
val isLoading: Boolean = false,
val error: String? = null,
val searchQuery: String = ""
)
class ItemListViewModel(
private val getItems: GetItemsUseCase
) : ViewModel() {
private val _state = MutableStateFlow(ItemListState())
val state: StateFlow<ItemListState> = _state.asStateFlow()
fun onSearch(query: String) {
_state.update { it.copy(searchQuery = query) }
loadItems(query)
}
private fun loadItems(query: String) {
viewModelScope.launch {
_state.update { it.copy(isLoading = true) }
getItems(query).fold(
onSuccess = { items -> _state.update { it.copy(items = items, isLoading = false) } },
onFailure = { e -> _state.update { it.copy(error = e.message, isLoading = false) } }
)
}
}
}
@Composable
fun ItemListScreen(viewModel: ItemListViewModel = koinViewModel()) {
val state by viewModel.state.collectAsStateWithLifecycle()
ItemListContent(
state = state,
onSearch = viewModel::onSearch
)
}
@Composable
private fun ItemListContent(
state: ItemListState,
onSearch: (String) -> Unit
) {
// 无状态可组合函数 — 易于预览和测试
}
对于复杂屏幕,使用密封接口处理事件而非多个回调 lambda:
sealed interface ItemListEvent {
data class Search(val query: String) : ItemListEvent
data class Delete(val itemId: String) : ItemListEvent
data object Refresh : ItemListEvent
}
// 在 ViewModel 中
fun onEvent(event: ItemListEvent) {
when (event) {
is ItemListEvent.Search -> onSearch(event.query)
is ItemListEvent.Delete -> deleteItem(event.itemId)
is ItemListEvent.Refresh -> loadItems(_state.value.searchQuery)
}
}
// 在可组合函数中 — 单个 lambda 替代多个
ItemListContent(
state = state,
onEvent = viewModel::onEvent
)
将路由定义为 @Serializable 对象:
@Serializable data object HomeRoute
@Serializable data class DetailRoute(val id: String)
@Serializable data object SettingsRoute
@Composable
fun AppNavHost(navController: NavHostController = rememberNavController()) {
NavHost(navController, startDestination = HomeRoute) {
composable<HomeRoute> {
HomeScreen(onNavigateToDetail = { id -> navController.navigate(DetailRoute(id)) })
}
composable<DetailRoute> { backStackEntry ->
val route = backStackEntry.toRoute<DetailRoute>()
DetailScreen(id = route.id)
}
composable<SettingsRoute> { SettingsScreen() }
}
}
使用 dialog() 和覆盖层模式替代命令式的 show/hide:
NavHost(navController, startDestination = HomeRoute) {
composable<HomeRoute> { /* ... */ }
dialog<ConfirmDeleteRoute> { backStackEntry ->
val route = backStackEntry.toRoute<ConfirmDeleteRoute>()
ConfirmDeleteDialog(
itemId = route.itemId,
onConfirm = { navController.popBackStack() },
onDismiss = { navController.popBackStack() }
)
}
}
使用插槽参数设计可组合函数以获得灵活性:
@Composable
fun AppCard(
modifier: Modifier = Modifier,
header: @Composable () -> Unit = {},
content: @Composable ColumnScope.() -> Unit,
actions: @Composable RowScope.() -> Unit = {}
) {
Card(modifier = modifier) {
Column {
header()
Column(content = content)
Row(horizontalArrangement = Arrangement.End, content = actions)
}
}
}
Modifier 顺序很重要 — 按此序列应用:
Text(
text = "Hello",
modifier = Modifier
.padding(16.dp) // 1. 布局(内边距、尺寸)
.clip(RoundedCornerShape(8.dp)) // 2. 形状
.background(Color.White) // 3. 绘制(背景、边框)
.clickable { } // 4. 交互
)
// commonMain
@Composable
expect fun PlatformStatusBar(darkIcons: Boolean)
// androidMain
@Composable
actual fun PlatformStatusBar(darkIcons: Boolean) {
val systemUiController = rememberSystemUiController()
SideEffect { systemUiController.setStatusBarColor(Color.Transparent, darkIcons) }
}
// iosMain
@Composable
actual fun PlatformStatusBar(darkIcons: Boolean) {
// iOS 通过 UIKit 互操作或 Info.plist 处理此功能
}
当所有属性都稳定时,将类标记为 @Stable 或 @Immutable:
@Immutable
data class ItemUiModel(
val id: String,
val title: String,
val description: String,
val progress: Float
)
key() 和懒加载列表LazyColumn {
items(
items = items,
key = { it.id } // 稳定的 key 支持条目复用和动画
) { item ->
ItemRow(item = item)
}
}
derivedStateOf 延迟读取val listState = rememberLazyListState()
val showScrollToTop by remember {
derivedStateOf { listState.firstVisibleItemIndex > 5 }
}
// 差 — 每次重组都创建新的 lambda 和列表
items.filter { it.isActive }.forEach { ActiveItem(it, onClick = { handle(it) }) }
// 好 — 为每个条目设置 key,使回调保持绑定到正确的行
val activeItems = remember(items) { items.filter { it.isActive } }
activeItems.forEach { item ->
key(item.id) {
ActiveItem(item, onClick = { handle(item) })
}
}
@Composable
fun AppTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
dynamicColor: Boolean = true,
content: @Composable () -> Unit
) {
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
if (darkTheme) dynamicDarkColorScheme(LocalContext.current)
else dynamicLightColorScheme(LocalContext.current)
}
darkTheme -> darkColorScheme()
else -> lightColorScheme()
}
MaterialTheme(colorScheme = colorScheme, content = content)
}
mutableStateOf,而 MutableStateFlow 配合 collectAsStateWithLifecycle 对生命周期更安全NavController 深层传递到可组合函数中 — 应传递 lambda 回调@Composable 函数中进行繁重计算 — 移到 ViewModel 或 remember {}LaunchedEffect(Unit) 替代 ViewModel 初始化 — 在某些配置中会在配置变更时重新运行参见技能:android-clean-architecture 了解模块结构和分层。
参见技能:kotlin-coroutines-flows 了解协程和 Flow 模式。
npx claudepluginhub aaione/everything-claude-code-zhProvides patterns for shared UI in Compose Multiplatform across Android, iOS, Desktop, and Web: state management with ViewModels/StateFlow, navigation, theming, and performance.
Provides Compose Multiplatform and Jetpack Compose patterns for state management, navigation, theming, and performance optimization in KMP projects.
Provides Jetpack Compose patterns for state hoisting, remember variants, slot APIs, modifiers, side effects, theming, animations, and performance in Android UI development.