How to present an empty view in flutter as Widget.build cannot return null to indicate that there is nothing to render.
9 Answers
For anyone like me who was wondering what is "the correct way" to show an empty widget - official Material codebase uses this:
Widget build(BuildContext context) {
return SizedBox.shrink();
}
SizedBox.shrink()
is a widget that is unlike Container
or Material
has no background or any decorations whatsoever. It sizes itself to the smallest area possible, if not influenced by parent constraints.

- 9,401
- 5
- 33
- 37
-
10which basically just returns `SizedBox(width: 0, height: 0)` ! – Hannes Tiltmann Nov 27 '19 at 12:16
-
4this is the only answer that doesnt throw an error inside a listview – Adam Katz Mar 01 '20 at 12:31
-
Even though SizedBox.shrink is useful, it still takes some space in the screen, I would rather say it is like SizedBox(width: 5, height: 5) – Rami Osman Dec 13 '20 at 14:58
-
1This wont work if you using Column and Row, it will still count as a col and row item – test Oct 21 '21 at 10:05
-
There are many possible solutions of it. Like
-
Widget build(context) => SizedBox();
-
Widget build(context) => Container();
-
Widget build(context) => Scaffold();

- 237,138
- 77
- 654
- 440
-
1Returning as scaffold just to prevent returning `null` is not a good solution! Additionally, a container will fill its parent constraints, which can often be an undesired result. – jnt Dec 02 '22 at 11:30
-
@jnt I just listed different ways of doing it. The better one is `SizedBox` which is equivalent to `SizedBox.shrink()`. – CopsOnRoad Dec 02 '22 at 14:59
-
`SizedBox()` is technically not the same as `SizedBox.shrink()`, because `SizedBox()` will have its properties width and height set to null. However, I agree that it will have the same behaviour as `SizedBox.shrink()` if the box does not contain any element – Jack' May 10 '23 at 13:20
Performance
Container = 166,173 ms
SizedBox.shrink = 164,523 ms
DIY
main() async {
testWidgets('test', (WidgetTester tester) async {
await tester.pumpWidget( Container());
final Stopwatch timer = new Stopwatch()..start();
for (int index = 0; index < 5000000; index += 1) {
await tester.pump();
}
timer.stop();
debugPrint('Time taken: ${timer.elapsedMilliseconds}ms');
});
}

- 1,222
- 10
- 10
-
If you dont know where to put this code, press double shift and open `widget_test.dart` – Pratik Butani Aug 20 '21 at 11:58
-
how did you evaluate this time for both the widget. is there a way we can check our Widget time/performance anywhere? – Kapil Bansal Sep 27 '22 at 13:42
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
);
}
}
You can also simply return an empty Container
and avoid using the Scaffold
entirely. But this would result in a black screen if this is the only primary widget in you app, you can set the color
property of the Container
if you want to prevent the black background.
Example:
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white // This is optional
);
}
}

- 5,529
- 3
- 17
- 39

- 11,668
- 6
- 41
- 54
This may be too late but all of these solutions are not suitable in some scenarios like playing with PopupMenuItems
or affecting UI rendering!
Null safety Update
[
.
.
.
if(condition)...[//Conditionally widget(s) here
Something(...),
],
.
.
.
],
The solution is to remove null items before pass to the rendering component:
Column(
children: [
Text('Title'),
name != ''
? Text(name) //show name
: null // just pass a null we will filter it in next line!
].where((e) => e != null).toList()// Filter list and make it List again!
)
in this way, we can have a lot of null and UI will not affect by any empty Widget
.
PopupMenuButton
example where we cannot pass SizedBox :
PopupMenuButton(
icon: Icon(Icons.add),
itemBuilder: (context) => [
PopupMenuItem(
child: Row(children:[ Icon(Icons.folder), Text('So something')]),
value: 'do.something',
),
1 > 2 //⚠️ A false condition
? PopupMenuItem(
child: Row(children: [ Icon(Icons.file_upload), Text('⚠️No way to display ')]),
'no.way.to.display',
)
: null,// ⚠️ Passing null
PopupMenuItem(
child: Row(children: [ Icon(Icons.file_upload), Text('Do something else')]),
'do.something.else',
)
].where((e) => e != null).toList(),//ℹ️ Removing null items
onSelected: (item) {}
)
And this can be used as API with extension
:
extension NotNulls on List {
///Returns items that are not null, for UI Widgets/PopupMenuItems etc.
notNulls() {
return where((e) => e != null).toList();
}
}
//Usage:
PopupMenuButton(
icon: Icon(Icons.add),
itemBuilder: (context) => [
PopupMenuItem(
child: Row(children:[ Icon(Icons.folder), Text('So something')]),
value: 'do.something',
),
1 > 2 //⚠️ A false condition
? PopupMenuItem(
child: Row(children: [ Icon(Icons.file_upload), Text('⚠️No way to display ')]),
'no.way.to.display',
)
: null,// ⚠️ Passing null
PopupMenuItem(
child: Row(children: [ Icon(Icons.file_upload), Text('Do something else')]),
'do.something.else',
)
].notNulls(),//ℹ️ Removing null items
onSelected: (item) {}
)

- 1,309
- 16
- 20
-
Someone should performance test this. I imagine filtering nulls out of a short list will perform better than size boxes. As such, this might be a better solution even when sizebox or empty container is considered "good enough". – SpiRail Oct 31 '22 at 18:42
When a build function returns null, the error message from flutter is :
Build functions must never return null. To return an empty space that causes the building widget to fill available room, return "new Container()". To return an empty space that takes as little room as possible, return "new Container(width: 0.0, height: 0.0)".

- 469
- 2
- 7
- 16
-
Yes. If I run app in a null-safety regimen, I face this problem. So, I choose to follow your recommendation. – kokserek Jun 11 '21 at 06:08
The recommended widget to show nothing is to use SizedBox
.
SizedBox(
width: 200.0,
height: 300.0,
)

- 3,244
- 5
- 28
- 48
-
17
-
1Took me ages to reply, but SizedBox has been used inside first party widgets like AppBar to show something empty. – Aawaz Gyawali Oct 08 '21 at 07:54
-
1When creating a Container with width and height 0, Android Studio proposes to replace it with a SizedBox with width and height 0 in case you want to show nothing. – xuiqzy May 01 '23 at 01:01
My problem was very similar, but I found Container
and SizedBox.shrink
still affect the UI (frustratingly).
The best solution I've got is to build it differently using a named constructor and initializer list. An example of these would be:
class MyWidget extends StatelessWidget {
final String name = 'Default';
final bool hasThing = true;
MyWidget({this.name});
MyWidget.withoutThing({this.name}) : hasThing = false;
@override
Widget build(BuildContext context) {
//define widgets they have in common here (as many as possible)
if (hasThing) {
return Widget(child: Thing(this.name));
} else {
return Widget(child: WithoutThing(this.name));
}
}
}
And to use it:
Center(child: MyWidget.withoutThing(name: 'Foo'),)//don't show thing
or
Center(child: MyWidget(name: 'Foo'),)
based on your needs.
For more on initializer lists: Colon after Constructor in dart

- 37
- 5
-
What would the `Thing` and `WithoutThing` widgets look like? They're still widgets so they are not really empty and will still render. – Hans Vn Aug 17 '22 at 22:12
Inside Column
I am using SizedBox(height: 0.01)
Column(
children: [
Text('Title'),
name == ''
? SizedBox(height: 0.01) // show nothing
: Text(name) // show name
]
)

- 2,728
- 20
- 18
-
you are giving a very small size can't be check but still it will take the space. you can put 0.0 instead 0.01. the question was, how and what is the best best way to do the job. – Kapil Bansal Sep 27 '22 at 13:44