You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何单独修改Material3 MediumTopAppBar的大标题TextStyle?

问题描述

使用Material3的MediumTopAppBar时,尝试修改大标题的TextStyle但不影响小标题样式。当前实现代码如下:

MediumTopAppBar(
                title = { HeadlineLargeBlackText(text = "pageTitle") },
                navigationIcon = {
                    IconButton(onClick = { onBackPressed.invoke() }) {
                        Icon(
                            imageVector = Icons.Filled.ArrowBack,
                            contentDescription = stringResource(id = R.string.action_back)
                        )
                    }
                },
                scrollBehavior = scrollBehavior
            )

但设置HeadlineLargeBlackText后,大、小标题的TextStyle均被修改,导致两者样式一致。需求是大标题为自定义大样式,小标题保持默认小样式。查看源码发现TwoRowsTopAppBar中单独定义了两者的TextStyle,但相关方法为私有,请问如何单独修改这两个标题的样式?


解决方案

问题根源

直接给MediumTopAppBar的title参数传入固定样式的Text组件,会覆盖组件内部根据滚动状态自动切换标题样式的逻辑,导致展开(大标题)和折叠(小标题)阶段都使用同一种样式。

方法一:基于滚动状态动态切换样式

利用scrollBehavior.state.collapsedFraction判断标题折叠状态,为大、小标题分别应用不同样式:

MediumTopAppBar(
    title = {
        val scrollState = scrollBehavior.state
        // collapsedFraction=0为完全展开的大标题,=1为完全折叠的小标题
        val textStyle = if (scrollState.collapsedFraction < 0.5f) {
            // 自定义大标题样式
            MaterialTheme.typography.headlineLarge.copy(color = Color.Black)
        } else {
            // 默认小标题样式
            MaterialTheme.typography.titleLarge.copy(color = MaterialTheme.colorScheme.onSurface)
        }
        Text(text = "pageTitle", style = textStyle)
    },
    navigationIcon = {
        IconButton(onClick = { onBackPressed.invoke() }) {
            Icon(
                imageVector = Icons.Filled.ArrowBack,
                contentDescription = stringResource(id = R.string.action_back)
            )
        }
    },
    scrollBehavior = scrollBehavior
)

方法二:局部覆盖主题大标题样式

如果需要当前页面的MediumTopAppBar统一使用自定义大标题样式,可通过CompositionLocalProvider局部修改主题Typography,不影响全局:

CompositionLocalProvider(
    LocalTypography provides MaterialTheme.typography.copy(
        headlineLarge = MaterialTheme.typography.headlineLarge.copy(color = Color.Black)
    )
) {
    MediumTopAppBar(
        title = { Text(text = "pageTitle") },
        navigationIcon = {
            IconButton(onClick = { onBackPressed.invoke() }) {
                Icon(
                    imageVector = Icons.Filled.ArrowBack,
                    contentDescription = stringResource(id = R.string.action_back)
                )
            }
        },
        scrollBehavior = scrollBehavior
    )
}

默认MediumTopAppBar展开时使用headlineLarge样式,折叠时使用titleLarge样式,仅修改headlineLarge即可单独调整大标题样式。

方法三:自定义标题布局(精细控制)

若需要更灵活的动画和样式控制,可手动实现大、小标题的切换逻辑:

MediumTopAppBar(
    title = {
        val scrollState = scrollBehavior.state
        // 动画参数:控制缩放和透明度
        val scale by animateFloatAsState(
            targetValue = if (scrollState.collapsedFraction > 0.5f) 0.75f else 1f,
            animationSpec = tween(200)
        )
        val alpha by animateFloatAsState(
            targetValue = if (scrollState.collapsedFraction > 0.5f) 1f else 0f,
            animationSpec = tween(200)
        )

        // 大标题(自定义样式)
        Text(
            text = "pageTitle",
            style = MaterialTheme.typography.headlineLarge.copy(color = Color.Black),
            modifier = Modifier.alpha(1f - alpha)
        )
        // 小标题(默认样式)
        Text(
            text = "pageTitle",
            style = MaterialTheme.typography.titleLarge,
            modifier = Modifier
                .alpha(alpha)
                .scale(scale)
                .align(Alignment.CenterStart)
                .offset(y = (-16).dp * (1f - scale))
        )
    },
    navigationIcon = {
        IconButton(onClick = { onBackPressed.invoke() }) {
            Icon(
                imageVector = Icons.Filled.ArrowBack,
                contentDescription = stringResource(id = R.string.action_back)
            )
        }
    },
    scrollBehavior = scrollBehavior
)

内容的提问来源于stack exchange,提问作者Meyben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 18:15:40