Jetpack Compose 自定义标题栏终极指南:从基础到高级实战
本文将带你彻底掌握 Compose 标题栏开发,涵盖 5 种专业级实现方案 + 性能优化技巧 + 完整可运行代码。
📚 核心方案对比
方案 | 特点 | 适用场景 | 复杂度 |
---|---|---|---|
基础Row布局 | 完全自定义,灵活度高 | 简单标题栏 | ⭐ |
Material增强版 | 完美兼容MD3主题 | 标准化产品 | ⭐⭐ |
沉浸式标题 | 动态透明度/折叠效果 | 内容型APP | ⭐⭐⭐ |
多状态管理 | 集成菜单/搜索框 | 复杂交互需求 | ⭐⭐⭐⭐ |
跨平台适配 | 处理刘海屏/手势冲突 | 全屏应用 | ⭐⭐⭐⭐ |
🛠️ 5 种专业实现方案
方案1:基础标题栏(15行代码)
@Composable
fun BasicTitleBar(title: String, onBack: () -> Unit) {Row(modifier = Modifier.fillMaxWidth().height(56.dp).padding(horizontal = 16.dp),verticalAlignment = Alignment.CenterVertically) {IconButton(onClick = onBack) {Icon(Icons.Default.ArrowBack, null)}Text(text = title,style = MaterialTheme.typography.titleMedium,modifier = Modifier.weight(1f))}
}
方案2:Material3 增强版
@Composable
fun MaterialTitleBar(title: String,subtitle: String? = null,actions: @Composable RowScope.() -> Unit = {}
) {Surface(color = MaterialTheme.colorScheme.surface,shadowElevation = 3.dp) {Row(Modifier.fillMaxWidth().padding(16.dp),horizontalArrangement = Arrangement.SpaceBetween,verticalAlignment = Alignment.CenterVertically) {Column(Modifier.weight(1f)) {Text(title, style = MaterialTheme.typography.titleLarge)subtitle?.let {Text(it, style = MaterialTheme.typography.bodySmall)}}Row(actions = actions)}}
}
方案3:沉浸式动态标题
@Composable
fun ImmersiveTitleBar(scrollState: ScrollState,title: String
) {val alpha by remember {derivedStateOf {min(1f, scrollState.value / 200f)}}Box(modifier = Modifier.fillMaxWidth().height(64.dp)) {Text(text = title,modifier = Modifier.align(Alignment.BottomStart).padding(16.dp).graphicsLayer { this.alpha = alpha },style = MaterialTheme.typography.headlineSmall)}
}
🚀 高级功能集成
动态菜单控制
@Composable
fun MenuTitleBar() {var expanded by remember { mutableStateOf(false) }Row {// 标题...Box {IconButton(onClick = { expanded = true }) {Icon(Icons.Default.MoreVert, null)}DropdownMenu(expanded, onDismiss = { expanded = false }) {DropdownMenuItem(text = { Text("设置") }, onClick = {})DropdownMenuItem(text = { Text("退出") }, onClick = {})}}}
}
标题栏交互动画
val transition = updateTransition(targetState = expanded)
val elevation by transition.animateDp { if (it) 8.dp else 0.dp }Surface(modifier = Modifier.shadow(elevation)
) { /* ... */ }
💡 性能优化要点
-
避免重组:
@Immutable data class TitleState(val text: String, val icon: ImageVector)
-
边界条件处理:
Modifier.windowInsetsPadding(WindowInsets.systemBars).navigationBarsPadding()
-
图片加载优化:
AsyncImage(model = "url",contentDescription = null,modifier = Modifier.size(32.dp).clip(CircleShape) )
📌 最佳实践建议:
- 简单场景直接用
Row
布局- 需要主题适配选
Material
组件- 复杂交互优先考虑状态管理架构
- 全屏应用必须处理系统手势冲突
通过本指南,你可以轻松实现从简单到企业级的标题栏需求。如果有特殊场景需求,欢迎在评论区讨论!