Flutter中的沉浸式模式设置

Flutter中的沉浸式模式设置

为什么会想要设置沉浸式模式?

Flutter中关于尺寸的适配问题需要避开顶部状态栏与底部导航条,为了方便这些尺寸的书写以及好看。

接下来说说沉浸式模式遇到的几种坑,以及沉浸式最终的实现方式:

最终实现方案:

沉浸式适配工具类:

dart 复制代码
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class ImmersiveUtil {
  static Future<void> init() async {
    final deviceInfo = DeviceInfoPlugin();
    final androidInfo = await deviceInfo.androidInfo;
    final sdk = androidInfo.version.sdkInt; // 直接拿到 SDK 数字,比如 33 = Android 13
    final release = androidInfo.version.release; // Android 版本字符串,比如 "13"
    logger.d(release);
    if (sdk >= 34) {
      // Android 14、15 用 immersiveSticky
      _immersiveSticky();
    } else {
      // Android 13 及以下用透明状态栏+导航栏
      _edgeToEdge();
    }
  }

  /// 透明状态栏 + 导航栏
  static void _edgeToEdge() {
    SystemChrome.setEnabledSystemUIMode(
      SystemUiMode.manual,
      overlays: [SystemUiOverlay.top],
    );
    SystemChrome.setSystemUIOverlayStyle(
      const SystemUiOverlayStyle(
        statusBarColor: Colors.transparent,
        statusBarIconBrightness: Brightness.dark,
        systemNavigationBarContrastEnforced: false,
      ),
    );
  }

  /// 自动沉浸式(手势呼出后几秒自动隐藏)
  static void _immersiveSticky() {
    SystemChrome.setEnabledSystemUIMode(
      SystemUiMode.immersiveSticky,
      overlays: [],
    );
    SystemChrome.setSystemUIOverlayStyle(
      const SystemUiOverlayStyle(
        statusBarColor: Colors.transparent,
        statusBarIconBrightness: Brightness.dark,
        systemNavigationBarContrastEnforced: false,
      ),
    );
  }
}

调用:

dart 复制代码
await ImmersiveUtil.init();
runApp(OKToast(child: Phoenix(child: MyApp())));

遇到的问题:

为什么要采用不同Android版本来进行不同的沉浸式适配呢?

我起初因为导航条的黑色背景想要全局设置透明,但是一直不生效;所以采用自动沉浸式模式,来实现系统几秒后自动关闭状态栏和导航栏。经过测试SystemUiMode.immersiveSticky的自动沉浸式在Android13版本下会出现顶部状态栏虽然消失但是状态栏的位置会留下一条黑色背景。于是采用分版本显示,但是导航栏的颜色还是设置不了影响体验,经过最终尝试把systemNavigationBarContrastEnforced:false, // 控制系统是否强制确保导航栏按钮(返回、主页、最近任务)与导航栏背景颜色有足够的对比度,以保证图标可读性。的这个属性设置为false就实现了导航栏透明,其他的导航栏配置都是不起作用的,只能通过这个属性来控制导航栏的黑色与透明(可能是系统厂商的高度定制问题)

各属性配置代表什么:

这里主要是配置状态栏和导航栏怎么样显示以及显示哪些:

dart 复制代码
SystemChrome.setEnabledSystemUIMode(
      SystemUiMode.manual,
      overlays: [SystemUiOverlay.top],
    );

📌 SystemUiMode 枚举的可选值及作用:

SystemUiMode.manual

  • 手动控制显示哪些系统 UI(通过 overlays 参数指定)。
  • 一般配合 SystemUiOverlay.values(即 statusBarnavigationBar)使用。
  • 适合需要自己决定显示/隐藏状态栏、导航栏的情况。
ini 复制代码
SystemChrome.setEnabledSystemUIMode(
  SystemUiMode.manual,
  overlays: [SystemUiOverlay.top], // 只显示状态栏
);

SystemUiMode.leanBack

  • 轻量全屏模式。
  • 系统栏(状态栏、导航栏)会被隐藏,但用户 轻触屏幕任意位置时会再次显示
  • 适合临时全屏,比如视频播放时。

SystemUiMode.immersive

  • 沉浸模式。
  • 系统栏会隐藏,用户需要 从屏幕边缘滑动 才能唤出。
  • 唤出后会 停留,直到用户手动操作。
  • 常用于游戏或需要较强沉浸感的应用。

SystemUiMode.immersiveSticky

  • 粘性沉浸模式。
  • 系统栏同样需要 从屏幕边缘滑动 才能唤出,但 几秒后会自动隐藏
  • 常用于阅读器、沉浸式视频播放等场景。

SystemUiMode.edgeToEdge

  • 边到边模式。
  • 状态栏和导航栏会保持显示,但应用内容可以绘制到系统栏的区域(需设置透明背景色)。
  • 常用于现代应用的沉浸式设计(比如顶部大图延伸到状态栏)。
less 复制代码
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
SystemChrome.setSystemUIOverlayStyle(
  const SystemUiOverlayStyle(
    statusBarColor: Colors.transparent,
    systemNavigationBarColor: Colors.transparent,
  ),
);

总结对比:

模式 系统栏显示 唤出方式 适用场景
manual 自定义 根据 overlays 精细控制
leanBack 隐藏,点屏幕可唤出 点击 视频播放
immersive 隐藏,边缘滑动可唤出 滑动边缘 游戏
immersiveSticky 隐藏,滑动边缘可唤出,几秒后自动隐藏 滑动边缘 阅读、全屏视频
edgeToEdge 显示(透明) 常显 现代 UI、沉浸式布局

这里主要是配置状态栏和导航栏的颜色样式:

dart 复制代码
SystemChrome.setSystemUIOverlayStyle(
      const SystemUiOverlayStyle(
        statusBarColor: Colors.transparent,
        statusBarIconBrightness: Brightness.dark,
        systemNavigationBarContrastEnforced: false,
      ),
    );

我设置了很多不起作用,只能说这里想要全局底部导航栏透明设置:

dart 复制代码
systemNavigationBarContrastEnforced: false, // 控制 系统是否强制确保导航栏按钮(返回、主页、最近任务)与导航栏背景颜色有足够的对比度,以保证图标可读性。

就可以了,设置其他属性状态栏颜色导航栏颜色什么的都不起作用。

相关推荐
云水一下2 小时前
从零开始!VMware安装Fedora Workstation 44桌面系统完整教程
前端
小码哥_常3 小时前
安卓黑科技:实现多平台商品详情页一键跳转APP
前端
killerbasd3 小时前
还是迷茫 5.3
前端·react.js·前端框架
不会敲代码14 小时前
TCP/IP 与前端性能:从数据包到首次渲染的底层逻辑
前端·tcp/ip
kyriewen4 小时前
奥特曼借GPT-5.5干杯,而你的Copilot正按Token收钱
前端·github·openai
AC赳赳老秦4 小时前
投标合规提效:用 OpenClaw 实现标书 / 合同自动审核、关键词校验、格式优化,降低废标风险
开发语言·前端·python·eclipse·emacs·deepseek·openclaw
kyriewen4 小时前
代码写成一锅粥?3个设计模式让你的项目“起死回生”
前端·javascript·设计模式
千寻girling4 小时前
《 Git 详细教程 》
前端·后端·面试
之歆6 小时前
DAY08_CSS浮动与行内块布局实战指南(下)
前端·css
yqcoder6 小时前
CSS Position 全解析:5 种定位模式详解
前端·css