flutter / flutter

Flutter makes it easy and fast to build beautiful apps for mobile and beyond
https://flutter.dev
BSD 3-Clause "New" or "Revised" License
163.21k stars 26.86k forks source link

Flutter overrides Android statusbar icon brightness on startup #64001

Open josh-burton opened 3 years ago

josh-burton commented 3 years ago

Android supports light/dark brightness for statusbar icons. On startup, the FlutterActivity always sets the status bar icons to light.

When trying to create an app with dark status bar icons, this causes a flicker between brightness on startup.

flutter_light_status_bar

Steps to Reproduce

To reproduce, configure the Android theme to have a light status bar (dark icons):

<style name="LaunchTheme" parent="@style/Theme.AppCompat.Light">

        <!--  The statusbar color is overridden to match the statusbar color set in Flutter -->
        <item name="android:statusBarColor">#42000000</item> 
        <!--  Request the statusbar has dark icons -->
        <item name="android:windowLightStatusBar">true</item>

        <item name="android:windowBackground">@drawable/launch_background</item>
    </style>
         This Theme is only used starting with V2 of Flutter's Android embedding. -->
    <style name="NormalTheme" parent="@style/Theme.AppCompat.Light">

        <!--  The statusbar color is overridden to match the statusbar color set in Flutter -->
        <item name="android:statusBarColor">#42000000</item>
        <!--  Request the statusbar has dark icons -->
        <item name="android:windowLightStatusBar">true</item>

        <item name="android:windowBackground">@android:color/white</item>
    </style>

In Flutter, also set the status bar icons to dark:

 SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
    statusBarIconBrightness: Brightness.dark,
    statusBarColor: Colors.black26, //this color matches what we have set in the Android theme
  ));

Expected result: On startup, the statusbar color and icon color should be consistent across the native startup sequence and as the Flutter engine/app starts.

Actual result: The app starts with the correct status bar/icon colors, then flickers to light status bar icons during startup, and once the Flutter app is running flicks back to dark statusbar icons.

A sample project can be found here.

The cause of the issue seems to be this method in io.flutter.embedding.android.FlutterActivity:

  private void configureStatusBarForFullscreenFlutterExperience() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      Window window = getWindow();
      window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
      window.setStatusBarColor(0x40000000);
      window.getDecorView().setSystemUiVisibility(PlatformPlugin.DEFAULT_SYSTEM_UI);
    }
  }

Either Flutter should set the status bar color/brightness to the existing Android theme settings, or provide a way to override these values in the theme or manifest metadata.

Logs ``` ➜ flutter doctor -v [✓] Flutter (Channel beta, 1.20.0, on Mac OS X 10.15.5 19F101, locale en-AU) • Flutter version 1.20.0 at /Users/athor/dev/flutter • Framework revision 916c3ac648 (2 weeks ago), 2020-08-01 09:01:12 -0700 • Engine revision d6ee1499c2 • Dart version 2.9.0 (build 2.9.0-21.10.beta) [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.1) • Android SDK at /Users/athor/dev/android-sdk • Platform android-30, build-tools 30.0.1 • ANDROID_HOME = /Users/athor/dev/android-sdk • Java binary at: /Users/athor/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-1/201.6719854/Android Studio 4.1 Preview.app/Contents/jre/jdk/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 11.6) • Xcode at /Applications/Xcode.app/Contents/Developer • Xcode 11.6, Build version 11E708 • CocoaPods version 1.8.4 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 4.0) • Android Studio at /Users/athor/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-2/193.6626763/Android Studio.app/Contents • Flutter plugin version 47.1.2 • Dart plugin version 193.7361 • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593) [!] Android Studio (version 4.1) • Android Studio at /Users/athor/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-1/201.6719854/Android Studio 4.1 Preview.app/Contents ✗ Flutter plugin not installed; this adds Flutter specific functionality. ✗ Dart plugin not installed; this adds Dart specific functionality. • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593) [!] Android Studio • Android Studio at /Users/athor/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/201.6720134/Android Studio 4.2 Preview.app/Contents ✗ Flutter plugin not installed; this adds Flutter specific functionality. ✗ Dart plugin not installed; this adds Dart specific functionality. • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593) [✓] IntelliJ IDEA Ultimate Edition (version 2020.2) • IntelliJ at /Users/athor/Applications/JetBrains Toolbox/IntelliJ IDEA Ultimate.app • Flutter plugin version 48.0.4-dev.4 • Dart plugin version 202.6397.47 [✓] VS Code (version 1.47.1) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.12.2 [✓] Connected device (3 available) • Android SDK built for x86 64 (mobile) • emulator-5554 • android-x64 • Android 10 (API 29) (emulator) • Web Server (web) • web-server • web-javascript • Flutter Tools • Chrome (web) • chrome • web-javascript • Google Chrome 84.0.4147.125 ! Doctor found issues in 2 categories. ```
pedromassangocode commented 3 years ago

Able to reproduce this on latest master channel.

flutter doctor -v ``` [✓] Flutter (Channel master, 1.21.0-10.0.pre.138, on Mac OS X 10.15.6 19G2021, locale en) • Flutter version 1.21.0-10.0.pre.138 at /Users/pedromassango/dev/SDKs/flutter_master • Framework revision 3562b3c0de (2 hours ago), 2020-08-18 01:46:02 -0400 • Engine revision 02de4eb7ce • Dart version 2.10.0 (build 2.10.0-37.0.dev) • Pub download mirror https://pub.flutter-io.cn • Flutter download mirror https://storage.flutter-io.cn [!] Android toolchain - develop for Android devices (Android SDK version 30.0.1) • Android SDK at /Users/pedromassango/Library/Android/sdk • Platform android-30, build-tools 30.0.1 • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593) ! Some Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses [✓] Xcode - develop for iOS and macOS (Xcode 11.6) • Xcode at /Applications/Xcode.app/Contents/Developer • Xcode 11.6, Build version 11E708 • CocoaPods version 1.9.3 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [!] Android Studio (version 4.0) • Android Studio at /Applications/Android Studio.app/Contents ✗ Flutter plugin not installed; this adds Flutter specific functionality. ✗ Dart plugin not installed; this adds Dart specific functionality. • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593) [✓] IntelliJ IDEA Community Edition (version 2020.2) • IntelliJ at /Applications/IntelliJ IDEA CE.app • Flutter plugin version 48.0.4 • Dart plugin version 202.6397.47 [!] VS Code (version 1.48.0) • VS Code at /Applications/Visual Studio Code.app/Contents ✗ Flutter extension not installed; install from https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter [✓] Connected device (3 available) • macOS (desktop) • macos • darwin-x64 • Mac OS X 10.15.6 19G2021 • Web Server (web) • web-server • web-javascript • Flutter Tools • Chrome (web) • chrome • web-javascript • Google Chrome 84.0.4147.125 ! Doctor found issues in 3 categories. ```
GrantSavill commented 3 years ago

Is there a workaround for this?

josh-burton commented 3 years ago

Not that I found as it is hardcoded in the FlutterActivity. You could potentially create your own version of the FlutterActivity.

@blasten is the Android embedding your area of expertise? Any suggestions on this bug?

GrantSavill commented 3 years ago

Just tried a release version of my app and it doesn't appear to be noticeable, so may just be an issue whilst debugging.

ajbeattie commented 3 years ago

I have this issue (even in release mode) and it seems to have become more pronounced after moving from 1.20 to 1.22.

Just watching the app launch, the time between splash screen fading and widgets being drawn to the screen has increased (seemingly as a result of the splash screen being visible for a shorter time), which means the time that this darker status bar is present has increased as well. This unfortunately makes the app launch feel pretty sloppy.

1.20 - splash screen stays visible until just before flutter widgets are rendered, and the darkened status bar flashes only for a brief moment. Not perfect, but better than in 1.22 (below).

https://user-images.githubusercontent.com/6845951/104380784-2c2e1080-54f1-11eb-8cdd-11f545de9016.mp4

1.22 - splash screen theme is replaced by normal theme much quicker, and the darkened status bar is visible for a much longer time before flutter widgets are rendered.

https://user-images.githubusercontent.com/6845951/104380812-351ee200-54f1-11eb-9693-bfbab65b6ee9.mp4

For a generic example that shows this issue, see the examples in https://github.com/flutter/flutter/issues/73351. In this example they use a flutter based splash screen after the launch theme is switched to the normal theme, but you can still see the status bar switch color for a noticeable length of time before switching back to their configured color.

Any update or workaround on this?

GrantSavill commented 3 years ago

Does it help at all if you set the status bar colour before runApp? For example:

...
import 'package:flutter/services.dart';

void main() {
  SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
    statusBarColor: Color(0x00000000),
  ));
  runApp(MyApp());
}
...
ajbeattie commented 3 years ago

@GrantSavill yes, this helps tremendously - not seeing the statusbar change in release mode anymore. Thank you very much!

GrantSavill commented 3 years ago

@ajbeattie glad I could help!

biklas7 commented 3 years ago

This solves the issue for me, but only in release mode.

josh-burton commented 3 years ago

Likely because release builds run a lot faster - which means that is a good work around but not a real fix as on slow devices the same issue could still appear.

joselicht90 commented 3 years ago

I had the same problem, and i found that the widget that was changing the color, was the AppBar. I had

AppBar(
        brightness: Brightness.dark,
        backgroundColor: Colors.transparent,
        iconTheme: IconThemeData(
            color: context.read<GlobalBloc>().styles.theme.primaryColor),
        elevation: 0,
      )

i had to change it to brightness: Brightness.light,

gaodeng commented 3 years ago

any news?

ziqq commented 3 years ago

it didn't help me

image image

HenryQuan commented 3 years ago

I encountered the same issue and it is as Josh said Flutter Activity is calling configureStatusBarForFullscreenFlutterExperience but you can do some workaround.

Android

Flutter

With a light theme and a light status bar, the status bar is completely white. This way, there is no brightness change. Once Flutter is loaded, it will replace with the colour and brightness you want to set. It is not perfect but works for me. Tested on Flutter 2.0.3.

https://user-images.githubusercontent.com/6754708/112262023-0e371600-8cc1-11eb-8ff3-4b9dbcb73a23.mov

OliverRhyme commented 3 years ago

Try on the android's MainActivity, Override the oncreate method then after calling super, set window.statusBarColor = Color.TRANSPARENT . This is just a workaround since Flutter activity automatically sets the status bar color. But by doing this is just reverting it back immediately to be transparent.

blasten commented 3 years ago

The engine sets a hardcoded bar color in a few places, which is likely happening before Dart starts executing (and this code runs).

Would anyone be interested in exploring a solution in that space? Maybe looking at the manifest, and if a custom color is set, avoid resetting the status bar color.

cc @xster for thoughts

macklinb commented 3 years ago

Flutter should just keep the status bar color the same color as the android:statusBarColor item (doc) of the NormalTheme in styles.xml - if set. Having it flicker between the launch screen color, then the seemingly unconfigurable theme color, then whatever color is set with setSystemUIOverlayType isn't a clean look.

vanlooverenkoen commented 3 years ago

This is what I am using. We only wanted to remove the black statusbar when the app is launching.

colors.xml

    <color name="statusbar">#40000000</color>

styles.xml

    <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
        <item name="android:windowBackground">@drawable/launch_background</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:statusBarColor">@color/statusbar</item>
    </style>

    <style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
        <item name="android:windowBackground">@drawable/launch_background</item>
    </style>
hectorAguero commented 3 years ago

@HenryQuan workaround works, these is a more complete example snippet.

MainActivity.kt

package com.example.app

import android.os.Bundle
import android.graphics.Color
import io.flutter.embedding.android.FlutterActivity

class MainActivity: FlutterActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        window.setStatusBarColor(Color.TRANSPARENT);
    }
}

main.dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setSystemUIOverlayStyle(
    SystemUiOverlayStyle(
      statusBarIconBrightness:
          WidgetsBinding.instance!.platformDispatcher.platformBrightness ==
                  Brightness.light
              ? Brightness.dark
              : Brightness.light,
    ),
  );
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Material App',
      theme: ThemeData.light(),
      darkTheme: ThemeData.dark(),
      home: Scaffold(
        body: Center(
          child: Container(
            child: Text('Hello World'),
          ),
        ),
      ),
    );
  }
}
muhammadidrees commented 2 years ago

Any update on this? I am having the same issue as well :(

hectorAguero commented 2 years ago

From what I understand, this issue is in someway fixed in flutter 2.5 with this https://flutter.dev/docs/development/ui/advanced/splash-screen#migrating-from-manifest--activity-defined-custom-splash-screens but not by default.

Flutter now automatically keeps the Android launch screen displayed until Flutter has drawn the first frame.

So I need to remove the meta tag io.flutter.embedding.android.SplashScreenDrawable in AndroidManifest.xml

change some configs in both styles.xml ```xml ```
Also if you dont want the shadow behind the statusbaricons, set to transparent ```dart import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle( systemNavigationBarColor: Colors.transparent, statusBarColor: Colors.transparent)); SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); return MaterialApp( title: 'Material App', home: Scaffold( appBar: AppBar( title: Text('Material App Bar'), ), body: ListView.builder( itemCount: 50, itemBuilder: (context, index) => Container( height: 100, color: index % 2 == 0 ? Colors.white : Colors.grey.shade900)), )); } } ```
droplet-js commented 2 years ago

any news update? it is helpful for custom splash screen

wytesk133 commented 2 years ago

@camsim99 FYI since you are working on #91128; see also b/201755161

emakar commented 2 years ago

Why just don't remove setStatusBarColor in configureStatusBarForFullscreenFlutterExperience?

darshankawar commented 1 year ago

Verified this issue using latest versions and using the code sample provided here and observed that the original issue persists as shown below:

https://user-images.githubusercontent.com/67046386/234843484-427d3862-fc0e-4539-8bed-bda979876b4c.mov

stable, master flutter doctor -v ``` [!] Flutter (Channel stable, 3.7.12, on macOS 12.2.1 21D62 darwin-x64, locale en-GB) • Flutter version 3.7.12 on channel stable at /Users/dhs/documents/fluttersdk/flutter ! Warning: `flutter` on your path resolves to /Users/dhs/Documents/Fluttersdk/flutter/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/dhs/documents/fluttersdk/flutter. Consider adding /Users/dhs/documents/fluttersdk/flutter/bin to the front of your path. ! Warning: `dart` on your path resolves to /Users/dhs/Documents/Fluttersdk/flutter/bin/dart, which is not inside your current Flutter SDK checkout at /Users/dhs/documents/fluttersdk/flutter. Consider adding /Users/dhs/documents/fluttersdk/flutter/bin to the front of your path. • Upstream repository https://github.com/flutter/flutter.git • Framework revision 4d9e56e694 (3 days ago), 2023-04-17 21:47:46 -0400 • Engine revision 1a65d409c7 • Dart version 2.19.6 • DevTools version 2.20.1 • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades. [!] Xcode - develop for iOS and macOS (Xcode 12.3) • Xcode at /Applications/Xcode.app/Contents/Developer ! Flutter recommends a minimum Xcode version of 13. Download the latest version or update via the Mac App Store. • CocoaPods version 1.11.2 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] VS Code (version 1.62.0) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.21.0 [✓] Connected device (5 available) • SM G975F (mobile) • RZ8M802WY0X • android-arm64 • Android 11 (API 30) • Darshan's iphone (mobile) • 21150b119064aecc249dfcfe05e259197461ce23 • ios • iOS 14.4.1 18D61 • iPhone 12 Pro Max (mobile) • A5473606-0213-4FD8-BA16-553433949729 • ios • com.apple.CoreSimulator.SimRuntime.iOS-14-3 (simulator) • macOS (desktop) • macos • darwin-x64 • Mac OS X 10.15.4 19E2269 darwin-x64 • Chrome (web) • chrome • web-javascript • Google Chrome 98.0.4758.80 [✓] HTTP Host Availability • All required HTTP hosts are available ! Doctor found issues in 1 category. [!] Flutter (Channel master, 3.10.0-15.0.pre.22, on macOS 12.2.1 21D62 darwin-x64, locale en-GB) • Flutter version 3.10.0-15.0.pre.22 on channel master at /Users/dhs/documents/fluttersdk/flutter ! Warning: `flutter` on your path resolves to /Users/dhs/Documents/Fluttersdk/flutter/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/dhs/documents/fluttersdk/flutter. Consider adding /Users/dhs/documents/fluttersdk/flutter/bin to the front of your path. ! Warning: `dart` on your path resolves to /Users/dhs/Documents/Fluttersdk/flutter/bin/dart, which is not inside your current Flutter SDK checkout at /Users/dhs/documents/fluttersdk/flutter. Consider adding /Users/dhs/documents/fluttersdk/flutter/bin to the front of your path. • Upstream repository https://github.com/flutter/flutter.git • Framework revision fdd6b87636 (44 minutes ago), 2023-04-27 00:29:23 -0400 • Engine revision d9f91aadff • Dart version 3.1.0 (build 3.1.0-48.0.dev) • DevTools version 2.23.1 • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades. [!] Android toolchain - develop for Android devices (Android SDK version 30.0.3) • Android SDK at /Users/dhs/Library/Android/sdk ✗ cmdline-tools component is missing Run `path/to/sdkmanager --install "cmdline-tools;latest"` See https://developer.android.com/studio/command-line for more details. ✗ Android license status unknown. Run `flutter doctor --android-licenses` to accept the SDK licenses. See https://flutter.dev/docs/get-started/install/macos#android-setup for more details. [✓] Xcode - develop for iOS and macOS (Xcode 13.2.1) • Xcode at /Applications/Xcode.app/Contents/Developer • Build 13C100 • CocoaPods version 1.11.2 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] IntelliJ IDEA Ultimate Edition (version 2021.3.2) • IntelliJ at /Applications/IntelliJ IDEA.app • Flutter plugin version 65.1.4 • Dart plugin version 213.7228 [✓] VS Code (version 1.62.0) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.29.0 [✓] Connected device (3 available) • Darshan's iphone (mobile) • 21150b119064aecc249dfcfe05e259197461ce23 • ios • iOS 15.3.1 19D52 • macOS (desktop) • macos • darwin-x64 • macOS 12.2.1 21D62 darwin-x64 • Chrome (web) • chrome • web-javascript • Google Chrome 109.0.5414.119 [✓] Network resources • All expected network resources are available. ! Doctor found issues in 1 category. [!] Xcode - develop for iOS and macOS (Xcode 12.3) • Xcode at /Applications/Xcode.app/Contents/Developer ! Flutter recommends a minimum Xcode version of 13. Download the latest version or update via the Mac App Store. • CocoaPods version 1.11.2 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] VS Code (version 1.62.0) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.21.0 [✓] Connected device (5 available) • SM G975F (mobile) • RZ8M802WY0X • android-arm64 • Android 11 (API 30) • Darshan's iphone (mobile) • 21150b119064aecc249dfcfe05e259197461ce23 • ios • iOS 14.4.1 18D61 • iPhone 12 Pro Max (mobile) • A5473606-0213-4FD8-BA16-553433949729 • ios • com.apple.CoreSimulator.SimRuntime.iOS-14-3 (simulator) • macOS (desktop) • macos • darwin-x64 • Mac OS X 10.15.4 19E2269 darwin-x64 • Chrome (web) • chrome • web-javascript • Google Chrome 98.0.4758.80 [✓] HTTP Host Availability • All required HTTP hosts are available ! Doctor found issues in 1 category. ```
RolandDaum commented 3 weeks ago

Thank you. This fixed it for me.

> void main() {
>   WidgetsFlutterBinding.ensureInitialized();
>   SystemChrome.setSystemUIOverlayStyle(
>     SystemUiOverlayStyle(
>       statusBarIconBrightness:
>           WidgetsBinding.instance!.platformDispatcher.platformBrightness ==
>                   Brightness.light
>               ? Brightness.dark
>               : Brightness.light,
>     ),
>   );
>   runApp(MyApp());
> }