跳转到内容

TopAppBar

TopAppBar 是 COUI 中的顶部应用栏组件,用于在界面顶部提供导航、标题和操作按钮。支持大标题模式和普通模式,以及滚动时的动态效果。

此组件通常与 Scaffold 组件结合使用,以便在应用程序的不同页面中保持一致的布局和行为。

引入

kotlin
import io.github.suqi8.coui.kmp.basic.TopAppBar
import io.github.suqi8.coui.kmp.basic.SmallTopAppBar
import io.github.suqi8.coui.kmp.basic.COUIScrollBehavior
import io.github.suqi8.coui.kmp.basic.rememberTopAppBarState

基本用法

小标题顶部栏

kotlin
Scaffold(
    topBar = {
        SmallTopAppBar(
            title = "标题",
            navigationIcon = {
                IconButton(onClick = { /* 处理点击事件 */ }) {
                    Icon(COUIIcons.Back, contentDescription = "返回")
                }
            },
            actions = {
                IconButton(onClick = { /* 处理点击事件 */ }) {
                    Icon(COUIIcons.More, contentDescription = "更多")
                }
            }
        )
    }
)

大标题顶部栏

kotlin
Scaffold(
    topBar = {
        TopAppBar(
            title = "标题",
            largeTitle = "大标题", // 如果不指定,将使用 title 的值
            navigationIcon = {
                IconButton(onClick = { /* 处理点击事件 */ }) {
                    Icon(COUIIcons.Back, contentDescription = "返回")
                }
            },
            actions = {
                IconButton(onClick = { /* 处理点击事件 */ }) {
                    Icon(COUIIcons.More, contentDescription = "更多")
                }
            }
        )
    }
)

带副标题

两种顶部栏都可以在标题下方显示副标题。可折叠的 TopAppBar 中副标题默认随折叠渐隐;设置 hideSubtitleOnCollapse = false 可让其保持可见并滑入折叠栏标题下方:

kotlin
TopAppBar(
    title = "标题",
    largeTitle = "大标题",
    subtitle = "副标题",
    hideSubtitleOnCollapse = false
)

大标题顶部栏滚动行为(使用脚手架)

TopAppBar 支持随内容滚动时改变其显示状态:

kotlin
val scrollBehavior = COUIScrollBehavior()

Scaffold(
    topBar = {
        TopAppBar(
            title = "标题",
            largeTitle = "大标题", // 如果不指定,将使用 title 的值
            scrollBehavior = scrollBehavior
        )
    }
) { paddingValues ->
    // 内容区域需要考虑 padding
    LazyColumn(
        modifier = Modifier
            .fillMaxSize()
            // 如需添加越界回弹效果,则应在绑定滚动行为之前添加
            .overScrollVertical()
            // 绑定 TopAppBar 滚动事件
            .nestedScroll(scrollBehavior.nestedScrollConnection),
        contentPadding = PaddingValues(top = paddingValues.calculateTopPadding())
    ) {
        // 列表内容
    }
}

自定义样式

自定义颜色

kotlin
TopAppBar(
    title = "标题",
    color = COUITheme.colorScheme.primary,
    titleColor = COUITheme.colorScheme.onPrimary,
    largeTitleColor = COUITheme.colorScheme.onPrimary
)

自定义内容边距

kotlin
TopAppBar(
    title = "标题",
    titlePadding = 32.dp
)

自定义图标边距

kotlin
TopAppBar(
    title = "标题",
    navigationIconPadding = 12.dp,
    actionIconPadding = 12.dp
)

属性

TopAppBar 属性

属性名类型说明默认值是否必须
titleString顶部栏标题-
modifierModifier应用于顶部栏的修饰符Modifier
colorColor顶部栏背景颜色COUITheme.colorScheme.surface
titleColorColor折叠时小标题文字颜色COUITheme.colorScheme.onSurface
largeTitleString大标题文本title
largeTitleColorColor展开时大标题文字颜色COUITheme.colorScheme.onSurface
subtitleString显示在标题栏下方的副标题文本""
subtitleColorColor副标题文字颜色COUITheme.colorScheme.onSurfaceVariantSummary
dividerColorColor折叠时显现的底部细分割线颜色COUITheme.colorScheme.dividerLine
navigationIcon@Composable () -> Unit导航图标区域的可组合函数{}
actions@Composable RowScope.() -> Unit操作按钮区域的可组合函数(建议使用 24dp 图标){}
scrollBehaviorScrollBehavior?控制顶部栏滚动行为null
defaultWindowInsetsPaddingBoolean是否应用默认窗口边距true
showDividerBoolean是否绘制随折叠渐显的底部细分割线true
hideSubtitleOnCollapseBoolean副标题是否随折叠渐隐;为 false 时保持不透明并滑入折叠栏标题下方true
titlePaddingDp水平内容边距TopAppBarDefaults.TitlePadding
navigationIconPaddingDp导航图标的起始边距TopAppBarDefaults.NavigationIconPadding
actionIconPaddingDp操作图标的末尾边距TopAppBarDefaults.ActionIconPadding
bottomContent@Composable () -> Unit显示在标题栏下方的可组合内容{}

