flutter:SystemUiOverlayStyle与状态栏

SystemUiOverlayStyle 是什么

  • 它是 Flutter 提供的 控制系统状态栏和导航栏样式的类
  • 用来设置 状态栏 / 导航栏的颜色、亮度、图标颜色等。
  • 本质上是 对 Android/iOS 系统 UI 元素的样式请求,Flutter 会把这些信息通过 Platform Channel 发送给系统。
  • 注意:
    • 在 Android 13+(API ≥ 33)上,statusBarColor 可能不生效,因为系统默认透明状态栏。
    • 它只控制 样式和图标亮度,不是布局或者 UI 内容。

主要属性:改图标

属性 说明 Android 支持 iOS 支持 补充说明
statusBarColor 状态栏背景色 部分 API 版本生效(<33 有效,13+ 默认透明可能无效) 无效(状态栏透明) Android 13+ 可能被系统透明覆盖,需要手动绘制
statusBarIconBrightness 状态栏图标亮度(黑/白) 可控制图标颜色 无效 一般可用,Android 13+ 同样有效
statusBarBrightness 状态栏内容亮度 通常忽略 控制图标颜色 iOS 主要依赖此属性
systemNavigationBarColor 底部导航栏背景色 可用 全面屏手势模式下大部分机型不可见
systemNavigationBarIconBrightness 底部导航栏图标亮度 可用 全面屏手势模式下不可见
systemNavigationBarDividerColor 底部分割线颜色 可用 仅在导航栏可见时有效
systemStatusBarContrastEnforced 是否强制对比(Android 10+) 可用 Android 10+ 可强制状态栏图标对比

总结:现在主要起到作用的就是statusBarBrightnessstatusBarIconBrightness

属性 含义 显示效果
statusBarIconBrightness Brightness.dark 图标和文字为深色(黑色) 适合浅色背景
Brightness.light 图标和文字为浅色(白色) 适合深色背景
statusBarBrightness Brightness.dark 背景是深色(暗),图标 白色 适合深色背景
Brightness.light 背景是浅色(亮),图标 黑色 适合浅色背景

如何配置

全局配置

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  // 全局设置状态栏和导航栏样式
  SystemChrome.setSystemUIOverlayStyle(
    const SystemUiOverlayStyle(
      statusBarColor: Colors.red,               // 状态栏背景色(Android <13)
      statusBarIconBrightness: Brightness.dark, // 状态栏图标颜色(Android)
      statusBarBrightness: Brightness.light,    // 状态栏图标颜色(iOS)
      systemNavigationBarColor: Colors.black,   // 底部导航栏背景色
      systemNavigationBarIconBrightness: Brightness.light, // 导航栏图标颜色
    ),
  );

  runApp(const MyApp());
}
  • 优点:简单,App 内所有页面都生效。
  • 缺点:无法针对单独页面做不同风格。

单页面 / AppBar 内配置

AppBar(
  title: const Text("Demo"),
  backgroundColor: Colors.transparent, // 或自定义颜色
  elevation: 0,
  systemOverlayStyle: const SystemUiOverlayStyle(
    statusBarColor: Colors.red,
    statusBarIconBrightness: Brightness.dark,
    statusBarBrightness: Brightness.light,
  ),
)
  • 优点:覆盖全局设置,页面可单独配置状态栏风格。
  • 注意:AppBar 的背景色和状态栏颜色会联动,透明 AppBar 可让内容延伸到状态栏。

使用 AnnotatedRegion 覆盖整个页面

如果页面没有 AppBar,或者你想完全自定义状态栏:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  // // 全局设置状态栏颜色和图标
  // SystemChrome.setSystemUIOverlayStyle(
  //   const SystemUiOverlayStyle(
  //     statusBarColor: Colors.red, // Android 状态栏背景
  //     statusBarIconBrightness: Brightness.light, // 图标白色
  //     statusBarBrightness: Brightness.dark, // iOS 图标白色
  //   ),
  // );

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: AnnotatedRegion<SystemUiOverlayStyle>(
        value: const SystemUiOverlayStyle(
          statusBarColor: Colors.red, // Android 状态栏背景
          statusBarIconBrightness: Brightness.dark, // 图标黑色
          statusBarBrightness: Brightness.dark, // iOS 图标白色
        ),
        child: Scaffold(
          body: Column(
            children: [
              // 自定义 AppBar 区域
              SafeArea(
                child: Container(
                  height: 56, // 标准 AppBar 高度
                  padding: const EdgeInsets.symmetric(horizontal: 16),
                  color: Colors.black, // 可改为透明或其他颜色
                  alignment: Alignment.centerLeft,
                  child: const Text(
                    "自定义 AppBar",
                    style: TextStyle(
                      color: Colors.white,
                      fontSize: 20,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                ),
              ),
              // 页面主体内容
              Expanded(
                child: Container(
                  color: Colors.blue, // 背景色填充到状态栏下
                  child: const Center(
                    child: Text(
                      "Hello Flutter",
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

左边是Android 16statusBarColor没有生效。右边是Android 12statusBarColor 生效了。

AppBar对状态栏的影响

AppBar 的状态栏控制原理

  • AppBar 在 Flutter 中其实是一个 高度固定的 Container,默认会占据状态栏下方的高度。

  • AppBar 有一个 systemOverlayStyle 属性,用来控制状态栏的样式(颜色、图标亮度)。

  • 如果 AppBar 设置了背景色,系统通常会把状态栏背景与 AppBar 背景统一。

  • 如果 AppBar 透明backgroundColor: Colors.transparent),状态栏可能显示底层内容,或者保持透明。

AppBar 对状态栏的影响总结

情况 AppBar 背景色 状态栏颜色 状态栏图标亮度
AppBar 有背景色(非透明) AppBar 背景色 会被覆盖为 AppBar 背景色 systemOverlayStyle 的图标亮度
AppBar 透明或半透明 透明 状态栏透明,显示 Scaffold/内容背景 systemOverlayStyle 的图标亮度
不设置 systemOverlayStyle AppBar 背景色 Android 默认和 AppBar 背景一致 Android 默认亮色或深色图标(取决于背景)
设置 systemOverlayStyle AppBar 背景色 不影响背景,但控制图标亮度 iOS/Android 根据该属性控制图标颜色

状态栏的优先级

如果 AppBar 设置了 systemOverlayStyle,它会覆盖全局或 AnnotatedRegion 的设置。

  1. AppBar 的 systemOverlayStyle(单页面覆盖)
  2. 页面顶部的 AnnotatedRegion<SystemUiOverlayStyle>(局部覆盖)
  3. SystemChrome.setSystemUIOverlayStyle()(全局默认)

×

喜欢就点赞,疼爱就打赏