Flutter - Set Navigation Bar Color, Divider & Icon Brightness

This tutorial shows you how to set the color, divider color, and the icon brightness of the system navigation bar while your Flutter application is running on the foreground.

Most of the modern Android phones come with in-display navigation buttons. Sometimes, you may want to change the navigation bar style. If your application is developed using Flutter, changing the navigation bar style can be done easily by using SystemChrome or AnnotatedRegion. Below are the examples.

Using SystemChrome

To set the color of the navigation bar, you can use SystemChrome.setSystemUIOverlayStyle method. Using SystemChrome requires you to import package:flutter/services.dart first. The method accepts a parameter of type SystemUiOverlayStyle which can be used to define the style of the navigation bar.

Where to call the method depends on the use case. For example, if you want to set the same style for all routes in your application, you can call the method in the main method. If you want to have different styles for each route, you need to call the method in the respective widget.

Set Color

To set the color of the navigation bar, you need to set the systemNavigationBarColor argument when calling the constructor of SystemUiOverlayStyle.

  SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
    systemNavigationBarColor: Colors.red,
  ));

Output:

Flutter - Navigation Bar - SystemChrome - Color

Set Divider Color

For the divider color, the argument you need to pass is systemNavigationBarDividerColor.

  SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
    systemNavigationBarColor: Colors.red,
    systemNavigationBarDividerColor: Colors.blue,
  ));

Output:

Flutter - Navigation Bar - SystemChrome - Divider Color

Set Brightness

You may also want to set the color of the icons on the navigation bar. To do so, you can set the systemNavigationBarIconBrightness argument with a Brightness enum as the value. If you set the value to Brightness.light, the color of the icons will be set to light. Otherwise, if you set the value to Brightness.dark, the color of the icons will be set to dark.

  SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
    systemNavigationBarColor: Colors.red,
    systemNavigationBarIconBrightness: Brightness.dark,
  ));

Output:

Flutter - Navigation Bar - SystemChrome - Brightness.dark

The style applied by SystemChrome.setSystemUIOverlayStyle persists across different routes until the method is called again to set a different style or if another widget sets the SystemUIOverlayStyle. Beware that you may get unexpected results if the application has certain widgets such as AppBar or CupertinoNavigationBar as they may override the SystemUIOverlayStyle. In that case, calling setSystemUIOverlayStyle may have no effect. Depending on the case, we can create a workaround for that problem.