SmallTopAppBar 属性

属性名类型说明默认值是否必须
titleString顶部栏标题-
modifierModifier应用于顶部栏的修饰符Modifier
colorColor顶部栏背景颜色COUITheme.colorScheme.surface
titleColorColor标题文字颜色COUITheme.colorScheme.onSurface
subtitleString显示在标题栏下方的副标题文本""
subtitleColorColor副标题文字颜色COUITheme.colorScheme.onSurfaceVariantSummary
dividerColorColor滚动时显现的底部细分割线颜色COUITheme.colorScheme.dividerLine
navigationIcon@Composable () -> Unit导航图标区域的可组合函数{}
actions@Composable RowScope.() -> Unit操作按钮区域的可组合函数(建议使用 24dp 图标){}
scrollBehaviorScrollBehavior?控制顶部栏滚动行为null
defaultWindowInsetsPaddingBoolean是否应用默认窗口边距true
showDividerBoolean内容在栏下滚动时是否绘制底部细分割线(需要 scrollBehavior)true
titlePaddingDp水平内容边距TopAppBarDefaults.TitlePadding
navigationIconPaddingDp导航图标的起始边距TopAppBarDefaults.NavigationIconPadding
actionIconPaddingDp操作图标的末尾边距TopAppBarDefaults.ActionIconPadding
bottomContent@Composable () -> Unit显示在标题栏下方的可组合内容{}

TopAppBarDefaults 对象

TopAppBarDefaults 对象提供了 TopAppBar 和 SmallTopAppBar 组件的默认值。

常量

常量名类型说明默认值
TitlePaddingDp标题和大标题的水平内边距16.dp
LargeTitleTopPaddingDp展开态大标题的顶部内边距54.dp
NavigationIconPaddingDp导航图标的起始边距16.dp
ActionIconPaddingDp操作图标的末尾边距16.dp
CollapsedHeightDpTopAppBar 折叠时的高度52.dp
ExpandedHeightDp无副标题时 TopAppBar 展开态的最小高度107.dp
SmallTopAppBarCenterHeightDpSmallTopAppBar 布局的垂直中心高度52.dp
LargeTitleBottomPaddingDp展开态大标题区块下方的底部边距(折叠时渐变至 0.dp)12.dp
SubtitleBottomPaddingDp副标题溢出折叠栏时其下方的底部边距8.dp
SubtitleMarginTopDp标题与副标题之间的垂直间距3.5.dp
NavigationIconGapDp导航图标与折叠态标题之间的水平间距4.dp
ActionIconGapDp标题与操作图标之间的水平间距8.dp

ScrollBehavior

COUIScrollBehavior 是用于控制顶部栏滚动行为的配置对象。

rememberTopAppBarState

用于创建和记住 TopAppBarState:

kotlin
val scrollBehavior = COUIScrollBehavior(
    state = rememberTopAppBarState(),
    canScroll = { true }
)
参数名类型默认值说明
stateTopAppBarStaterememberTopAppBarState()控制滚动状态的状态对象
canScroll() -> Boolean控制是否允许滚动的回调
snapAnimationSpecAnimationSpec<Float>?180ms 减速 tween定义滚动停在中间态时吸附到全展开/全折叠的动画
flingAnimationSpecDecayAnimationSpec<Float>?rememberSplineBasedDecay()定义顶部栏滑动的衰减动画

进阶用法

处理窗口边距

kotlin
TopAppBar(
    title = "标题",
    largeTitle = "大标题",
    defaultWindowInsetsPadding = false // 自行处理窗口嵌入边距
)

自定义滚动行为动画

kotlin
var isScrollingEnabled by remember { mutableStateOf(true) }
val scrollBehavior = COUIScrollBehavior(
    snapAnimationSpec = tween(durationMillis = 100),
    flingAnimationSpec = rememberSplineBasedDecay(),
    canScroll = { isScrollingEnabled } // 可以动态控制是否允许滚动
)

TopAppBar(
    title = "标题",
    largeTitle = "大标题",
    scrollBehavior = scrollBehavior
)

大标题和小标题结合使用

kotlin
var useSmallTopBar by remember { mutableStateOf(false) }

Box(modifier = Modifier.fillMaxSize()) {
    if (useSmallTopBar) {
        SmallTopAppBar(
            title = "精简模式",
            navigationIcon = {
                IconButton(onClick = { useSmallTopBar = false }) {
                    Icon(
                        imageVector = COUIIcons.Back,
                        contentDescription = "切换到大标题",
                        tint = COUITheme.colorScheme.onBackground
                    )
                }
            }
        )
    } else {
        TopAppBar(
            title = "标题",
            largeTitle = "展开模式",
            navigationIcon = {
                IconButton(onClick = { useSmallTopBar = true }) {
                    Icon(
                        imageVector = COUIIcons.Back,
                        contentDescription = "切换到小标题",
                        tint = COUITheme.colorScheme.onBackground
                    )
                }
            }
        )
    }
}

变更日志

基于 Apache-2.0 许可发布