Android Jetpack Compose - TopAppBar、BottomAppBar、Scaffold

一、TopAppBar

1、基本介绍
  • TopAppBar 用于实现顶部的应用栏,它封装了顶部的应用栏的常见样式和交互,例如,标题、导航图标、操作按钮、滚动联动
参数 说明
title 显示在应用栏中的文字
navigationIcon 用于导航的主图标,显示在应用栏的左侧
actions 可让用户访问关键操作的图标,它们显示在应用栏的右侧
scrollBehavior 确定顶部应用栏如何响应容器内部内容的滚动
colors 确定应用栏的显示方式
2、演示
kotlin 复制代码
TopAppBar(
    colors = topAppBarColors(
        containerColor = MaterialTheme.colorScheme.primaryContainer,
        titleContentColor = MaterialTheme.colorScheme.primary,
    ),
    title = {
        Text("顶部的应用栏")
    }
)
kotlin 复制代码
TopAppBar(
    colors = topAppBarColors(
        containerColor = MaterialTheme.colorScheme.primaryContainer,
        titleContentColor = MaterialTheme.colorScheme.primary,
    ),
    navigationIcon = {
        IconButton(onClick = {}) {
            Icon(
                imageVector = Icons.AutoMirrored.Filled.ArrowBack,
                contentDescription = "返回"
            )
        }
    },
    actions = {
        IconButton(onClick = { }) {
            Icon(
                imageVector = Icons.Filled.Menu,
                contentDescription = "菜单"
            )
        }
    },
    title = {
        Text("顶部的应用栏")
    }
)
kotlin 复制代码
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())

Column(modifier = Modifier.fillMaxSize()) {
    TopAppBar(
        title = {
            Text("顶部的应用栏")
        },
        scrollBehavior = scrollBehavior
    )
    LazyColumn(
        modifier = Modifier
            .fillMaxSize()
            .nestedScroll(scrollBehavior.nestedScrollConnection),
        contentPadding = PaddingValues(top = 8.dp)
    ) {
        items(50) { Text("列表项 ${it + 1}", modifier = Modifier.padding(16.dp)) }
    }
}
3、其他顶部应用栏
  1. 居中对齐顶部应用栏
kotlin 复制代码
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())

Column(modifier = Modifier.fillMaxSize()) {
    CenterAlignedTopAppBar(
        colors = topAppBarColors(
            containerColor = MaterialTheme.colorScheme.primaryContainer,
            titleContentColor = MaterialTheme.colorScheme.primary,
        ),
        navigationIcon = {
            IconButton(onClick = {}) {
                Icon(
                    imageVector = Icons.AutoMirrored.Filled.ArrowBack,
                    contentDescription = "返回"
                )
            }
        },
        actions = {
            IconButton(onClick = { }) {
                Icon(
                    imageVector = Icons.Filled.Menu,
                    contentDescription = "菜单"
                )
            }
        },
        title = {
            Text("顶部的应用栏")
        },
        scrollBehavior = scrollBehavior
    )
    LazyColumn(
        modifier = Modifier
            .fillMaxSize()
            .nestedScroll(scrollBehavior.nestedScrollConnection),
        contentPadding = PaddingValues(top = 8.dp)
    ) {
        items(50) { Text("列表项 ${it + 1}", modifier = Modifier.padding(16.dp)) }
    }
}
  1. 中等顶部应用栏
kotlin 复制代码
MediumTopAppBar(
    colors = topAppBarColors(
        containerColor = MaterialTheme.colorScheme.primaryContainer,
        titleContentColor = MaterialTheme.colorScheme.primary,
    ),
    title = {
        Text("顶部的应用栏")
    }
)
  1. 大顶部应用栏
kotlin 复制代码
LargeTopAppBar(
    colors = topAppBarColors(
        containerColor = MaterialTheme.colorScheme.primaryContainer,
        titleContentColor = MaterialTheme.colorScheme.primary,
    ),
    title = {
        Text("顶部的应用栏")
    }
)

二、BottomAppBar

1、基本介绍
  • BottomAppBar 用于实现底部的应用栏,它封装了底部的应用栏的常见样式和交互,例如,操作按钮、浮动操作按钮
2、演示
  1. BottomAppBar 基本使用,BottomAppBar 默认不会固定在底部
kotlin 复制代码
BottomAppBar(
    actions = {
        IconButton(onClick = { }) {
            Icon(Icons.Filled.Check, contentDescription = "Check")
        }
        IconButton(onClick = { }) {
            Icon(
                Icons.Filled.Edit,
                contentDescription = "Edit",
            )
        }
        IconButton(onClick = { }) {
            Icon(
                Icons.Filled.ThumbUp,
                contentDescription = "ThumbUp",
            )
        }
        IconButton(onClick = { }) {
            Icon(
                Icons.Filled.MailOutline,
                contentDescription = "MailOutline",
            )
        }
    },
    floatingActionButton = {
        FloatingActionButton(
            onClick = { },
            containerColor = BottomAppBarDefaults.bottomAppBarFabColor,
            elevation = FloatingActionButtonDefaults.bottomAppBarFabElevation()
        ) {
            Icon(Icons.Filled.Add, "Add")
        }
    }
)
  1. BottomAppBar 固定在底部实现
