ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

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

2026/10/5 6:53:07 拓冰建站 浏览量
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
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. 示例和效果图

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

被遮挡了

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 的,可以看到,顶部页面内容没有被遮挡:

没有被遮挡

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属性定一个默认高度,来保证我们的内容不被遮挡。当设备有安全距离的时候,会从默认高度和安全距离中,取最大的那个。

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))],),),));
}

往期文章

  • flutter学习-day1-环境搭建和启动第一个项目
  • flutter学习-day6-路由和传参和守卫
  • Vue2全家桶+Element搭建的PC端在线音乐网站
  • vue3+element-plus配置cdn
  • 助你上手Vue3全家桶之Vue3教程
  • 助你上手Vue3全家桶之VueX4教程
  • 助你上手Vue3全家桶之Vue-Router4教程
  • 超详细!Vue的九种通信方式
  • 超详细!Vuex手把手教程
  • 使用nvm管理node.js版本以及更换npm淘宝镜像源
  • vue中利用.env文件存储全局环境变量,以及配置vue启动和打包命令
  • 超详细!Vue-Router手把手教程

个人主页

  • CSDN
  • GitHub
  • 简书
  • 博客园
  • 掘金