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.
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:
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:
SafeArea
- Parameters
Key? key
: The widget's key.bool left
: Whether to avoid system intrusions on the left. Defaults totrue
.bool top
: Whether to avoid system intrusions on the top. Defaults totrue
.bool right
: Whether to avoid system intrusions on the right. Defaults totrue
.bool bottom
: Whether to avoid system intrusions on the bottom. Defaults totrue
.EdgeInsets minimum
: The minimum padding to apply. Defaults toEdgeInsets.zero
.bool maintainBottomViewPadding
: Whether it should maintain theMediaQueryData.viewPadding
instead of theMediaQueryData.padding
when consumed by theMediaQueryData.viewInsets
of the current context'sMediaQuery
. Defaults tofalse
.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.