kotlin 复制代码
ConstraintLayout(
    modifier = Modifier.fillMaxSize()
) {
    val (content, bottomBar) = createRefs()

    // 填满剩余空间
    LazyColumn(
        modifier = Modifier
            .constrainAs(content) {
                top.linkTo(parent.top)
                start.linkTo(parent.start)
                end.linkTo(parent.end)
                bottom.linkTo(bottomBar.top)
                width = Dimension.fillToConstraints
                height = Dimension.fillToConstraints
            }
            .fillMaxWidth()
    ) {
        items(50) { index ->
            Text(
                text = "Item ${index + 1}",
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(16.dp)
            )
        }
    }

    BottomAppBar(
        modifier = Modifier.constrainAs(bottomBar) {
            bottom.linkTo(parent.bottom)
            start.linkTo(parent.start)
            end.linkTo(parent.end)
        },
        actions = {
            IconButton(onClick = { }) {
                Icon(Icons.Filled.Check, contentDescription = "Check")
            }
            IconButton(onClick = { }) {
                Icon(
                    Icons.Filled.Edit,
                    contentDescription = "Edit",
                )
            }
            IconButton(onClick = { }) {
                Icon(
                    Icons.Filled.ThumbUp,
                    contentDescription = "ThumbUp",
                )
            }
            IconButton(onClick = { }) {
                Icon(
                    Icons.Filled.MailOutline,
                    contentDescription = "MailOutline",
                )
            }
        },
        floatingActionButton = {
            FloatingActionButton(
                onClick = { },
                containerColor = BottomAppBarDefaults.bottomAppBarFabColor,
                elevation = FloatingActionButtonDefaults.bottomAppBarFabElevation()
            ) {
                Icon(Icons.Filled.Add, "Add")
            }
        }
    )
}

三、Scaffold

1、基本介绍
  • Scaffold 是 Compose 中用于构建标准化的页面结构的脚手架组件
kotlin 复制代码
@Composable
fun Scaffold(
    modifier: Modifier = Modifier,
    topBar: @Composable () -> Unit = {},
    bottomBar: @Composable () -> Unit = {},
    snackbarHost: @Composable () -> Unit = {},
    floatingActionButton: @Composable () -> Unit = {},
    floatingActionButtonPosition: FabPosition = FabPosition.End,
    containerColor: Color = MaterialTheme.colorScheme.background,
    contentColor: Color = contentColorFor(containerColor),
    contentWindowInsets: WindowInsets = ScaffoldDefaults.contentWindowInsets,
    content: @Composable (PaddingValues) -> Unit
)
参数 说明
modifier 整体修饰符
topBar 顶部栏
bottomBar 底部栏
snackbarHost Snackbar 的组件
floatingActionButton 浮动按钮
floatingActionButtonPosition 浮动按钮位置
containerColor 容器背景色
contentColor 内容文字色
contentWindowInsets 窗口边距
content 主要内容区域
2、基本使用
kotlin 复制代码
var presses by remember { mutableIntStateOf(0) }

Scaffold(
    topBar = {
        TopAppBar(
            colors = topAppBarColors(
                containerColor = MaterialTheme.colorScheme.primaryContainer,
                titleContentColor = MaterialTheme.colorScheme.primary,
            ),
            title = {
                Text("顶部应用栏")
            }
        )
    },
    bottomBar = {
        BottomAppBar(
            containerColor = MaterialTheme.colorScheme.primaryContainer,
            contentColor = MaterialTheme.colorScheme.primary,
        ) {
            Text(
                modifier = Modifier.fillMaxWidth(),
                textAlign = TextAlign.Center,
                text = "底部应用栏",
            )
        }
    },
    floatingActionButton = {
        FloatingActionButton(
            onClick = {
                presses++
            }
        ) {
            Icon(Icons.Default.Add, contentDescription = "添加")
        }
    }
) { innerPadding ->
    Column(
        modifier = Modifier.padding(innerPadding),
    ) {
        Text("点击了 $presses 次")
    }
}
3、使用 floatingActionButtonPosition
(1)基本介绍
  • FabPosition 是用于控制 Scaffold 中 FloatingActionButton(FAB)位置的枚举类
枚举值 说明
End 屏幕右下角
Center 屏幕底部正中央
Start 屏幕左下角
EndOverlay 屏幕右下角,悬浮在 BottomAppBar 上方
(2)演示
kotlin 复制代码
    var presses by remember { mutableIntStateOf(0) }

    Scaffold(
        topBar = {
            TopAppBar(
                colors = topAppBarColors(
                    containerColor = MaterialTheme.colorScheme.primaryContainer,
                    titleContentColor = MaterialTheme.colorScheme.primary,
                ),
                title = {
                    Text("顶部应用栏")
                }
            )
        },
        bottomBar = {
            BottomAppBar(
                containerColor = MaterialTheme.colorScheme.primaryContainer,
                contentColor = MaterialTheme.colorScheme.primary,
            ) {
                Text(
                    modifier = Modifier.fillMaxWidth(),
                    textAlign = TextAlign.Center,
                    text = "底部应用栏",
                )
            }
        },
        floatingActionButton = {
            FloatingActionButton(
                onClick = {
                    presses++
                }
            ) {
                Icon(Icons.Default.Add, contentDescription = "添加")
            }
        },
        floatingActionButtonPosition = FabPosition.EndOverlay
    ) { innerPadding ->
        Column(
            modifier = Modifier.padding(innerPadding),
        ) {
            Text("点击了 $presses 次")
        }
    }
