TopAppBar 顶部标题栏
2026/1/31大约 3 分钟
TopAppBar 顶部标题栏
概述
TopAppBar(顶部应用栏)是应用常用的导航与操作承载区,通常位于屏幕顶部,包含应用标题、导航按钮、操作按钮和可选的搜索/筛选输入。Compose 提供了 Material(androidx.compose.material)和 Material3(androidx.compose.material3)的 TopAppBar 组件,常在 Scaffold 的 topBar 槽位中使用。
常用 API 与参数(Material)
title: @Composable () -> Unit:标题内容,通常是Text。navigationIcon: @Composable (() -> Unit)?:导航图标槽,常用于返回或打开抽屉(hamburger)按钮。actions: @Composable RowScope.() -> Unit:右侧操作按钮槽,放置IconButton等。backgroundColor: Color:背景色。contentColor: Color:内容(图标/文字)颜色。elevation: Dp:阴影高度(Material)。
(Material3 的 TopAppBar 家族)
SmallTopAppBar、CenterAlignedTopAppBar、LargeTopAppBar、MediumTopAppBar:不同尺寸与对齐方式的 TopAppBar。scrollBehavior:配合TopAppBarScrollBehavior支持滚动折叠与展开。
常见使用模式与注意事项
- 将 TopAppBar 放在
Scaffold(topBar = { ... })中以与snackbar、drawer等协同。 - 导航图标通常使用
IconButton,在按下时触发navController.navigateUp()或打开抽屉。 - 操作按钮建议使用
IconButton+Icon,并保持图标尺寸与间距一致。 - 在滚动内容时使用 Material3 的
scrollBehavior能实现折叠/悬停效果。
代码示例(Material)
@Composable
fun SimpleTopAppBar(onMenu: () -> Unit, onSearch: () -> Unit) {
TopAppBar(
title = { Text(text = "我的应用") },
navigationIcon = {
IconButton(onClick = onMenu) {
Icon(Icons.Default.Menu, contentDescription = "菜单")
}
},
actions = {
IconButton(onClick = onSearch) { Icon(Icons.Default.Search, contentDescription = "搜索") }
IconButton(onClick = { /* TODO: 更多操作 */ }) { Icon(Icons.Default.MoreVert, contentDescription = "更多") }
},
backgroundColor = MaterialTheme.colors.primarySurface,
contentColor = MaterialTheme.colors.onPrimary,
elevation = 4.dp
)
}在 Scaffold 中使用:
@Composable
fun TopBarScaffoldSample() {
val drawerState = rememberScaffoldState()
Scaffold(
scaffoldState = drawerState,
topBar = { SimpleTopAppBar(onMenu = { /* 打开抽屉 */ }, onSearch = { /* 跳转搜索 */ }) }
) { innerPadding ->
// 主体内容
}
}Material3 示例:带滚动折叠的 TopAppBar
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun CollapsingTopAppBarSample() {
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(rememberTopAppBarState())
Scaffold(
topBar = {
SmallTopAppBar(
title = { Text("带折叠的标题栏") },
scrollBehavior = scrollBehavior
)
}
) { contentPadding ->
LazyColumn(modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection)) {
items(100) { index -> Text("Item $index", modifier = Modifier.padding(16.dp)) }
}
}
}注意:Material3 的 API 以及
TopAppBarDefaults、rememberTopAppBarState等在不同版本的 compose-material3 中可能有所变化,请以项目依赖的 Compose 版本为准。
示例注意点与最佳实践
- 图标与文字的可访问性描述(
contentDescription)不可忽略,便于 TalkBack 等无障碍工具。 - 对于需要在顶部展示搜索框或可展开操作的场景,考虑在
TopAppBar中放入TextField或使用LargeTopAppBar布局。 - 在深色/浅色主题中测试
backgroundColor与contentColor的对比度,或使用MaterialTheme提供的颜色槽。
参考
androidx.compose.material.TopAppBar文档androidx.compose.material3TopAppBar 系列文档
参考代码
package com.example.kt_android_demo.conponses
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.icons.filled.Search
import androidx.compose.material.icons.filled.Share
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.sp
import com.example.kt_android_demo.R
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TopAppBarComponent() {
val actionText = remember {
mutableStateOf("action")
}
Scaffold(
topBar = {
TopAppBar(
navigationIcon = {
IconButton(onClick = {
actionText.value = "navigation clicked!"
}) {
Icon(
Icons.Filled.Menu,
contentDescription = "navigation"
)
}
},
title = {
// 主标题,副标题
Column {
Text(
text = stringResource(R.string.app_name),
color = Color.White,
fontSize = 20.sp
)
Text(text = "sub Title.", color = Color.White, fontSize = 16.sp)
}
},
actions = {
IconButton(onClick = {
actionText.value = "share clicked!"
}) {
Icon(
Icons.Filled.Share,
contentDescription = "Share"
)
}
IconButton(onClick = {
actionText.value = "search clicked!"
}) {
Icon(
Icons.Filled.Search,
contentDescription = "Search"
)
}
IconButton(onClick = {
actionText.value = "more clicked!"
}) {
Icon(
Icons.Filled.MoreVert,
contentDescription = "MoreVert"
)
}
},
colors = TopAppBarDefaults.topAppBarColors(
containerColor = Color.Red,
navigationIconContentColor = Color.Blue,
titleContentColor = Color.Green,
actionIconContentColor = Color.White
),
)
}
) { padding ->
Column(
modifier = Modifier
.fillMaxSize()
.padding(padding),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = actionText.value)
}
}
}code
package com.example.note.jetpack.examples
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.TopAppBar
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material.icons.filled.Search
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.Scaffold
import androidx.compose.material.rememberScaffoldState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@Composable
fun SimpleTopAppBar(onMenu: () -> Unit, onSearch: () -> Unit) {
TopAppBar(
title = { Text(text = "我的应用") },
navigationIcon = {
IconButton(onClick = onMenu) {
Icon(Icons.Filled.Menu, contentDescription = "菜单")
}
},
actions = {
IconButton(onClick = onSearch) { Icon(Icons.Filled.Search, contentDescription = "搜索") }
IconButton(onClick = { /* 更多 */ }) { Icon(Icons.Filled.MoreVert, contentDescription = "更多") }
},
backgroundColor = MaterialTheme.colors.primarySurface,
contentColor = MaterialTheme.colors.onPrimary,
elevation = 4.dp
)
}
@Preview(showBackground = true)
@Composable
fun PreviewSimpleTopAppBar() {
var show by remember { mutableStateOf(true) }
val scaffoldState = rememberScaffoldState()
Scaffold(scaffoldState = scaffoldState, topBar = { SimpleTopAppBar(onMenu = {}, onSearch = {}) }) {
Column(modifier = Modifier.padding(it)) {
Text("主体内容示例", modifier = Modifier.padding(16.dp))
Spacer(modifier = Modifier.height(8.dp))
}
}
}
@Preview(showBackground = true)
@Composable
fun PreviewListWithTopAppBar() {
val scaffoldState = rememberScaffoldState()
Scaffold(scaffoldState = scaffoldState, topBar = { SimpleTopAppBar(onMenu = {}, onSearch = {}) }) { inner ->
LazyColumn(modifier = Modifier.padding(inner)) {
items((1..20).toList()) { i -> Text("Item $i", modifier = Modifier.padding(16.dp)) }
}
}
}