2

I want to set status bar color for each screen. E.g. in screen A status bar color is red and in screen B is blue. I tried many solutions. But each one has it's own problem. like:

AnnotatedRegion(
    value: SystemUiOverlayStyle(
        systemNavigationBarColor: navigationBarColor,
        statusBarColor: statusBarColor,
    ),
    child: child,
);

or this before return in build method:

SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
  statusBarColor: Colors.white
));

My final try :

  static void pushNamed({
    BuildContext context,
    String route,
    Object arguments,
    Color statusBarColor,
    Color navigationBarColor = Colors.black,
  }) async {
    if (statusBarColor != null) {
      await FlutterStatusbarcolor.setStatusBarColor(statusBarColor);
    }
    await Navigator.pushNamed(
      context,
      route,
      arguments: arguments,
    );
  }

but sometimes fails. and other problem of this solution is when use back button, color not changed.(I write my code for back button in appbar). and even when in hot reload color change to previous. How can I handle this problem?

Update #2

I create a class for my routing.

static void pushNamedAndRemoveUntil({
    BuildContext context,
    String route,
    Object arguments,
    Color statusBarColor,
    Color popStatucBarColor,
    Color popNavigationBarColor,
    Color navigationBarColor,
}) async {
    changeSystemColor(statusBarColor, navigationBarColor);
    Navigator.pushNamedAndRemoveUntil(
        context,
        route,
        (Route<dynamic> route) => false,
        arguments: arguments,
    ).then((res) {
        changeSystemColor(popStatucBarColor, popNavigationBarColor);
    });
}

and:

void changeSystemColor(Color statusBarColor, Color navigationBarColor) {
  if (statusBarColor != null)
    SystemChrome.setSystemUIOverlayStyle(
      SystemUiOverlayStyle(
        systemNavigationBarColor: navigationBarColor ?? Colors.black,
        statusBarColor: statusBarColor,
      ),
    );
}

and for using this

Routing.pushNamedAndRemoveUntil(
    context: context,
    route: Routes.homeScreen,
    arguments: user,
    statusBarColor: Colors.teal,
);

and now not work when use pushNamedAndRemoveUntil.

BeHappy
  • 3,705
  • 5
  • 18
  • 59

4 Answers4

0

You can use an AppBar but set its height and elevation to 0 so that it only covers the status bar and has no shadow.

appBar: PreferredSize(
                preferredSize: Size.fromHeight(0),
                child: new AppBar(
                        brightness: Brightness.light,
                        backgroundColor: backgroundColour,
                        elevation: 0,
                )
),

Then in initState() you can make the status bar transparent so it won't be discoloured.

You need to call this before and after your await Navigator.push() calls.

SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
   statusBarColor: desiredColour
));
andrew zuo
  • 1
  • 1
  • 1
0

You can't trigger the System Color change on initState or any of the other Stateful Widget lifecycle methods. The best way seems to be by setting the color before navigating to the new view and when return from that view:

void goToWhiteView(){
  changeSystemColor(Colors.white);
  Navigator.pushNamed(
    context,
    route,
    arguments: arguments,
  ).then((result){
    changeSystemColor(Colors.blue);
  });
}

void changeSystemColor(Color color){
  SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
    systemNavigationBarColor: color,
    statusBarColor: color
  ));
}
J. S.
  • 8,905
  • 2
  • 34
  • 44
0

I create ScreenContainer widget and wrap my screen with it:

    return AnnotatedRegion<SystemUiOverlayStyle>(
      value: SystemUiOverlayStyle(
        statusBarColor: statusbarcolor ?? ColorPalette.accent,
        statusBarIconBrightness: statusBarIconBrightness ?? Brightness.light,
      ),
      child: child,
    );
BeHappy
  • 3,705
  • 5
  • 18
  • 59
0

Use focus_detector for the page you want to set statusBarColor.

@override
Widget build(BuildContext context) =>
    FocusDetector(
      onVisibilityGained: () {
        //Here you can change statusBarColor as you like
        SystemUiOverlayStyle systemUiOverlayStyle = SystemUiOverlayStyle.dark
        .copyWith(statusBarColor: Colors.transparent);
    SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
      },
      child: YourOwnPage(),
    );

More information can see at visibility_detector.

ouflak
  • 2,458
  • 10
  • 44
  • 49
朱相卿
  • 61
  • 1
  • 2