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 次")
    }
}
相关推荐
今天_也很困1 天前
LeetCode热题100-560. 和为 K 的子数组
java·算法·leetcode
在繁华处1 天前
线程进阶: 无人机自动防空平台开发教程V2
java·无人机
A懿轩A1 天前
【Java 基础编程】Java 变量与八大基本数据类型详解:从声明到类型转换,零基础也能看懂
java·开发语言·python
m0_740043731 天前
【无标题】
java·spring boot·spring·spring cloud·微服务
@ chen1 天前
Spring事务 核心知识
java·后端·spring
aithinker1 天前
使用QQ邮箱收发邮件遇到的坑 有些WIFI不支持ipv6
java
星火开发设计1 天前
C++ 预处理指令:#include、#define 与条件编译
java·开发语言·c++·学习·算法·知识
Hx_Ma161 天前
SpringMVC返回值
java·开发语言·servlet
晚霞的不甘1 天前
Flutter for OpenHarmony从零到一:构建《冰火人》双人合作闯关游戏
android·flutter·游戏·前端框架·全文检索·交互
2601_949833391 天前
flutter_for_openharmony口腔护理app实战+饮食记录实现
android·javascript·flutter