Skip to content

IOS When the app switches from the foreground to the background, using Theme.of(context) will cause a rebuild, and Theme.of(context).brightness will return an incorrect value. This leads to a brief black-and-white flicker when switching from the background to the foreground. #142890

Closed

Description

@disonwei

Steps to reproduce

My application supports both light and dark modes.

Initially, I used Theme.of(context).extension()!.homeCardBGColor! to define the color of components in my application.

When the app is set to light mode, I noticed a brief flicker in the color of components using Theme.of(context).extension()!.homeCardBGColor!
when the app switches from the background to the foreground.

The color momentarily changes from black to white before settling on the final color.

Similarly, when the app is set to dark mode, there is a momentary change from white to black before reverting to the correct color.

For this issue, I wrote a test code to troubleshoot and found that when using color: Theme.of(context).primaryColor in the component, it causes all components to rebuild when the app switches from the foreground to the background.

I also observed that during the rebuilding process, the output of Theme.of(context).brightness is incorrect, showing "Brightness.light" even though my app is set to "Brightness.dark".

However, when the app returns from the background to the foreground, the output of Theme.of(context).brightness is correct, showing "Brightness.dark".

Therefore, I believe that the brief flicker in the page occurs because the app's theme changes from "Brightness.light" to "Brightness.dark" during the transition from the background to the foreground.

Expected results

  1. The app switching from the background to the foreground will not flicker.
  2. The app switching from the foreground to the background will not cause page reconstruction if Theme.of(context).primaryColor is used.
  3. When the app switches from the foreground to the background, Theme.of(context).brightness should obtain the correct value.

Actual results

  1. When the app switches from the background to the foreground, it will flicker, as shown in the video.
  2. Using Theme.of(context).primaryColor when the app switches from the foreground to the background will cause page reconstruction.
  3. When the app switches from the foreground to the background, Theme.of(context).brightness retrieves incorrect values.

Code sample

Code sample
/// main
void main() async {
  WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
  await SharedStorageBase.init();
  print("main ");
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print("myapp ");
    return ScreenUtilInit(
        designSize: const Size(430, 932),
        minTextAdapt: true,
        useInheritedMediaQuery: true,
        builder: (context, child) {
          return MediaQuery(
              ///Setting font does not change with system font size
              data: MediaQuery.of(context)
                  .copyWith(textScaler: const TextScaler.linear(1.0)),
              child:
              GestureDetector(
              onTap: () {
          KeyboardUtil.hideKeyboard(Get.context!);
          },
          child:
              GetMaterialApp(
                title: "Application",
                initialRoute: AppPages.INITIAL,
                getPages: AppPages.routes,
                
                themeMode: ThemeTool.getThemeModel(),
                theme: AppTheme.lightTheme,
                darkTheme: AppTheme.darkTheme,
              )));
        });
  }
}

// home
  Widget test1(context){

    var data = Theme.of(context).brightness;

    print("Theme.of(context).brightness ${ data}");
    print("isDarkMode ${Get.isDarkMode}");
    
    return Container(
      color: Theme.of(context)
          .primaryColor,
      height: 200,
      width: 200,
      child: Text(controller.count.value.toString()),
    );
  }

  @override
  Widget build(BuildContext context) {
    print("22222");
    return Scaffold(
      resizeToAvoidBottomInset: false,
      body: ListView(
        children: [
          TextField(),
         Obx(() =>  test1(context),),

        ],
      ),
    );
  }







Screenshots or Video

Screenshots / Video demonstration

[Upload media here]

2024-02-04.22.33.42.mov

Logs

Logs
The app switches from the foreground to the background:

flutter: home build
flutter: Theme.of(context).brightness Brightness.light
flutter: isDarkMode false


The app switches from the background to the foreground again:

flutter: home build
flutter: Theme.of(context).brightness Brightness.dark
flutter: isDarkMode true





Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.16.9, on macOS 14.1.2 23B92 darwin-arm64, locale zh-Hans-US)
    • Flutter version 3.16.9 on channel stable at /Users/dison/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 41456452f2 (10 days ago), 2024-01-25 10:06:23 -0800
    • Engine revision f40e976bed
    • Dart version 3.2.6
    • DevTools version 2.28.5

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    • Android SDK at /Users/dison/Library/Android/sdk
    • Platform android-34, build-tools 34.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 15C65
    • CocoaPods version 1.14.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2022.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • 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 17.0.6+0-17.0.6b829.9-10027231)

[✓] Android Studio (version 2022.3)
    • Android Studio at /Users/dison/Applications/Android Studio.app/Contents
    • 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 17.0.6+0-17.0.6b829.9-10027231)

[✓] VS Code (version 1.85.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension can be installed from:
      🔨 https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter

[✓] Connected device (4 available)
    • dison_3pm (mobile)     • 00008110-000459100C42801E            • ios            • iOS 17.1.2 21B101
    • iPhone 15 Pro (mobile) • 178033B7-C85D-4241-80E6-94319B548077 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-17-2 (simulator)
    • macOS (desktop)        • macos                                • darwin-arm64   • macOS 14.1.2 23B92 darwin-arm64
    • Chrome (web)           • chrome                               • web-javascript • Google Chrome 121.0.6167.139

[✓] Network resources
    • All expected network resources are available.

Activity

  1. darshankawar commented on Feb 5, 2024

    @darshankawar
    Member

    @disonwei
    I see that you have custom implementations in code sample provided. Can you try to remove those implementations and just use framework code (without third party packages) and check if you still get same behavior as reported ?
    If so, please provide us updated runnable reproducible code sample to verify it further.

  2. added
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Feb 5, 2024
  3. disonwei commented on Feb 5, 2024

    @disonwei
    Author

    This is a simple example program.

    The issue I want to address is that when themeMode is set to ThemeMode.system, the iOS program will cause the page to rebuild when returning from the background, and Theme.of(context).brightness will print the incorrect Brightness state.

    However, when themeMode is set to ThemeMode.dark or ThemeMode.light, it will not cause a rebuild, and the state of Theme.of(context).brightness will not change, which is the correct behavior.

    ///main 
    void main() async {
      print("main ");
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        print("myapp ");
        return MaterialApp(
          title: "Application",
          themeMode:ThemeMode.system,
          theme: AppTheme.lightTheme,
          darkTheme: AppTheme.darkTheme,
          home: HomeView()
        );
      }
    }
    
    ////home
    
    class HomeView extends StatelessWidget {
      const HomeView({Key? key}) : super(key: key);
    
      Widget test1(context){
    
        var data = Theme.of(context).brightness;
        print("-------test1 has been called------");
        print("Theme.of(context).brightness ${ data}");
        return Container(
          color: Theme.of(context)
              .primaryColor,
          height: 200,
          width: 200,
          child: Text("123"),
        );
      }
    
      @override
      Widget build(BuildContext context) {
        print("home build");
        return Scaffold(
          resizeToAvoidBottomInset: false,
          body: ListView(
            children: [
              TextField(),
              test1(context),
    
            ],
          ),
        );
      }
    }
    

    @darshankawar

    2.5.mp4
  4. removed
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Feb 5, 2024
  5. disonwei commented on Feb 5, 2024

    @disonwei
    Author

    I also tried in my application.

    When I set themeMode: ThemeMode.system, it causes the app to refresh when switching to the background, and when switching back to the foreground, it causes a black-and-white flickering issue.

    However, when I set themeMode: ThemeMode.dark or themeMode: ThemeMode.light, the components are not re-created.

    The issue seems to be related to themeMode: ThemeMode.system.
    Please help me troubleshoot this problem. Thank you very much.

  6. darshankawar commented on Feb 6, 2024

    @darshankawar
    Member

    Thanks for the details @disonwei
    Check the documentation for how the themeMode works and see if it helps to give you further reference.

    Since you are using all below properties, it states that:

    If set to [ThemeMode.system](https://api.flutter.dev/flutter/material/ThemeMode.html), the choice of which theme to use will be based on the user's system preferences. If the [MediaQuery.platformBrightnessOf](https://api.flutter.dev/flutter/widgets/MediaQuery/platformBrightnessOf.html) is [Brightness.light](https://api.flutter.dev/flutter/dart-ui/Brightness.html), [theme](https://api.flutter.dev/flutter/material/MaterialApp/theme.html) will be used. If it is [Brightness.dark](https://api.flutter.dev/flutter/dart-ui/Brightness.html), [darkTheme](https://api.flutter.dev/flutter/material/MaterialApp/darkTheme.html) will be used (unless it is null, in which case [theme](https://api.flutter.dev/flutter/material/MaterialApp/theme.html) will be used.
    
    If set to [ThemeMode.light](https://api.flutter.dev/flutter/material/ThemeMode.html) the [theme](https://api.flutter.dev/flutter/material/MaterialApp/theme.html) will always be used, regardless of the user's system preference.
    
    If set to [ThemeMode.dark](https://api.flutter.dev/flutter/material/ThemeMode.html) the [darkTheme](https://api.flutter.dev/flutter/material/MaterialApp/darkTheme.html) will be used regardless of the user's system preference. If [darkTheme](https://api.flutter.dev/flutter/material/MaterialApp/darkTheme.html) is null then it will fallback to using [theme](https://api.flutter.dev/flutter/material/MaterialApp/theme.html).
    
    themeMode:ThemeMode.system,
          theme: AppTheme.lightTheme,
          darkTheme: AppTheme.darkTheme,
    

    ie, the user device's system preferences also comes into play when above properties are used.

  7. added
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Feb 6, 2024
  8. github-actions commented on Feb 27, 2024

    @github-actions

    Without additional information, we are unfortunately not sure how to resolve this issue. We are therefore reluctantly going to close this bug for now.
    If you find this problem please file a new issue with the same description, what happens, logs and the output of 'flutter doctor -v'. All system setups can be slightly different so it's always better to open new issues and reference the related ones.
    Thanks for your contribution.

  9. github-actions commented on Mar 12, 2024

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  10. locked as resolved and limited conversation to collaborators on Mar 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    in triagePresently being triaged by the triage teamwaiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions