rydmike / flex_color_scheme

A Flutter package to make and use beautiful color scheme based themes.
Other
887 stars 100 forks source link

How do I modify the color of the system UI overlay? #178

Closed TDuffinNTU closed 10 months ago

TDuffinNTU commented 10 months ago

image

As you can see from the image, the background of the ui navigator overlay is showing a white (SchemeColor.surface??) color of my theme. I tried using SystemChrome but this is overridden when the theme loads, and you can't modify this at runtime as far as I know.

Here's how my theme looks:

  // Theme config for FlexColorScheme version 7.2.x. Make sure you use
  // same or higher package version, but still same major version. If you
  // use a lower package version, some properties may not be supported.
  // In that case remove them after copying this theme to your app.
  ThemeData get lightTheme => FlexThemeData.light(
        colorScheme: colorScheme,
        surfaceMode: FlexSurfaceMode.levelSurfacesLowScaffold,
        blendLevel: 7,
        appBarStyle: FlexAppBarStyle.primary,
        subThemesData: const FlexSubThemesData(
          blendOnLevel: 10,
          blendOnColors: false,
          useTextTheme: true,
          useM2StyleDividerInM3: true,
          navigationBarSelectedLabelSchemeColor: SchemeColor.onPrimary,
          navigationBarUnselectedLabelSchemeColor: SchemeColor.inversePrimary,
          navigationBarSelectedIconSchemeColor: SchemeColor.onPrimary,
          navigationBarUnselectedIconSchemeColor: SchemeColor.inversePrimary,
          navigationBarIndicatorSchemeColor: SchemeColor.onPrimary,
          navigationBarBackgroundSchemeColor: SchemeColor.primary,
        ),
        keyColors: const FlexKeyColors(),
        visualDensity: FlexColorScheme.comfortablePlatformDensity,
        useMaterial3: true,
        swapLegacyOnMaterial3: true,
        // To use the Playground font, add GoogleFonts package and uncomment
        // fontFamily: GoogleFonts.notoSans().fontFamily,
      );

  ThemeData get darkTheme => FlexThemeData.dark(
        colorScheme: colorScheme,
        surfaceMode: FlexSurfaceMode.levelSurfacesLowScaffold,
        blendLevel: 13,
        subThemesData: const FlexSubThemesData(
          blendOnLevel: 20,
          useTextTheme: true,
          useM2StyleDividerInM3: true,
          navigationBarSelectedLabelSchemeColor: SchemeColor.onPrimary,
          navigationBarUnselectedLabelSchemeColor: SchemeColor.inversePrimary,
          navigationBarSelectedIconSchemeColor: SchemeColor.onPrimary,
          navigationBarUnselectedIconSchemeColor: SchemeColor.inversePrimary,
          navigationBarIndicatorSchemeColor: SchemeColor.onPrimary,
          navigationBarBackgroundSchemeColor: SchemeColor.primary,
        ),
        keyColors: const FlexKeyColors(),
        visualDensity: FlexColorScheme.comfortablePlatformDensity,
        useMaterial3: true,
        swapLegacyOnMaterial3: true,
        // To use the Playground font, add GoogleFonts package and uncomment
        // fontFamily: GoogleFonts.notoSans().fontFamily,
      );

  ColorScheme get colorScheme => SeedColorScheme.fromSeeds(primaryKey: Color(0xFFFF5500));

This might be unrelated to your package but I know you're well versed with theming so maybe you know where I can look next? thanks!

TDuffinNTU commented 10 months ago

It appears that when I use SystemChrome to change the navbar color, it briefly flashes the desired color then is overridden by the theme, but only when using a Flex theme

  SystemChrome.setSystemUIOverlayStyle(
  SystemUiOverlayStyle(systemNavigationBarColor: Colors.black));
TDuffinNTU commented 10 months ago

Fixed it!

Wrapped this around my navigation bar widget and it's sorted :D

return AnnotatedRegion<SystemUiOverlayStyle> 
    // Makes the bottom nav bar transparent so we dont have to see its ugly face
    value: SystemUiOverlayStyle(
      systemNavigationBarColor: Colors.black.withOpacity(0),
    ),
)
rydmike commented 10 months ago

Hi @TDuffinNTU,

My apologies for not noticing this question earlier. Glad to see you figured it out.

Just to confirm, yes using an AnnotatedRegion is the correct way to control the system navigation bar in Flutter. It is not a very well known widget.

In the FlexColorScheme docs it is mentioned here: https://docs.flexcolorscheme.com/deep_dives#themed-system-navigation-bar-in-android

There is also a static helper for using the AnnotatedRegion in the FlexColorScheme class (FlexColorScheme.themedSystemNavigationBar). It provides some convenience features, like matching the color to surface, background, scaffold background, including seed generation and surface blend impacts on such colors. It also makes it easy to add a divider to it and opacity on the background or make it fully transparent. For an iOS like full screen look of the system navigation bar in Android, try the transparent option. I like it, but it is just a personal preference.

You can find API docs for the FlexColorScheme.themedSystemNavigationBar here: https://pub.dev/documentation/flex_color_scheme/latest/flex_color_scheme/FlexColorScheme/themedSystemNavigationBar.html

It is also mentioned in the Themes Playground app in the Android Sys Nav panel.

Screenshot 2023-08-14 at 10 37 55

Of course the features do not work on the Themes Playground WEB app, as it is not a theme feature and it does not do anything on WEB builds. However, if you build the Themes Playground for an Android device and manipulate the settings in this panel, you can see their impact.

The settings for the system navigation bar in Android have limitations and do not work on older versions of Android, also earlier there were some issues in Flutter with it even on some newer versions. It is fixed now, but if it is of interest, this issue can be an educational read: https://github.com/flutter/flutter/issues/100027

This issue also contains a nice collection about system navigation bar APIs and its known issues: https://github.com/flutter/flutter/issues/112301 Many of them have been solved.

Happy theming and good luck with your Flutter app!

-Mike

PS. I'm going to add this issue to Q&A in Discussions, since by making it discoverbale there I think it might benefit more devs than only having it here in a closed issue.