Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change Android Navigation Bar Color on System Dark Mode toggle #45

Closed
iamhx opened this issue Sep 27, 2022 · 6 comments
Closed

Change Android Navigation Bar Color on System Dark Mode toggle #45

iamhx opened this issue Sep 27, 2022 · 6 comments

Comments

@iamhx
Copy link

iamhx commented Sep 27, 2022

When using AdaptiveTheme.of(context).modeChangeNotifier.addListener, I can change my android's navigation bar color like this:

AdaptiveTheme.of(context).modeChangeNotifier.addListener(() async {
      //This gets the system's platform brightness.
      final platformBrightness = MediaQuery.of(context).platformBrightness;

      final themeMode = AdaptiveTheme.of(context).mode;
      late Color color;
      late Brightness brightness;

      switch (themeMode) {
        case AdaptiveThemeMode.light:
          color = Colors.white;
          brightness = Brightness.dark;
          break;
        case AdaptiveThemeMode.dark:
          color = Colors.black;
          brightness = Brightness.light;
          break;
        case AdaptiveThemeMode.system:
          color = (platformBrightness == Brightness.dark)
              ? Colors.black
              : Colors.white;
          brightness = (platformBrightness == Brightness.dark)
              ? Brightness.light
              : Brightness.dark;
          break;
        default:
          break;
      }

      SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
          systemNavigationBarColor: color,
          systemNavigationBarIconBrightness: brightness));
});

However, the navigation bar color does not change when I toggle dark mode from my Notification Centre. I tried finding a way to listen for platform brightness here by using WidgetsBinding.instance.handlePlatformBrightnessChanged();, but this would disable the dynamic theming of the app provided in your package (As I realised that I am probably overriding your code).

Is there a way I can change the navigation bar color, when toggling dark mode from notification centre?

Example (Gif was too large to show here, sorry)

@iamhx
Copy link
Author

iamhx commented Sep 27, 2022

It turns out that I used WidgetsBinding.instance.handlePlatformBrightnessChanged(); wrongly, as I had to do it inside the WidgetsBinding.instance.window.onPlatformBrightnessChanged instead...

var window = WidgetsBinding.instance.window;
    window.onPlatformBrightnessChanged = () async {
      // This callback is called every time the brightness changes.
      WidgetsBinding.instance.handlePlatformBrightnessChanged();
      final currentPlatformBrightness = window.platformBrightness;
      final currentThemeMode = await AdaptiveTheme.getThemeMode();

      switch (currentThemeMode) {
        case AdaptiveThemeMode.light:
          color = Colors.white;
          brightness = Brightness.dark;
          break;
        case AdaptiveThemeMode.dark:
          color = Colors.black;
          brightness = Brightness.light;
          break;
        case AdaptiveThemeMode.system:
          color = (currentPlatformBrightness == Brightness.dark)
              ? Colors.black
              : Colors.white;
          brightness = (currentPlatformBrightness == Brightness.dark)
              ? Brightness.light
              : Brightness.dark;
          break;
        default:
          break;
      }
      SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
          systemNavigationBarColor: color,
          systemNavigationBarIconBrightness: brightness));
    };

Now when the dark mode is toggled through the notification centre, the navigation bar color changes accordingly.

@iamhx iamhx closed this as completed Sep 27, 2022
@BirjuVachhani
Copy link
Owner

@iamhx Glad you were able to make it work on your own. However, you don't need to register a listener. You can just set those properties if you can in your theme and let the package do its thing.

@iamhx
Copy link
Author

iamhx commented Sep 28, 2022

@BirjuVachhani Thanks for the reply.

In my theme_light.dart:

final ThemeData lightTheme = ThemeData(
    appBarTheme: AppBarTheme(
        systemOverlayStyle: const SystemUiOverlayStyle(
        statusBarColor: Colors.transparent,
        statusBarIconBrightness: Brightness.dark,
        statusBarBrightness: Brightness.light,
        systemNavigationBarColor: Colors.green, //Trying to change color here, does not work.
      )
    );

Setting those properties in my theme doesn't seem to change anything and I am not sure why. That is why I had to use SystemChrome.setSystemUIOverlayStyle. Tried searching online on why that doesn't work, but haven't really found the answer to this issue. But as long as it works, I guess!

Thank you for this great package.

@BirjuVachhani
Copy link
Owner

I am not sure but I think you have to set brightness as well.

@BrianMwas
Copy link

I am not sure but I think you have to set brightness as well.

Brightness is deprecated

@BrianMwas
Copy link

It turns out that I used WidgetsBinding.instance.handlePlatformBrightnessChanged(); wrongly, as I had to do it inside the WidgetsBinding.instance.window.onPlatformBrightnessChanged instead...

var window = WidgetsBinding.instance.window;
    window.onPlatformBrightnessChanged = () async {
      // This callback is called every time the brightness changes.
      WidgetsBinding.instance.handlePlatformBrightnessChanged();
      final currentPlatformBrightness = window.platformBrightness;
      final currentThemeMode = await AdaptiveTheme.getThemeMode();

      switch (currentThemeMode) {
        case AdaptiveThemeMode.light:
          color = Colors.white;
          brightness = Brightness.dark;
          break;
        case AdaptiveThemeMode.dark:
          color = Colors.black;
          brightness = Brightness.light;
          break;
        case AdaptiveThemeMode.system:
          color = (currentPlatformBrightness == Brightness.dark)
              ? Colors.black
              : Colors.white;
          brightness = (currentPlatformBrightness == Brightness.dark)
              ? Brightness.light
              : Brightness.dark;
          break;
        default:
          break;
      }
      SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
          systemNavigationBarColor: color,
          systemNavigationBarIconBrightness: brightness));
    };

Now when the dark mode is toggled through the notification centre, the navigation bar color changes accordingly.

Hey instead of this you can use the following
final currentBrightness = MediaQuery.platformBrightnessOf(context)
Its way more performant in the long run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants