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, // 控制 系统是否强制确保导航栏按钮(返回、主页、最近任务)与导航栏背景颜色有足够的对比度,以保证图标可读性。

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

相关推荐
Ashley的成长之路5 小时前
前端性能优化实战手册·第2篇:资源加载策略全解
前端·性能优化·资源加载·http/3·性能优化实战·资源加载优化
浅水壁虎5 小时前
vue基础(第二章 )
前端·javascript·vue.js
界面开发小八哥5 小时前
界面控件DevExtreme v26.1新版亮点——支持Angular 22
前端·javascript·angular.js·devexpress·ui开发·devextreme
Getflare5 小时前
前端 + UI 设计 + AI:这不是三个工种,是一个新三角能力模型(附自检清单)
前端·人工智能·ui
oil欧哟5 小时前
我做了一个 Vibe Coding 术语学习站:VibeHub
前端·ai·agent·独立开发·vibe coding
审小匠OpenCPAi6 小时前
银行流水核查怎么自动化?单边匹配、双向勾稽与图聚类异常检测的工程对比
java·前端·人工智能·python·审计
Revolution616 小时前
一个公共表格组件,是怎么一步步失控的
前端·前端工程化
腻害兔6 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:CRM 客户关系模块深度解析——从线索到回款,一套完整的 B2B 销售闭环是怎么搭的?
java·前端·javascript·vue.js·产品经理·ai编程
whyfail6 小时前
前端学 Spring Boot(2):一次点击,如何穿过整个后端?
前端·spring boot·后端