4、关于 innerPadding
(1)基本介绍
  • innerPadding 是 Scaffold 自动计算并传递给主要内容区域的安全边距值,它确保内容不会被 Scaffold 的其他部分遮挡,例如,顶部栏、底部栏
(2)演示
  • 不使用 innerPadding,顶部内容会被顶部栏遮挡,底部内容会被底部栏遮挡
kotlin 复制代码
var presses by remember { mutableIntStateOf(0) }

Scaffold(
    topBar = {
        TopAppBar(
            colors = topAppBarColors(
                containerColor = MaterialTheme.colorScheme.primaryContainer,
                titleContentColor = MaterialTheme.colorScheme.primary,
            ),
            title = {
                Text("顶部应用栏")
            }
        )
    },
    bottomBar = {
        BottomAppBar(
            containerColor = MaterialTheme.colorScheme.primaryContainer,
            contentColor = MaterialTheme.colorScheme.primary,
        ) {
            Text(
                modifier = Modifier.fillMaxWidth(),
                textAlign = TextAlign.Center,
                text = "底部应用栏",
            )
        }
    },
    floatingActionButton = {
        FloatingActionButton(
            onClick = {
                presses++
            }
        ) {
            Icon(Icons.Default.Add, contentDescription = "添加")
        }
    }
) { innerPadding ->
    Column(
        modifier = Modifier.fillMaxSize()
    ) {
        LazyColumn(
            modifier = Modifier.fillMaxSize()
        ) {
            items(50) { Text("列表项 ${it + 1}", modifier = Modifier.padding(16.dp)) }
        }
    }
}
5、使用 snackbarHost
kotlin 复制代码
var presses by remember { mutableIntStateOf(0) }
val scope = rememberCoroutineScope()
val snackbarHostState = remember { SnackbarHostState() }

Scaffold(
    topBar = {
        TopAppBar(
            colors = topAppBarColors(
                containerColor = MaterialTheme.colorScheme.primaryContainer,
                titleContentColor = MaterialTheme.colorScheme.primary,
            ),
            title = {
                Text("顶部应用栏")
            }
        )
    },
    bottomBar = {
        BottomAppBar(
            containerColor = MaterialTheme.colorScheme.primaryContainer,
            contentColor = MaterialTheme.colorScheme.primary,
        ) {
            Text(
                modifier = Modifier.fillMaxWidth(),
                textAlign = TextAlign.Center,
                text = "底部应用栏",
            )
        }
    },
    snackbarHost = {
        SnackbarHost(hostState = snackbarHostState)
    },
    floatingActionButton = {
        FloatingActionButton(
            onClick = {
                scope.launch {
                    presses++
                    val result = snackbarHostState.showSnackbar(
                        message = "点击了 $presses 次",
                        actionLabel = "撤销",
                        duration = SnackbarDuration.Short
                    )

                    if (result == SnackbarResult.ActionPerformed) {
                        presses--
                    }
                }
            }
        ) {
            Icon(Icons.Default.Add, contentDescription = "添加")
        }
    }
) { innerPadding ->
    Column(
        modifier = Modifier.padding(innerPadding),
    ) {
        Text("点击了 $presses 次")
    }
}
相关推荐
忧郁的Mr.Li7 小时前
SpringBoot中实现多数据源配置
java·spring boot·后端
消失的旧时光-19437 小时前
从 Kotlin 到 Dart:为什么 sealed 是处理「多种返回结果」的最佳方式?
android·开发语言·flutter·架构·kotlin·sealed
yq1982043011567 小时前
静思书屋:基于Java Web技术栈构建高性能图书信息平台实践
java·开发语言·前端
一个public的class7 小时前
你在浏览器输入一个网址,到底发生了什么?
java·开发语言·javascript
有位神秘人7 小时前
kotlin与Java中的单例模式总结
java·单例模式·kotlin
Jinkxs7 小时前
Gradle - 与Groovy/Kotlin DSL对比 构建脚本语言选择指南
android·开发语言·kotlin
&有梦想的咸鱼&7 小时前
Kotlin委托机制的底层实现深度解析(74)
android·开发语言·kotlin
golang学习记7 小时前
IntelliJ IDEA 2025.3 重磅发布:K2 模式全面接管 Kotlin —— 告别 K1,性能飙升 40%!
java·kotlin·intellij-idea
爬山算法7 小时前
Hibernate(89)如何在压力测试中使用Hibernate?
java·压力测试·hibernate
LDORntKQH7 小时前
基于深度强化学习的混合动力汽车能量管理策略 1.利用DQN算法控制电池和发动机发电机组的功率分配 2
android