在 Flutter 中使用 SafeArea

Posted

技术标签:

【中文标题】在 Flutter 中使用 SafeArea【英文标题】:Using SafeArea in Flutter 【发布时间】:2018-08-20 00:38:30 【问题描述】:

我正在尝试理解 Flutter 中的 SafeArea 小部件。

SafeArea 代码添加到 Flutter Gallery 应用程序 here 在 github 中显示 top:falsebottom:false 无处不在。为什么在这些情况下需要将这些设置为 false?

【问题讨论】:

根据该讨论,顶部和底部现在是错误的,以避免修复 iPhone X UI。 您能否就他们正在帮助避免的 iPhone X UI 修复添加一些解释?我在 GitHub 讨论中找不到与此相关的任何内容。 "github.com/flutter/flutter/issues/13594" => iPhone X:更新 Flutter Gallery 演示以使用安全区域插图。浏览 cmets 和提交。 请查看youtu.be/lkF0TQJO0bA 【参考方案1】:

SafeArea 基本上是一个美化的Padding 小部件。如果您使用SafeArea 包装另一个小部件,它会添加任何必要的填充,以防止您的小部件被系统状态栏、槽口、孔、圆角和制造商的其他“创意”功能阻挡。

如果您使用带有 AppBar 的 Scaffold,则会在屏幕顶部计算适当的间距,而无需将 Scaffold 包裹在 SafeArea 中,并且状态栏背景将受到 AppBar 颜色的影响(此处为红色)示例)。

如果将 Scaffold 包裹在 SafeArea 中,则状态栏区域将具有黑色背景,而不受 AppBar 的影响。

这是一个没有设置SafeArea的例子:

Align(
  alignment: Alignment.topLeft,  // and bottomLeft
  child: Text('My Widget: ...'),
)

再次将小部件包装在 SafeArea 小部件中:

Align(
  alignment: Alignment.topLeft,  // and bottomLeft
  child: SafeArea(
    child: Text('My Widget: ...'),
  ),
)

您可以为不受槽口等影响的边缘设置最小填充:

SafeArea(
  minimum: const EdgeInsets.all(16.0),
  child: Text('My Widget: ...'),
)

您还可以关闭任何一侧的安全区域插入:

SafeArea(
  left: false,
  top: false,
  right: false,
  bottom: false,
  child: Text('My Widget: ...'),
)

将它们全部设置为 false 与不使用 SafeArea 相同。所有边的默认值为true。大多数时候你不需要使用这些设置,但我可以想象这样一种情况,你有一个小部件填满整个屏幕。你希望顶部不被任何东西阻挡,但你不关心底部。在这种情况下,您只需设置 bottom: false,而将其他边保留为默认的 true 值。

SafeArea(
  bottom: false,
  child: myWidgetThatFillsTheScreen,
)

补充代码

如果你想玩更多,这里是 main.dart

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: BodyWidget(),
      ),
    );
  


class BodyWidget extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return Align(
      alignment: Alignment.topLeft,
      child: SafeArea(
        left: true,
        top: true,
        right: true,
        bottom: true,
        minimum: const EdgeInsets.all(16.0),
        child: Text(
            'My Widget: This is my widget. It has some content that I don\'t want '
            'blocked by certain manufacturers who add notches, holes, and round corners.'),
      ),
    );
  

【讨论】:

每次构建应用时都使用 SafeArea 是一种好习惯吗? @MarufHassan 我想这不会有什么坏处,但如果你在顶部和底部没有任何重要的东西,那就没有必要了。所以这取决于你的 UI 内容。 我认为@Paras Sharma 的输入也是有效的。当您拥有 ConstrainedBox 和 SafeArea 时,您还需要从 ContraintBox 中的可用高度减少 mediaQueryData.padding.bottom【参考方案2】:

在 iPhone 12 pro max 中不使用 SafeArea

使用 SafeArea

使用 SafeArea 编码 sn-p

SafeArea(
   child: Text('Your Widget'),
)

【讨论】:

这是一个很好的例子【参考方案3】:

SafeArea 是一个小部件,它通过足够的填充设置其子级,以避免操作系统的入侵并改善用户界面。

import 'package:flutter/material.dart';

class SafeArea extends StatefulWidget 
 @override
 _SafeAreaState createState() => _SafeAreaState();
  

 class _SafeAreaState extends State<SafeArea> 
  @override
  Widget build(BuildContext context) 
   MediaQueryData mediaQueryData=MediaQuery.of(context);
   double screenWidth = mediaQueryData.size.width;
   var bottomPadding=mediaQueryData.padding.bottom;

return Padding(
  padding: EdgeInsets.only(bottom: bottomPadding),
  child: Scaffold(
    body: new Container(
    ),
  ),
);  

【讨论】:

在理解你的答案时,仅仅发布代码而不做任何解释并不是最好的做法。【参考方案4】:

当您将小部件 A 包装在安全区域中时,您是在向框架请求“请让我的小部件 A 远离设备的 UI 导航和凹槽” .

参数'top、bottom、right和left'用于告诉框架你是否希望他专门避免设备从那一侧侵入。

例如:如果您将小部件 A 放在屏幕顶部的安全区域内并将“top”参数设置为 false,它将被裁剪iPhone X 和 Pixel 3 的凹槽。

【讨论】:

以上是关于在 Flutter 中使用 SafeArea的主要内容,如果未能解决你的问题,请参考以下文章

在 Flutter Web 中使用 Flutter 移动包

如何使用 flutter_webview 插件在 Flutter 中启用位置?

在flutter中使用Chopper网络库和flutter_bloc库

Flutter : 在 Flutter web 中使用 Froala-editor

如何在flutter中使用flutter_webview_plugin和AndroidX

在 Flutter 中使用 webview_flutter 4.0 | 基础用法与事件处理