Flutter - Using SafeArea Widget Examples

This tutorial shows you how to use SafeArea in order to avoid application content from being clipped by intrusions such as status bar, hole/notch on a display, and the rounded corners part of a display.

Most Android and iOS smartphones have a status bar displayed on the top of the screen. Besides, there are a lot of new devices that come with super-slim bezels lately. To accommodate the front camera, those devices usually have a notch or a hole at the top of the screen. In addition, the display corners on recent phones are usually quite rounded. For mobile app developers, it may cause a problem that the application content can be clipped by the presence of those intrusions.

For example, we create a page that consists of a Text widget without AppBar.

  const Text(
    'Woolha.com is a blog about programming. You can find Flutter tutorials.',
    style: const TextStyle(fontSize: 18),
  )

The result can be seen in the below screenshot. As you can see, a piece of the text is clipped by the notch.

Flutter - without SafeArea

As more and more devices come with screens that have rounded corners and a hole or notch, it becomes very important to handle that problem. Luckily, Flutter already provides a widget called SafeArea. It works by insetting its child by sufficient padding to avoid intrusions. In this tutorial, I am going to show you how to use SafeArea.

Using SafeArea

The constructor of SafeArea is as follow.

  const SafeArea({
    Key? key,
    bool left = true,
    bool top = true,
    bool right = true,
    bool bottom = true,
    EdgeInsets minimum = EdgeInsets.zero,
    bool maintainBottomViewPadding = false,
    required Widget child,
  })

Using SafeArea requires you to pass a widget as child argument, while the other arguments are optional.

Let's try to wrap the Text above as the child of a SafeArea widget.

  const SafeArea(
    child: const Text(
      'Woolha.com is a blog about programming. You can find Flutter tutorials.',
      style: const TextStyle(fontSize: 18),
    ),
  )

Now the text is no longer clipped by the notch. That's because Flutter adds sufficient padding to the child, so that it will not be rendered in the area where the content can be intruded.

The constructor has four parameters that represent the four sides of the screen: left, top, right, and bottom. Those parameters are used to set whether to avoid system intrusions on the respective side. All of them are default to true, which means if you use SafeArea, by default Flutter will try to avoid system intrusions on all sides.

There is another argument minimum that can be used to set the minimum padding. You can pass an instance of EdgeInsets (which is usually used to set padding), so you can set the minimum padding for each side. The code below sets the minimum padding of all sides to 20.

  const SafeArea(
    minimum: EdgeInsets.all(20),
    child: const Text(
      'Woolha.com is a blog about programming. You can find Flutter tutorials.',
      style: const TextStyle(fontSize: 18),
    ),
  )

Output:

Flutter - SafeArea

From the result, you can see that the padding on each side follows the minimum value. If the padding on a side is already greater than the minimum value, it will not be affected. For example, if Flutter already adds padding on the top side (because of a notch, a hole, or the status bar) with a value greater than the minimum, the padding size on the top side will not change. The minimum value will still be applied even if the argument value of the respective side (left, top, right, and bottom) is false.

Output:

Flutter - SafeArea - Minimum

SafeArea - Parameters

  • Key? key: The widget's key.
  • bool left: Whether to avoid system intrusions on the left. Defaults to true.
  • bool top: Whether to avoid system intrusions on the top. Defaults to true.
  • bool right: Whether to avoid system intrusions on the right. Defaults to true.
  • bool bottom: Whether to avoid system intrusions on the bottom. Defaults to true.
  • EdgeInsets minimum: The minimum padding to apply. Defaults to EdgeInsets.zero.
  • bool maintainBottomViewPadding: Whether it should maintain the MediaQueryData.viewPadding instead of the MediaQueryData.padding when consumed by the MediaQueryData.viewInsets of the current context's MediaQuery. Defaults to false.
  • required Widget child: The widget below this widget in the tree.

?: value can be null.
required: value must be passed.

Full Code

  import 'package:flutter/material.dart';
  
  void main() => runApp(MyApp());
  
  class MyApp extends StatelessWidget {
  
    @override
    Widget build(BuildContext context) {
      return MaterialApp(
        title: 'Woolha.com Flutter Tutorial',
        home: Scaffold(
          body: SafeAreaExample(),
        ),
      );
    }
  }
  
  class SafeAreaExample extends StatelessWidget {
  
    @override
    Widget build(BuildContext context) {
      return const SafeArea(
        minimum: EdgeInsets.all(20),
        child: const Text(
          'Woolha.com is a blog about programming. You can find Flutter tutorials.',
          style: const TextStyle(fontSize: 18),
        ),
      );
    }
  }

Summary

If you're developing an application using Flutter, avoiding content being clipped by system intrusions can be done by using SafeArea widget. You can set on which sides the system intrusions should be avoided and also the minimum padding to be applied on each side.