flutter学习-day20-使用SafeArea组件处理各机型的安全距离

📚 目录

  1. 介绍
  2. 分析
  3. 示例和效果图
  4. 特殊情况

1. 介绍

安全区域,指的是移动端设备的可视窗口范围。处于安全区域的内容不受圆角、刘海屏、iPhone 小黑条、状态栏等的影响,也就是说,我们要做好适配,必须保证页面可视、可操作区域是在安全区域内,而 SafeArea 组件会自动进行屏幕适配,帮你空出所占高度。如下图所示:

2. 解析

实际上 SafeArea 也是一个 StatelessWidget,它本身不用主动去更新 ui,它仅仅是包裹了一层 Padding 和 MediaQuery.removePadding 的容器。它外层的 Padding 填充了被异形屏所遮挡的部分,而内部的 MediaQuery.removePadding 则是把这部分的填充距离给去掉,这样就保证了 SafeArea 包裹的子元素不会被异形屏所遮挡,且后续其 child 获取外部 Padding 的时候就不会再重复获取多余的 Padding 了。

SafeArea 的属性如下:

属性 说明 默认值
top 左侧是否需要有安全距离 false
left 左侧是否需要有安全距离 false
right 左侧是否需要有安全距离 false
bottom 左侧是否需要有安全距离 false
minimum 最小填充距离 EdgeInsets.zero
maintainBottomViewPadding 是否需要底部视图填充 false
child 子元素 Widget
dart 复制代码
const SafeArea({
  super.key,
  this.left = true,
  this.top = true,
  this.right = true,
  this.bottom = true,
  this.minimum = EdgeInsets.zero,
  this.maintainBottomViewPadding = false,
  required this.child,
});

3. 示例和效果图

如下,是一个没有设置安全距离的页面,可以看到,由于没有设置安全区域,所以页面顶部的一部分文字被状态栏给遮挡了:

dart 复制代码
Widget build(BuildContext context) {
  return Scaffold(
    body: Container(
      alignment: Alignment.center,
      child: Column(
        children: [
          Container(
            width: double.maxFinite,
            height: 60,
            color: Colors.black.withOpacity(0.15),
            child: const Text('我是一段文字',
                style: TextStyle(color: Colors.black, fontSize: 16)),
          ),
          Expanded(
              child: Container(
                  constraints: const BoxConstraints.expand(),
                  color: Colors.white))
        ],
      ),
    )
  );
}

如下,是设置了 SafeArea 的,可以看到,顶部页面内容没有被遮挡:

dart 复制代码
Widget build(BuildContext context) {
  return Scaffold(
    body: SafeArea(
      child: Container(
        alignment: Alignment.center,
        child: Column(
          children: [
            Container(
              width: double.maxFinite,
              height: 60,
              color: Colors.black.withOpacity(0.15),
              child: const Text('我是一段文字',
                  style: TextStyle(color: Colors.black, fontSize: 16)),
            ),
            Expanded(
                child: Container(
                    constraints: const BoxConstraints.expand(),
                    color: Colors.white))
          ],
        ),
      ),
    )
  );
}

4. 特殊情况

有的时候,我们的老手机等设备是没有底部栏的,这时获取的安全距离为 0。这种情况我们需要使用minimum属性定一个默认高度,来保证我们的内容不被遮挡。当设备有安全距离的时候,会从默认高度和安全距离中,取最大的那个。

dart 复制代码
Widget build(BuildContext context) {
  return Scaffold(
    body: SafeArea(
      // 当有底部安全距离的时候,会从默认高度和安全距离里取最大的那个
      minimum: const EdgeInsets.only(bottom: 20),
      child: Container(
        alignment: Alignment.center,
        child: Column(
          children: [
            Container(
              width: double.maxFinite,
              height: 60,
              color: Colors.black.withOpacity(0.15),
              child: const Text('我是一段文字',
                  style: TextStyle(color: Colors.black, fontSize: 16)),
            ),
            Expanded(
                child: Container(
                    constraints: const BoxConstraints.expand(),
                    color: Colors.white))
          ],
        ),
      ),
    )
  );
}

往期文章

个人主页

相关推荐
咸鱼加辣36 分钟前
【前端框架】react
前端·react.js·前端框架
ITKEY_38 分钟前
flutter 运行windows版本 Nuget.exe not found解决办法
flutter
kirk_wang44 分钟前
Flutter `flutter_statusbarcolor_ns` 在 OpenHarmony 平台的状态栏颜色适配实践
flutter·移动开发·跨平台·arkts·鸿蒙
不爱吃糖的程序媛44 分钟前
开源鸿蒙跨平台赋能:Flutter/RN/KMP/CMP 多栈适配
flutter·开源·harmonyos
走在路上的菜鸟1 小时前
Android学Dart学习笔记第二十二节 类-扩展方法
android·笔记·学习·flutter
子榆.1 小时前
【2025 最新实践】Flutter 与 OpenHarmony 的“共生模式”:如何构建跨生态应用?(含完整项目架构图 + 源码)
flutter·华为·智能手机·electron
Lethehong1 小时前
React构建实时股票分析系统:蓝耘MaaS平台与DeepSeek-V3.2的集成实践
前端·react.js·前端框架·蓝耘mcp·蓝耘元生代·蓝耘maas
kirk_wang1 小时前
Flutter 三方库在 OHOS 平台的适配实践:以 flutter_test_lib 为例
flutter·移动开发·跨平台·arkts·鸿蒙
巴拉巴拉~~1 小时前
KMP 算法通用折叠面板组件:KmpExpandablePanelWidget 平滑动画 + 单 / 多面板 + 全样式自定义
flutter
hudawei9962 小时前
对比kotlin和flutter中的异步编程
开发语言·flutter·kotlin·异步·