Jetpack Compose 自定义标题栏终极指南:从基础到高级实战

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)
) { /* ... */ }

💡 性能优化要点

  1. 避免重组

    @Immutable
    data class TitleState(val text: String, val icon: ImageVector)
    
  2. 边界条件处理

    Modifier
        .windowInsetsPadding(WindowInsets.systemBars)
        .navigationBarsPadding()
    
  3. 图片加载优化

    AsyncImage(
        model = "url",
        contentDescription = null,
        modifier = Modifier.size(32.dp).clip(CircleShape)
    )
    

📌 最佳实践建议

  1. 简单场景直接用 Row 布局
  2. 需要主题适配选 Material 组件
  3. 复杂交互优先考虑状态管理架构
  4. 全屏应用必须处理系统手势冲突

通过本指南,你可以轻松实现从简单到企业级的标题栏需求。如果有特殊场景需求,欢迎在评论区讨论!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值