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

NavigationBarThemeData中MaterialState不生效,标签颜色无法区分选中状态

问题描述

我尝试根据NavigationBar项目是否选中来修改标签文本颜色,但Flutter为所有标签设置了同一种颜色。打印每个项的状态时,发现始终为MaterialState.pressed。

当前代码:

NavigationBarTheme(
            data: NavigationBarThemeData(
                backgroundColor: Theme.of(context)
                    .extension<MyExtension>()!
                    .white,
                labelTextStyle: MaterialStateProperty.resolveWith(
                    (state) {
                      return state == MaterialState.selected
                        ? Theme.of(context).textTheme.caption!.copyWith(
                        color: Theme.of(context)
                            .extension<MyExtension>()!
                            .black,
                      )
                        : Theme.of(context).textTheme.caption!.copyWith(
                              color: Theme.of(context)
                                  .extension<MyExtension>()!
                                  .grey3,
                            );
                    }),
                indicatorColor: Theme.of(context)
                    .extension<MyExtension>()!
                    .grey2),

当前效果:
当前效果

解决方案

问题出在状态判断的逻辑上——MaterialStateProperty.resolveWith传入的state是一个状态集合(Set<MaterialState>),不是单个状态值,直接用==判断永远匹配不到MaterialState.selected。

修改代码,改用state.contains(MaterialState.selected)来检测选中状态即可:

NavigationBarTheme(
  data: NavigationBarThemeData(
    backgroundColor: Theme.of(context).extension<MyExtension>()!.white,
    labelTextStyle: MaterialStateProperty.resolveWith((states) {
      // 检测状态集合中是否包含选中状态
      if (states.contains(MaterialState.selected)) {
        return Theme.of(context).textTheme.caption!.copyWith(
          color: Theme.of(context).extension<MyExtension>()!.black,
        );
      }
      return Theme.of(context).textTheme.caption!.copyWith(
        color: Theme.of(context).extension<MyExtension>()!.grey3,
      );
    }),
    indicatorColor: Theme.of(context).extension<MyExtension>()!.grey2,
  ),
  // 必须用child包裹你的NavigationBar,确保主题生效
  child: NavigationBar(
    selectedIndex: // 这里要正确设置选中的索引值
    destinations: // 你的导航项配置
  ),
)

额外注意:

  • 要确保NavigationBar正确设置了selectedIndex,且被NavigationBarTheme的child属性包裹,否则主题不会作用到导航栏上
  • 调试时可以直接打印states,会输出当前所有激活的状态集合,选中时会明确包含MaterialState.selected

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 05:55:00