name: android-jetpack-compose-expert
description: “Expert guidance for building modern Android UIs with Jetpack Compose, covering state management, navigation, performance, and Material Design 3.”
risk: safe
source: community
date_added: “2026-02-27”
Android Jetpack Compose 专家
概览
使用 Jetpack Compose 构建生产质量 Android 应用程序的全面指南。本技能涵盖架构模式、使用 ViewModel 的状态管理、导航类型安全,以及性能优化技术。
何时使用此技能
- 在使用 Jetpack Compose 启动新的 Android 项目时使用。
- 在将旧版 XML 布局迁移到 Compose 时使用。
- 在实现复杂的 UI 状态管理和副作用时使用。
- 在优化 Compose 性能(重组计数、稳定性)时使用。
- 在设置具有类型安全的导航时使用。
逐步指南
1. 项目设置与依赖
确保你的libs.versions.toml包含必要的 Compose BOM 和库。
[versions]composeBom="2024.02.01"activityCompose="1.8.2"[libraries]androidx-compose-bom={group="androidx.compose",name="compose-bom",version.ref="composeBom"}androidx-ui={group="androidx.compose.ui",name="ui"}androidx-ui-graphics={group="androidx.compose.ui",name="ui-graphics"}androidx-ui-tooling-preview={group="androidx.compose.ui",name="ui-tooling-preview"}androidx-material3={group="androidx.compose.material3",name="material3"}androidx-activity-compose={group="androidx.activity",name="activity-compose",version.ref="activityCompose"}2. 状态管理模式(MVI/MVVM)
使用ViewModel结合StateFlow来公开 UI 状态。避免公开MutableStateFlow。
// UI State DefinitiondataclassUserUiState(valisLoading:Boolean=false,valuser:User?=null,valerror:String?=null)// ViewModelclassUserViewModel@Injectconstructor(privatevaluserRepository:UserRepository):ViewModel(){privateval_uiState=MutableStateFlow(UserUiState())valuiState:StateFlow<UserUiState>=_uiState.asStateFlow()funloadUser(){viewModelScope.launch{_uiState.update{it.copy(isLoading=true)}try{valuser=userRepository.getUser()_uiState.update{it.copy(user=user,isLoading=false)}}catch(e:Exception){_uiState.update{it.copy(error=e.message,isLoading=false)}}}}}3. 创建屏幕可组合项
在“Screen”可组合函数中使用状态,并将数据传递给无状态组件。
@ComposablefunUserScreen(viewModel:UserViewModel=hiltViewModel()){valuiStatebyviewModel.uiState.collectAsStateWithLifecycle()UserContent(uiState=uiState,onRetry=viewModel::loadUser)}@ComposablefunUserContent(uiState:UserUiState,onRetry:()->Unit){Scaffold{padding->Box(modifier=Modifier.padding(padding)){when{uiState.isLoading->CircularProgressIndicator()uiState.error!=null->ErrorView(uiState.error,onRetry)uiState.user!=null->UserProfile(uiState.user)}}}}例子
示例 1:类型安全的导航
使用新的导航 Compose 类型安全(在最近版本中可用)。
// Define Destinations@SerializableobjectHome@SerializabledataclassProfile(valuserId:String)// Setup NavHost@ComposablefunAppNavHost(navController:NavHostController){NavHost(navController,startDestination=Home){composable<Home>{HomeScreen(onNavigateToProfile={id->navController.navigate(Profile(userId=id))})}composable<Profile>{backStackEntry->valprofile:Profile=backStackEntry.toRoute()ProfileScreen(userId=profile.userId)}}}最佳实践
- ✅做:使用
remember和derivedStateOf来在重组过程中最小化不必要的计算。 - ✅操作:如果数据类用于 UI 状态,并且包含
List或其他不稳定类型,请将其标记为@Immutable或@Stable,以启用智能重组跳过。 - ✅做:使用
LaunchedEffect来处理由状态变化触发的一次性副作用(例如显示 Snackbar)。 - ❌不要:在 Composable 函数体内直接执行昂贵的操作(例如排序列表),而不使用
remember。 - ❌不要:将
ViewModel实例传递给子组件。只传递数据(状态)和 lambda 回调(事件)。
故障排除
问题:无限重组循环。
解决方案:检查是否在组合中创建了新的对象实例(例如List或Modifier)而没有使用remember,或者是否在组合阶段更新了状态而不是在副作用或回调中更新。使用布局检查器(Layout Inspector)调试重组次数。
限制
- 仅当任务明确符合上述描述的范围时,才使用此技能。
- 不要将输出视为环境特定验证、测试或专家审查的替代品。
- 如果缺少所需的输入、权限、安全界限或成功标准,请停下来并要求澄清。