How to change status bar text color in Flutter
Table of Contents
App-wide
If you want to change a status bar text color across your app, a theme is always the right choice for this kind of task. To do that, set brightness
property in AppBarTheme
to either Brightness.dark
or Brightness.light
.
Brightness (Obsolete)
class StatusBarApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
appBarTheme: AppBarTheme(
brightness: Brightness.dark,
),
),
home: StatusBarPage(),
debugShowCheckedModeBanner: false,
);
}
}
Brightness.dark
means app bar color is dark and will require a light text color to achieve readable contrast.Brightness.light
means app bar color is light and will require a dark text color to achieve readable contrast.
But this brightness property is obsolete, and Flutter recommended we use systemOverlayStyle
instead.
SystemOverlayStyle
To use systemOverlayStyle
, we need to also set backwardsCompatibility
to false
so the system knows which property to use (brightness
and systemOverlayStyle
).
class StatusBarApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
appBarTheme: AppBarTheme(
backwardsCompatibility: false, // 1
systemOverlayStyle: SystemUiOverlayStyle.light, // 2
),
),
home: StatusBarPage(),
debugShowCheckedModeBanner: false,
);
}
}
<1> Set backwardsCompatibility
to false
to tell the system that we are going to use systemOverlayStyle
not brightness
.
<2> Use systemOverlayStyle
to control status bar text color.
One thing to note here is that SystemUiOverlayStyle.dark/light refers to the text, not that app bar color like what Brightness.dark/light did. So the result might be the reverse of what you thought.
SystemUiOverlayStyle.dark
means System overlays text should be drawn with a dark color. Intended for applications with a light background.SystemUiOverlayStyle.light
means System overlays text should be drawn with a light color. Intended for applications with a dark background.
This is more align with what iOS have UIStatusBarStyle.darkContent
and UIStatusBarStyle.lightContent
.
You can easily support sarunw.com by checking out this sponsor.
AI Grammar: Correct grammar, spell check, check punctuation, and parphrase.
Specific View with an AppBar
If you want to change a status bar text color for a specific view (with an app bar), you can use the exact property we employ in the theme, but this time set it to the AppBar.
class StatuBarsPage extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Flutter Demo',
),
// brightness: Brightness.light,
systemOverlayStyle: SystemUiOverlayStyle.dark, // 1
),
body: ...
);
}
}
<1> Set brightness
or systemOverlayStyle
to the AppBar. We don't need backwardsCompatibility
here since it will inherit from the theme.
Dynamically change the status bar text color
If you need to change the status bar text color dynamically, e.g., when you want it to change based on the scrollable content or some condition, you can extract systemOverlayStyle
to variable and change it with setState
.
class StatusBarPage extends StatefulWidget {
_StatusBarPageState createState() => _StatusBarPageState();
}
class _StatusBarPageState extends State<StatusBarPage> {
var overlayStyle = SystemUiOverlayStyle.light; // 1
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Flutter Demo',
),
systemOverlayStyle: overlayStyle, // 2
),
body: Center(
child: Center(
child: ElevatedButton(
child: Text('Toggle'),
onPressed: () {
setState(() { // 3
if (overlayStyle == SystemUiOverlayStyle.light) {
overlayStyle = SystemUiOverlayStyle.dark;
} else {
overlayStyle = SystemUiOverlayStyle.light;
}
});
},
),
),
),
);
}
}
<1> Declare variable for SystemUiOverlayStyle
.
<2> Use this variable for app bar.
<3> Change it with setState
whene needed.
Specific View without an AppBar
SystemUiOverlayStyle
If your page doesn't have an app bar, you can set a status bar text color with setSystemUIOverlayStyle
method. To do that call SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light)
anywhere in your build method.
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light); // 1
return const Placeholder();
}
<1> Call SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light)
in your build method.
Dynamically change the status bar text color
If you use setSystemUIOverlayStyle
to control your status bar text color, you can easily change your style by calling SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light)
again. No variable or set state needed.
class StatusBarPage extends StatelessWidget {
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light); // 1
return Center(
child: ElevatedButton(
child: Text('Toggle'),
onPressed: () {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark); // 2
},
),
);
}
}
<1> Start with white status bar text color.
<2> Tap the button will change it to black.
You can easily support sarunw.com by checking out this sponsor.
AI Grammar: Correct grammar, spell check, check punctuation, and parphrase.
Specific View without an AppBar (Advanced)
Suppose you want to create a custom widget with the ability to control status bar text color (just like app bar). In that case, the AnnotatedRegion
widget is more appropriate than calling setSystemUIOverlayStyle
directly.
AnnotatedRegion
If the annotated region widget is found under that status and navigation bar (top area of the app), its value will be used to configure the system styles.
Here is fake app bar I created using AnnotatedRegion. It is a simple pink bar with a white status bar text color.
class FakeAppBar extends StatelessWidget {
Widget build(BuildContext context) {
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.light,
child: Container(
height: 100,
width: double.infinity,
decoration: BoxDecoration(
color: Colors.pink,
),
),
);
}
}
Place this AnnotatedRegion
widget around the top area, and the system will configure the system styles based on its value
.
class StatusBarApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
appBarTheme: AppBarTheme(
backwardsCompatibility: false,
systemOverlayStyle: SystemUiOverlayStyle.light,
),
),
home: Column(
children: [
FakeAppBar(), // 1
SizedBox(
height: 100,
),
],
),
debugShowCheckedModeBanner: false,
);
}
}
<1> Put it at the very top.
If the AnnotatedRegion
widget isn't placed around the top area, the value won't be used. This makes perfect sense since the widget color won't interfere with the status bar, so it shouldn't affect the status bar style.
class StatusBarApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
appBarTheme: AppBarTheme(
backwardsCompatibility: false,
systemOverlayStyle: SystemUiOverlayStyle.light,
),
),
home: Column(
children: [
SizedBox( // 1
height: 100,
),
FakeAppBar(),
],
),
debugShowCheckedModeBanner: false,
);
}
}
<1> Put SizedBox
above FakeAppBar
push our widget away from the status bar area make it no longer affect the status bar style.
Dynamically change the status bar text color
You can change style dynamically just like an app bar with variable and setState because internally, AppBar also uses AnnotatedRegion. I won't repeat the process here. You can look in the Local AppBar section.
The following is a part of AppBar implementation taken from the source code.
Widget build(BuildContext context) {
....
return Semantics(
container: true,
child: AnnotatedRegion<SystemUiOverlayStyle>( // 1
value: overlayStyle,
child: Material(
color: backgroundColor,
elevation: widget.elevation
?? appBarTheme.elevation
?? _defaultElevation,
shadowColor: widget.shadowColor
?? appBarTheme.shadowColor
?? _defaultShadowColor,
shape: widget.shape,
child: Semantics(
explicitChildNodes: true,
child: appBar,
),
),
),
);
}
<1> AppBar use AnnotatedRegion
internally.
Read more article about Flutter, Status Bar, or see all available topic
Enjoy the read?
If you enjoy this article, you can subscribe to the weekly newsletter.
Every Friday, you'll get a quick recap of all articles and tips posted on this site. No strings attached. Unsubscribe anytime.
Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading and see you next time.
If you enjoy my writing, please check out my Patreon https://www.patreon.com/sarunw and become my supporter. Sharing the article is also greatly appreciated.
Become a patron Buy me a coffee Tweet ShareHow to change a back button color in Flutter
Learn different ways to change the back button color in Flutter.
Pull to refresh in SwiftUI with refreshable
SwiftUI got a native way to add UIRefreshControl in iOS 15. Let's find out how to add it in the list view and even your custom view.