146

I am trying to understand the SafeArea widget in Flutter.

SafeArea code added to Flutter Gallery app here in github show top:false and bottom:false everywhere. Why do these need to be set false in these cases? enter image description here

Akhil
  • 13,888
  • 7
  • 35
  • 39
  • As per that discussion, The top and bottom are false now to avoid iPhone X UI fixe. – GvSharma Mar 12 '18 at 10:22
  • Can you add some explanation about which iPhone X UI fixes they are helping to avoid? I couldn't find anything related to that in the GitHub discussion. – Akhil Mar 12 '18 at 14:09
  • "https://github.com/flutter/flutter/issues/13594" => iPhone X: update Flutter Gallery demo to use safe area insets. Go through the comments and commits. – GvSharma Mar 13 '18 at 05:41
  • please check https://youtu.be/lkF0TQJO0bA – Dhaval Parmar Jan 21 '19 at 05:11

4 Answers4

326

SafeArea is basically a glorified Padding widget. If you wrap another widget with SafeArea, it adds any necessary padding needed to keep your widget from being blocked by the system status bar, notches, holes, rounded corners, and other "creative" features by manufacturers.

If you are using a Scaffold with an AppBar, the appropriate spacing will be calculated at the top of the screen without needing to wrap the Scaffold in a SafeArea and the status bar background will be affected by the AppBar color (Red in this example).

AppBar with no SafeArea

If you wrap the Scaffold in a SafeArea, then the status bar area will have a black background rather than be influenced by the AppBar.

AppBar wrapped with SafeArea

Here is an example without SafeArea set:

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

enter image description here

And again with the widget wrapped in a SafeArea widget:

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

enter image description here

You can set a minimum padding for edges not affected by notches and such:

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

enter image description here

You can also turn off the safe area insets for any side:

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

Setting them all to false would be the same as not using SafeArea. The default for all sides is true. Most of the time you will not need to use these settings, but I can imagine a situation where you have a widget that fills the whole screen. You want the top to not be blocked by anything, but you don't care about the bottom. In that case, you would just set bottom: false but leave the other sides to their default true values.

SafeArea(
  bottom: false,
  child: myWidgetThatFillsTheScreen,
)

Supplemental code

In case you want to play around more with this, here is 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.'),
      ),
    );
  }
}
Jeff Neet
  • 734
  • 1
  • 8
  • 22
Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
  • 5
    Is it a good practice to use SafeArea everytime I build a app? – Maruf Hassan Feb 13 '20 at 05:36
  • 3
    @MarufHassan I suppose that wouldn't hurt, though if you don't have anything important at the top and bottom it isn't necessary. So it depends on your UI content. – Suragch Feb 13 '20 at 06:32
  • I think the input from @Paras Sharma is also valid. When you have ConstrainedBox and a SafeArea then you will also need to reduze `mediaQueryData.padding.bottom` from available hight in the ContraintBox. – Adam Oct 26 '20 at 13:19
  • Is there a way to get the height of area above the safe area? – Janaka Oct 01 '22 at 05:10
18

When you wrap a widget A in a safe area, you are asking to the framework "Please, keep my widget A away from the device's UI navigation and notches".

The arguments 'top, bottom, right and left' are used to tell to the framework if you want him to avoid the device's intrusions from that sides specifically.

For example: if you put your widget A inside a safe area in the top of the screen and sets the "top" argument to false, it will be cropped by the iPhone's X and Pixel 3's notches.

Daniel Oliveira
  • 8,053
  • 11
  • 40
  • 76
4

SafeArea is a widget that sets its child by enough padding to avoid intrusions by the operating system and improve the user interface.

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(
    ),
  ),
);  }}
Paras Sharma
  • 181
  • 2
  • 3
    Just posting code without any explanation is not the best thing to do when it comes to understand your answer. – Logemann May 01 '20 at 16:25
2

Without using SafeArea in iPhone 12 pro max

enter image description here

With using SafeArea enter image description here

Code snippet using SafeArea

SafeArea(
   child: Text('Your Widget'),
)
Quick learner
  • 10,632
  • 4
  • 45
  • 55