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

Flutter中如何仅在特定页面修改状态栏颜色?解决AnnotatedRegion导致全局状态栏变色的问题

我之前也踩过这个坑!用AnnotatedRegion实现特定页面状态栏变色时,如果没处理好路由切换后的样式重置,很容易导致全局状态栏颜色都被改掉。下面给你几个经过验证的解决方案,按需选择:

解决方案1:在目标页面单独处理,退出时重置样式

这个方案最直接——在需要自定义状态栏的页面外层包裹AnnotatedRegion,同时监听页面退出事件,手动恢复默认的状态栏样式。

class CustomStatusBarPage extends StatefulWidget {
  const CustomStatusBarPage({super.key});

  @override
  State<CustomStatusBarPage> createState() => _CustomStatusBarPageState();
}

class _CustomStatusBarPageState extends State<CustomStatusBarPage> {
  // 保存页面进入前的默认状态栏样式
  late SystemUiOverlayStyle _defaultStatusStyle;

  @override
  void initState() {
    super.initState();
    // 获取当前的默认样式(也可以根据主题直接定义)
    _defaultStatusStyle = SystemUiOverlayStyle.light.copyWith(
      statusBarColor: Theme.of(context).appBarTheme.backgroundColor,
    );
  }

  @override
  Widget build(BuildContext context) {
    return PopScope(
      canPop: true,
      onPopInvoked: (didPop) {
        if (didPop) {
          // 页面返回时,恢复默认状态栏样式
          SystemChrome.setSystemUIOverlayStyle(_defaultStatusStyle);
        }
      },
      child: AnnotatedRegion<SystemUiOverlayStyle>(
        value: const SystemUiOverlayStyle(
          statusBarColor: Colors.deepOrange, // 目标页面的状态栏颜色
          statusBarIconBrightness: Brightness.light, // 适配图标亮度,避免看不见
        ),
        child: Scaffold(
          // 如果用AppBar,要关闭它自带的状态栏样式,避免冲突
          appBar: AppBar(
            title: const Text("自定义状态栏页面"),
            systemOverlayStyle: SystemUiOverlayStyle.dark.copyWith(
              statusBarColor: Colors.transparent,
            ),
          ),
          body: const Center(child: Text("这是状态栏为橙色的页面")),
        ),
      ),
    );
  }
}

为什么要这么做?
AnnotatedRegion的样式会沿着Widget树向上传递,如果页面退出时不手动重置,上一个页面的样式不会自动恢复,就会出现全局变色的问题。

解决方案2:通过路由全局管理状态栏样式

如果有多个页面需要自定义状态栏,可以把样式配置和路由绑定,在路由跳转时统一处理:

MaterialApp(
  initialRoute: '/',
  onGenerateRoute: (settings) {
    switch (settings.name) {
      case '/custom-red':
        return MaterialPageRoute(
          builder: (context) {
            return AnnotatedRegion<SystemUiOverlayStyle>(
              value: const SystemUiOverlayStyle(
                statusBarColor: Colors.red,
                statusBarIconBrightness: Brightness.light,
              ),
              child: const RedStatusBarPage(),
            );
          },
        );
      case '/custom-blue':
        return MaterialPageRoute(
          builder: (context) {
            return AnnotatedRegion<SystemUiOverlayStyle>(
              value: const SystemUiOverlayStyle(
                statusBarColor: Colors.blue,
                statusBarIconBrightness: Brightness.light,
              ),
              child: const BlueStatusBarPage(),
            );
          },
        );
      default:
        return MaterialPageRoute(
          builder: (context) {
            // 回到首页时恢复默认样式
            SystemChrome.setSystemUIOverlayStyle(
              SystemUiOverlayStyle.light.copyWith(
                statusBarColor: Theme.of(context).primaryColor,
              ),
            );
            return const HomePage();
          },
        );
    }
  },
);

这种方式把状态栏样式和路由强绑定,切换路由时自动应用对应样式,不用每个页面单独写重置逻辑。

解决方案3:用第三方插件简化操作

如果不想手动写重置逻辑,可以用flutter_statusbar_manager插件,它能更便捷地控制状态栏样式,且在页面销毁时自动恢复:

class GreenStatusBarPage extends StatefulWidget {
  const GreenStatusBarPage({super.key});

  @override
  State<GreenStatusBarPage> createState() => _GreenStatusBarPageState();
}

class _GreenStatusBarPageState extends State<GreenStatusBarPage> {
  late Color _defaultBarColor;

  @override
  void initState() {
    super.initState();
    // 保存默认颜色
    _defaultBarColor = SystemChrome.latestStyle?.statusBarColor ?? Colors.transparent;
    // 设置自定义状态栏颜色
    FlutterStatusbarManager.setColor(Colors.green);
    // 可选:设置图标亮度
    FlutterStatusbarManager.setStyle(StatusBarStyle.LIGHT_CONTENT);
  }

  @override
  void dispose() {
    // 页面销毁时恢复默认颜色
    FlutterStatusbarManager.setColor(_defaultBarColor);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("插件实现")),
      body: const Center(child: Text("状态栏为绿色")),
    );
  }
}
关键注意事项
  • 一定要适配statusBarIconBrightness:深色状态栏用Brightness.light,浅色状态栏用Brightness.dark,不然图标会和状态栏颜色融合,导致用户看不见。
  • 如果页面使用了AppBar,记得关闭它自带的状态栏样式(设置systemOverlayStyle为透明背景),避免和AnnotatedRegion的样式冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 23:02:39