Skip to content

Using systemNavigationBarDividerColor changes statusBarIconBrightness and systemNavigationBarIconBrightness on Android11 #100027

@rydmike

Description

@rydmike

Steps to Reproduce

When you use an AnnotatedRegion to control the design of the system navigation bar on Android the
statusBarIconBrightness and systemNavigationBarIconBrightness unexpectedly change to Brightness.light if you give any value to systemNavigationBarDividerColor on Android 11 (SDK30).

To see the issue try the provided code sample with different Android SDK API versions.

Reproduction sample code
void main() {
  runApp(const MyApp());
}

final AppBarTheme appBarLight = AppBarTheme(
  backgroundColor: Colors.white.withAlpha(0xEE),
  foregroundColor: Colors.black,
  elevation: 0.5,
  systemOverlayStyle: SystemUiOverlayStyle.dark.copyWith(
    statusBarColor: Colors.transparent,
  ),
);

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Annotated Region Issue',
      theme: ThemeData.from(colorScheme: const ColorScheme.light())
          .copyWith(appBarTheme: appBarLight),
      home: const MyHomePage(title: 'Annotated Region Issue'),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  Widget build(BuildContext context) {
    final MediaQueryData media = MediaQuery.of(context);
    final double topPadding = media.padding.top + kToolbarHeight;
    final double bottomPadding = media.padding.bottom;
    SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
    return AnnotatedRegion(
      value: SystemUiOverlayStyle(
        systemNavigationBarColor: Colors.white.withAlpha(0xEE),
        systemNavigationBarDividerColor: Colors.transparent,
        systemNavigationBarIconBrightness: Brightness.dark,
        systemNavigationBarContrastEnforced: false,
      ),
      child: Scaffold(
        extendBody: true,
        extendBodyBehindAppBar: true,
        appBar: AppBar(
          title: Text(title),
        ),
        body: GridView.builder(
          padding:
              EdgeInsets.fromLTRB(10, topPadding + 10, 10, bottomPadding + 10),
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 3,
            mainAxisSpacing: 8,
            crossAxisSpacing: 8,
            childAspectRatio: 2,
          ),
          itemCount: 100,
          itemBuilder: (context, index) => Card(
            color: Colors.primaries[index % Colors.primaries.length][800]!,
            elevation: 2,
            child: Center(
              child: Text(
                'Tile nr ${index + 1}',
                style: const TextStyle(color: Colors.white, fontSize: 16),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

Actual results

  • On Android 11 (SDK 30) the icons become light even though they are set to dark.
  • On Android 9 (SDK 28) the system navigation bar does not change to given color.
Android 9 (SDK 28) Android 10 (SDK 29) Android 11 (SDK 30) Android 12 (SDK 31)
FAIL OK FAIL OK
image image image image

Results from Pixel4XL at shown Android SDK API level using the 3 button system navigation style to make the results more visible. The results are the same with the smaller swipe navigation too, but not as visible.

Expected results

Expected that the system navigation bar icons and status bar icons would have remained dark on Android 11 (SDK 30) as in result from Android 10 (SDK 29) and Android 12 (SDK 31). Surprisingly even the status bar icons change their brightness, even though they are not set in the SystemUiOverlayStyle used in the AnnotatedRegion at all.

Expected that Android 9 (SDK 28) would have gotten a white system navigation bar with opacity. This was expected since the documentation states:

/// The color of the system bottom navigation bar.
///
/// Only honored in Android versions O and greater.
final Color? systemNavigationBarColor;

Since Android O, is Android Oreo, version 8.0 (SDK 26), then setting the systemNavigationBarColor should have worked also in this case with Android 9 (SDK 28), but as shown it did not change color.

Tested Flutter versions

The issue exists in latest Flutter stable 2.10.3 and master channel version shown below:

Flutter doctor from master
[√] Flutter (Channel master, 2.11.0-0.0.pre.870, on Microsoft Windows [Version 10.0.22000.556], locale en-US)
    • Flutter version 2.11.0-0.0.pre.870 at C:\Users\mryds\fvm\versions\master
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 2f73173c36 (2 days ago), 2022-03-11 15:00:16 -0500
    • Engine revision 6239bfb884
    • Dart version 2.17.0 (build 2.17.0-182.0.dev)
    • DevTools version 2.11.1

[√] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    • Android SDK at C:\Users\mryds\AppData\Local\Android\sdk
    • Platform android-31, build-tools 30.0.3
    • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 11.0.11+9-b60-7590822)
    • All Android licenses accepted.

[√] Chrome - develop for the web
    • Chrome at C:\Program Files (x86)\Google\Chrome\Application\chrome.exe

[√] Visual Studio - develop for Windows (Visual Studio Community 2019 16.11.9)
    • Visual Studio at C:\Program Files (x86)\Microsoft Visual Studio\2019\Community
    • Visual Studio Community 2019 version 16.11.32106.194
    • Windows 10 SDK version 10.0.19041.0

[√] Android Studio (version 2021.1)
    • Android Studio at C:\Program Files\Android\Android Studio
    • Flutter plugin can be installed from:
       https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
       https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.11+9-b60-7590822)

[√] IntelliJ IDEA Community Edition (version 2021.3)
    • IntelliJ at C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2018.3.1
    • Flutter plugin version 65.2.4
    • Dart plugin version 213.7227

[√] VS Code (version 1.65.2)
    • VS Code at C:\Users\mryds\AppData\Local\Programs\Microsoft VS Code
    • Flutter extension version 3.36.0

[√] Connected device (4 available)
    • sdk gphone x86 64 arm64 (mobile) • emulator-5554 • android-x64    • Android 11 (API 30) (emulator)
    • Windows (desktop)                • windows       • windows-x64    • Microsoft Windows [Version 10.0.22000.556]   
    • Chrome (web)                     • chrome        • web-javascript • Google Chrome 99.0.4844.51
    • Edge (web)                       • edge          • web-javascript • Microsoft Edge 99.0.1150.30

[√] HTTP Host Availability
    • All required HTTP hosts are available

• No issues found!

System navigation bar divider is a surface layer, not a divider line

If you on Android 10, 11 and 12 set systemNavigationBarDividerColor to a color with opacity, then the system navigation bar becomes almost opaque and no longer has the opacity defined by systemNavigationBarColor. As shown here:

return AnnotatedRegion(
      value: SystemUiOverlayStyle(
        systemNavigationBarColor: Colors.white.withAlpha(0xEE),
        systemNavigationBarDividerColor: Colors.white.withAlpha(0xEE),
        systemNavigationBarIconBrightness: Brightness.dark,
        systemNavigationBarContrastEnforced: false,
      ),

It seems like the systemNavigationBarDividerColor is a full layer behind the navigation bar with just a 1dp higher height. We can test this theory with separate colors on divider and the system navigation bar, with both having suitable opacity:

return AnnotatedRegion(
      value: SystemUiOverlayStyle(
        systemNavigationBarColor: Colors.white.withAlpha(0xBB),
        systemNavigationBarDividerColor: Colors.red.withAlpha(0x55),
        systemNavigationBarIconBrightness: Brightness.dark,
        systemNavigationBarContrastEnforced: false,
      ),

Which reveals that this is in fact the case. Here we can see a translucent white surface on the navigation bar, showing the translucent red divider surface behind it, with it reaching about 1dp higher and top part being visible as a red semi transparent line.

To not have any impact from the systemNavigationBarDividerColor on the systemNavigationBarColor with opacity, you have to use fully transparent color Colors.transparent on the divider color.

Knowing that the divider color is in fact the color of a full surface behind the system navigation bar that is just 1dp higher than navigation bar area, and not a divider line, is a critical piece of information when dealing with how to use it when using opacity on the system navigation bar background. You can use this knowledge to create a system navigation bar area that has some transparency and a divider, but the transparency will be a sum of both colors and their transparency.

Consider documenting this critical information about the system navigation bar divider.

SystemUiOverlayStyle Documentation

Consider using clearer documentation of what feature is supported on which versions for each property in SystemUiOverlayStyle.

Prefer always stating Android version and SDK API level. Avoid using internal code version letters like "O" and "P", instead prefer saying "Android 8 (SDK 26)" and "Android 10 (SDK 29)".

Avoid using terms like SDK 29+, it is unclear if this means 29 and higher or higher than 29. Fortunately the docs do mention the unambiguous version too, but in some cases with the confusing Android one letter version code. Why include the ambiguous version at all?

Examples:

  • "in SDK 29+, or Android 10 and up", instead consider "in Android 10 (SDK 29) and up"
  • "SDK 28-, or Android P and lower", instead consider "in Android 9 (SDK 28) and lower"

Related issues

At least these issues touch subjects related to this issue, but are slightly different.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listc: regressionIt was better in the past than it is nowe: OS-version specificAffects only some versions of the relevant operating systemengineflutter/engine related. See also e: labels.found in release: 2.10Found to occur in 2.10found in release: 2.11Found to occur in 2.11frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onplatform-androidAndroid applications specificallyr: fixedIssue is closed as already fixed in a newer version

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions