-
Notifications
You must be signed in to change notification settings - Fork 29.2k
Description
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 |
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.