For example we are going to create a simple application that consists of two routes, both have an AppBar and each of them has a different style for the navigation bar. Calling setSystemUIOverlayStyle inside the build method or the initState may not work because the AppBar also sets the SystemUIOverlayStyle. One of the possible solutions is by calling the method after the build completes which can be done by putting the code inside WidgetsBinding.instance.addPostFrameCallback.

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      SystemChrome.setSystemUIOverlayStyle(overlayStyle);
    });
  }

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 StatefulWidget {
    @override
    State<StatefulWidget> createState() {
      return _PageOneState();
    }
  }
  
  class _PageOneState extends State<PageOne> {
  
    static const SystemUiOverlayStyle overlayStyle = SystemUiOverlayStyle(
      systemNavigationBarColor: Colors.red,
      systemNavigationBarIconBrightness: Brightness.light,
      systemNavigationBarDividerColor: Colors.blue,
    );
  
    @override
    void initState() {
      super.initState();
      WidgetsBinding.instance.addPostFrameCallback((_) {
        SystemChrome.setSystemUIOverlayStyle(overlayStyle);
      });
    }
  
    @override
    Widget build(BuildContext context) {
      SystemChrome.setSystemUIOverlayStyle(overlayStyle);
      return Scaffold(
        appBar: AppBar(
          title: const Text('Woolha.com Flutter Tutorial'),
          backgroundColor: Colors.teal,
        ),
        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 StatefulWidget {
    @override
    State<StatefulWidget> createState() {
      return _PageTwoState();
    }
  }
  
  class _PageTwoState extends State<PageTwo> {
  
    static const SystemUiOverlayStyle overlayStyle = SystemUiOverlayStyle(
      systemNavigationBarColor: Colors.yellow,
      systemNavigationBarIconBrightness: Brightness.dark,
      systemNavigationBarDividerColor: Colors.brown,
    );
  
    @override
    void initState() {
      super.initState();
      WidgetsBinding.instance.addPostFrameCallback((_) {
        SystemChrome.setSystemUIOverlayStyle(overlayStyle);
      });
    }
  
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: const Text('Woolha.com Flutter Tutorial'),
          backgroundColor: Colors.teal,
        ),
        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:

Flutter - Navigation Bar - SystemChrome - Full Code

Using AnnotatedRegion

Another way to set the navigation bar style is by using AnnotatedRegion, which is a class with a generic type T extends Object. It's used to annotate a region of the layer tree with a value whose type is T. Therefore, we can create an AnnotatedRegion with SystemUiOverlayStyle as the generic type (AnnotatedRegion<SystemUiOverlayStyle>)

  const AnnotatedRegion({
    Key? key,
    required Widget child,
    required T value,
    bool sized = true,
  })

For setting SystemUiOverlayStyle using AnnotatedRegion, you are required to pass a SystemUiOverlayStyle as the value argument and a Widget as the child argument. That means you need to create a customized SystemUiOverlayStyle instance. Since we also use SystemUiOverlayStyle to define the style, the name and type of the arguments used to change the navigation bar style are basically the same as the respective arguments used on the previous section which uses SystemChrome.

Set Color

To change the color of the navigation bar, you need to set the systemNavigationBarColor argument.

  AnnotatedRegion(
    value: SystemUiOverlayStyle(
      systemNavigationBarColor: Colors.purple,
    ),
    child: Scaffold(
       // ...
    )
  )

Output:

Flutter - Navigation Bar - AnnotatedRegion - Color

Set Divider Color

To change the divider color, you need to set the systemNavigationBarDividerColor argument.

  AnnotatedRegion(
    value: SystemUiOverlayStyle(
      systemNavigationBarColor: Colors.purple,
      systemNavigationBarDividerColor: Colors.green,
    ),
    child: Scaffold(
       // ...
    )
  )

Output:

Flutter - Navigation Bar - AnnotatedRegion - Divider Color

Set Brightness

To set the brightness of the icons color, you need to set the systemNavigationBarIconBrightness argument. If you set the value to Brightness.light, the color of the icons will be set to light. Otherwise, if you set the value to Brightness.dark, the color of the icons will be set to dark.

  AnnotatedRegion(
    value: SystemUiOverlayStyle(
      systemNavigationBarColor: Colors.purple,
      systemNavigationBarIconBrightness: Brightness.light,
    ),
    child: Scaffold(
       // ...
    )
  )

Output:

Flutter - Navigation Bar - AnnotatedRegion - Brightness.light

The change applied by AnnotatedRegion persists across different routes until another widget overrides the SystemUiOverlayStyle and changes the navigation bar style. Unlike using SystemChrome which doesn't work if the page has an AppBar, using AnnotatedRegion does work to set the navigation bar on a page with AppBar, without any workaround.

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 {
  
    static const SystemUiOverlayStyle overlayStyle = SystemUiOverlayStyle(
      systemNavigationBarColor: Colors.red,
      systemNavigationBarIconBrightness: Brightness.light,
      systemNavigationBarDividerColor: Colors.blue,
    );
  
    @override
    Widget build(BuildContext context) {
      return AnnotatedRegion<SystemUiOverlayStyle>(
        value: overlayStyle,
        child: Scaffold(
          appBar: AppBar(
            title: const Text('Woolha.com Flutter Tutorial'),
            backgroundColor: Colors.teal,
          ),
          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 {
  
    static const SystemUiOverlayStyle overlayStyle = SystemUiOverlayStyle(
      systemNavigationBarColor: Colors.purple,
      systemNavigationBarIconBrightness: Brightness.dark,
      systemNavigationBarDividerColor: Colors.green,
    );
  
    @override
    Widget build(BuildContext context) {
      return AnnotatedRegion<SystemUiOverlayStyle>(
        value: overlayStyle,
        child: Scaffold(
          appBar: AppBar(
            title: const Text('Woolha.com Flutter Tutorial'),
            backgroundColor: Colors.teal,
          ),
          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:

Flutter - Navigation Bar - AnnotatedRegion - Full Code

Summary

That's how to change the system navigation bar style for a Flutter application. You can use either SystemChrome or AnnotatedRegion.

You can also read about: