37

How do I change the system NavBar using Android Studio and flutter?

I presume it's not in the main.dart, and I need to go through the android system files, but when I tried to edit the style.xml, the theme editor didn't let me edit any of the colors.

Any help would be appreciated, I wanted to have a light NavBar to go with a light bottom AppBar.

Michel Feinstein
  • 13,416
  • 16
  • 91
  • 173
Tom O'Sullivan
  • 3,416
  • 5
  • 15
  • 27

3 Answers3

68

Note: this requires a more recent version of Flutter as it references APIs added in June 2018.

You can create a custom SystemUiOverlayStyle using the default constructor. The color of the system nav bar is defined there. But to avoid setting a lot of null values, use the copyWith method to update the values from an existing light/dark theme.

const mySystemTheme= SystemUiOverlayStyle.light
 .copyWith(systemNavigationBarColor: Colors.red);

You can imperatively set the system nav color using the SystemChrome static methods.

SystemChrome.setSystemUiOverlayStyle(mySystemTheme);

However, if you have multiple widgets which set this value, or use the material AppBar or Cupertino NavBar your value may be overwritten by them. Instead, you could use the new AnnotatedRegion API to tell flutter to automatically switch to this style anytime certain widgets are visible. For example, if you wanted to use the theme above anytime you are in a certain route, you could wrap it in an AnnotatedRegion widget like so.

Widget myRoute(BuildContext context) {
  return new AnnotatedRegion<SystemUiOverlayStyle>(
    value: mySystemTheme,
    child: new MyRoute(),
  );
}

This won't change your theme back to the previous value if you pop the route however

WSBT
  • 33,033
  • 18
  • 128
  • 133
Jonah Williams
  • 20,499
  • 6
  • 65
  • 53
  • Awesome ! But what happens if you have multiple `AnnotatedRegion` with conflicting values ? And if the previous route contains an `AnnotatedRegion`, is your last statement still valid ? – Rémi Rousselet Jun 24 '18 at 19:38
  • 2
    Currently the flutter view combines the system chrome values which intersect at the top and bottom of the screen in the actual layer tree. So it you have 3 annotated regions at the top of your screen, the last one will be chosen. This is kind of a low level API, and we intend to build a simpler one on top of it in material and cupertino – Jonah Williams Jun 24 '18 at 19:50
  • "last" meaning deepest, unless it is unsized :) – Jonah Williams Jun 24 '18 at 19:51
  • 1
    @JonahWilliams you said, "This won't change your theme back to the previous value if you pop the route however". Is there any option for changing the status bar color after pop or push to new route? – pso Apr 10 '19 at 07:52
  • 2
    @JonahWilliams I tried to use the `AnnotatedRegion` as the parent of a `Scaffold`, defining `statusBarColor: Colors.transparent,`, but it doesn't work, it appears that the `AppBar` has always precedence. – Michel Feinstein Aug 15 '19 at 18:44
  • Updated from 'SystemUiOverlayStyle' to 'setSystemUIOverlayStyle' – Peter I Feb 25 '20 at 22:03
  • 1
    So what is the solution for pop? – BeHappy Oct 12 '20 at 19:35
  • I can't stop material `AppBar` screw up my `AnnotatedRegion`... – jeiea Dec 21 '20 at 07:21
50

Flutter 2.4+ (Update)

Use systemOverlayStyle property

class MyPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        systemOverlayStyle: SystemUiOverlayStyle(
          systemNavigationBarColor: Colors.blue, // Navigation bar
          statusBarColor: Colors.pink, // Status bar
        ),
      ),
    );
  }
}
CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
15

You can simply call SystemChrome.setSystemUIOverlayStyle :

import 'package:flutter/services.dart'

SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
stevenspiel
  • 5,775
  • 13
  • 60
  • 89
Rémi Rousselet
  • 256,336
  • 79
  • 519
  • 432