Do you want to set the color, brightness, and transparency of the status bar when your Flutter application is running in the foreground? Find out in this tutorial.
Operating systems like Android and iOS have a status bar on the top of the screen where the user can see information such as time, battery level, and notifications. Sometimes, changing the appearance of the status bar according to the application theme may result in a better look. If you create an application using Flutter, setting the style of the status bar can be done easily by using AppBar
, SystemChrome
, or AnnotatedRegion
. Below are the examples.
Using AppBar
If your application includes an AppBar
at the top, by default the AppBar
affects the status bar appearance. Therefore, you can modify the AppBar
in order to change the status bar.
Set Color
The color of the AppBar
is applied to the status bar by default, with a semi-transparent overlay on the top of the status bar. You can change the color by passing backgroundColor
property to the constructor of AppBar
.
AppBar(
title: const Text('Woolha.com Flutter Tutorial'),
backgroundColor: Colors.teal,
)
Output:
Set Brightness
The brightness
property of AppBar
can be used to set the brightness of SystemUiOverlayStyle
. This can be used to set the color of the icons on the status bar. If you set the brightness
to Brightness.dark
, SystemUiOverlayStyle.light
will be used and the color of the icons will be set to light. Otherwise, if you set the brightness
to Brightness.light
, SystemUiOverlayStyle.dark
will be used and the color of the icons will be set to dark. AppBarTheme.brightness
will be used if you don't pass the value.
However, using AppBar
's brightness
to set SystemUiOverlayStyle
is obsolete. You should use systemOverlayStyle
instead.
AppBar(
title: const Text('Woolha.com Flutter Tutorial'),
backgroundColor: Colors.teal,
brightness: Brightness.dark,
)
Output:
Full Code
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Woolha.com Flutter Tutorial',
home: Scaffold(
appBar: AppBar(
title: const Text('Woolha.com Flutter Tutorial'),
backgroundColor: Colors.teal,
brightness: Brightness.dark,
),
body: const Center(
child: const Text('by Woolha.com', style: const TextStyle(fontSize: 36)),
),
),
);
}
}
Output:
Using SystemChrome
There is another way to set the style of the status bar. You can use SystemChrome.setSystemUIOverlayStyle
, which is used to set the SystemUiOverlayStyle
. While the previous way (using AppBar
only works if you have an AppBar
on the top, the SystemChrome.setSystemUIOverlayStyle
should only be used if you don't have an AppBar
or CupertinoNavigationBar
. If you call the static method, the change will persist across all routes in your application. Therefore, if the user navigates to another route, the applied style will not disappear until the SystemChrome.setSystemUIOverlayStyle
is called again to override the style.
The method can be called anywhere. If you want to apply the same style to all routes in your application, you can call it inside the main
method. If you want to have different styles for each page or route, you need to call the method inside the respective widget. For example, you can put it inside the initState
or build
method. Beware that using the method along with certain widgets such as AppBar
or CupertinoNavigationBar
may produce unexpected results since those widget may override the style.
Set Color
The color of the status bar can be set by passing a Color
as the statusBarColor
argument.
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Colors.purple,
));
Output:
Set Transparency/Opacity
To make the status bar looks transparent, you can set the opacity of the color.
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Colors.purple.withOpacity(0.3),
));
Output:
Set Brightness
The brightness of the top status bar icons can be set by passing statusBarIconBrightness
whose type is Brightness
enum. It only affects Android version M and greater. If you set the value to Brightness.light
, the icons color will be set to light. Otherwise, if you set the value to Brightness.dark
, the icons color will be set to dark.
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Colors.purple,
statusBarIconBrightness: Brightness.light,
));
Output:
For iOS, the brightness of the top status bar can be set by passing the statusBarBrightness
argument.
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Colors.purple,
statusBarBrightness: Brightness.light,
));
Full Code
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Woolha.com Flutter Tutorial',
initialRoute: '/one',
routes: {
'/one': (context) => PageOne(),
'/two': (context) => PageTwo(),
},
);
}
}
class PageOne extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Colors.yellow,
statusBarBrightness: Brightness.dark,
statusBarIconBrightness: Brightness.dark,
));
return Scaffold(
body: SizedBox.expand(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Woolha.com - One', style: const TextStyle(color: Colors.black)),
OutlinedButton(
child: const Text('Go to PageTwo'),
onPressed: () {
Navigator.popAndPushNamed(context, "/two");
},
),
],
),
),
);
}
}
class PageTwo extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Colors.purple.withOpacity(0.3),
statusBarBrightness: Brightness.light,
statusBarIconBrightness: Brightness.light,
));
return Scaffold(
body: SizedBox.expand(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Woolha.com - Two', style: const TextStyle(color: Colors.black)),
OutlinedButton(
child: const Text('Go to PageOne'),
onPressed: () {
Navigator.popAndPushNamed(context, "/one");
},
),
],
),
),
);
}
}
Output:
Using AnnotatedRegion
Flutter has a generic class named AnnotatedRegion<T extends Object>
, which is used to annotate a region of the layer tree with a value.
const AnnotatedRegion({
Key? key,
required Widget child,
required dynamic value,
bool sized = true,
})
You can set SystemUiOverlayStyle
as the generic type (AnnotatedRegion<SystemUiOverlayStyle>
). Therefore, you can pass SystemUiOverlayStyle
as the value
and a widget as the child
argument.
The constructor of SystemUiOverlayStyle
has some arguments for setting the style of the status bar. You can pass statusBarColor
, statusBarBrightness
, statusBarIconBrightness
. The name, type, and behavior of each argument are the same as the respective argument of SystemChrome.setSystemUIOverlayStyle
. Moreover, the applied style also persists when the user navigates to different routes. Using AppBar
or CupertinoNavigationBar
may also override the style created using AnnotatedRegion
.
Set Color
The color of the status bar can be set by passing statusBarColor
argument with a Color
value.
AnnotatedRegion(
value: SystemUiOverlayStyle(
statusBarColor: Colors.red,
),
child: Scaffold(
// ...
)
)
Output:
Set Transparency/Opacity
To make the status bar looks transparent, just set the opacity of the color.
AnnotatedRegion(
value: SystemUiOverlayStyle(
statusBarColor: Colors.red.withOpacity(0.3),
),
child: Scaffold(
// ...
)
)
Output:
Set Brightness
For Android M and higher, you can pass statusBarBrightness
to set the brightness of the status bar icons. If you set the value to Brightness.light
, the icons color will be set to light. Otherwise, if you set the value to Brightness.dark
, the icons color will be set to dark.
AnnotatedRegion(
value: SystemUiOverlayStyle(
statusBarColor: Colors.red,
statusBarBrightness: Brightness.light,
),
child: Scaffold(
// ...
),
)
Output:
For iOS, setting the top status bar brightness can be done by passing the statusBarIconBrightness
argument.
AnnotatedRegion(
value: SystemUiOverlayStyle(
statusBarColor: Colors.red,
statusBarIconBrightness: Brightness.light,
),
child: Scaffold(
// ...
),
)
Full Code
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Woolha.com Flutter Tutorial',
initialRoute: '/one',
routes: {
'/one': (context) => PageOne(),
'/two': (context) => PageTwo(),
},
);
}
}
class PageOne extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AnnotatedRegion(
// Reset SystemUiOverlayStyle for PageOne.
// If this is not set, the status bar will use the style applied from another route.
value: SystemUiOverlayStyle(
statusBarColor: Colors.yellow,
statusBarBrightness: Brightness.dark,
statusBarIconBrightness: Brightness.dark,
),
child: Scaffold(
body: SizedBox.expand(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Woolha.com - One', style: const TextStyle(color: Colors.black)),
OutlinedButton(
child: const Text('Go to PageTwo'),
onPressed: () {
Navigator.popAndPushNamed(context, "/two");
},
),
],
),
),
),
);
}
}
class PageTwo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AnnotatedRegion<SystemUiOverlayStyle>(
// Reset SystemUiOverlayStyle for PageTwo.
// If this is not set, the status bar will use the style applied from another route.
value: SystemUiOverlayStyle(
statusBarColor: Colors.red.withOpacity(0.3),
statusBarBrightness: Brightness.light,
statusBarIconBrightness: Brightness.light,
),
child: Scaffold(
body: SizedBox.expand(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Woolha.com - Two', style: const TextStyle(color: Colors.black)),
OutlinedButton(
child: const Text('Go to PageOne'),
onPressed: () {
Navigator.popAndPushNamed(context, "/one");
},
),
],
),
),
),
);
}
}
Output:
Summary
There are several ways to change the appearance of the status bar. If the application has an AppBar
, you can set the backgroundColor
and brightness
arguments of the AppBar
to change the style. If the application doesn't have an AppBar
, you can use SystemChrome.setSystemUIOverlayStyle
or AnnotatedRegion<SystemUiOverlayStyle>
.
You can also read about: