zoontek / react-native-edge-to-edge

Effortlessly enable edge-to-edge display in React Native (formerly known as react-native-bars).
MIT License
442 stars 19 forks source link

Initial load of Status Bar does not respect react-native useColorScheme hook #13

Closed vikrvm closed 2 years ago

vikrvm commented 2 years ago

Bug summary

So after going through the setup docs and getting things working, everything works just fine. The only thing I noticed is the initial load does not respect what color is set for the user's device. For example my current code:

const isDarkMode = useColorScheme() === 'dark';

<SystemBars
  animated={true}
  barStyle={isDarkMode ? 'light-content' : 'dark-content'}
/>

https://user-images.githubusercontent.com/6226652/191576643-436aad71-ee4f-46d8-8a6a-f1912ae5fde3.mov

Is there a fix to allow the <SystemBars /> initial styles to be relevant to the useColorScheme hook?

Library version

1.2.2

Environment info

System:
    OS: macOS 13.0
    CPU: (10) arm64 Apple M1 Max
    Memory: 1.44 GB / 32.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 18.9.0 - /opt/homebrew/bin/node
    Yarn: 1.22.18 - ~/.yarn/bin/yarn
    npm: 8.19.1 - /opt/homebrew/bin/npm
    Watchman: Not Found
  Managers:
    CocoaPods: 1.11.3 - /Users/vikrampal/.rbenv/shims/pod
  SDKs:
    iOS SDK:
      Platforms: DriverKit 21.4, iOS 16.0, macOS 12.3, tvOS 16.0, watchOS 9.0
    Android SDK: Not Found
  IDEs:
    Android Studio: 2021.2 AI-212.5712.43.2112.8815526
    Xcode: 14.0/14A309 - /usr/bin/xcodebuild
  Languages:
    Java: 18.0.2 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: 18.1.0 => 18.1.0 
    react-native: 0.70.1 => 0.70.1 
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Steps to reproduce

Steps show in the sample code.

Reproducible sample code

MainActivity.java

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    RNBootSplash.init(this);
    super.onCreate(null);
    RNBars.init(this, "light-content");
  }

values/styles.xml

<resources>

    <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
        <item name="android:editTextBackground">@drawable/rn_edit_text_material</item>

        <!-- Allow drawing under the system bars background -->
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:fitsSystemWindows">false</item>

        <!-- Set status bar background transparent -->
        <item name="android:statusBarColor">@android:color/transparent</item>

        <!-- Navigation bar will stay translucent on Android < 8.1 -->
        <item name="android:windowTranslucentNavigation">true</item>
    </style>

    <!-- BootTheme should inherit from Theme.SplashScreen -->
    <style name="BootTheme" parent="Theme.SplashScreen">
        <item name="windowSplashScreenBackground">@color/bootsplash_background</item>
        <item name="windowSplashScreenAnimatedIcon">@mipmap/bootsplash_logo</item>
        <item name="postSplashScreenTheme">@style/AppTheme</item>

        <!-- Status bar initial style: true = dark-content, false = light-content -->
        <item name="android:windowLightStatusBar">true</item>

        <!-- Navigation bar will stay translucent on Android < 8.1 -->
        <item name="android:windowTranslucentNavigation">true</item>
    </style>

</resources>

values-v27/styles.xml

<resources xmlns:tools="http://schemas.android.com/tools">

    <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
        <item name="android:editTextBackground">@drawable/rn_edit_text_material</item>

        <!-- Allow drawing under the system bars background -->
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:fitsSystemWindows">false</item>

        <!-- Set system bars background transparent -->
        <item name="android:statusBarColor">@android:color/transparent</item>
        <item name="android:navigationBarColor">@android:color/transparent</item>

        <!-- Disable auto contrasted system bars background -->
        <item name="android:enforceStatusBarContrast" tools:targetApi="q">false</item>
        <item name="android:enforceNavigationBarContrast" tools:targetApi="q">false</item>
    </style>

    <!-- BootTheme should inherit from Theme.SplashScreen -->
    <style name="BootTheme" parent="Theme.SplashScreen">
        <item name="windowSplashScreenBackground">@color/bootsplash_background</item>
        <item name="windowSplashScreenAnimatedIcon">@mipmap/bootsplash_logo</item>
        <item name="postSplashScreenTheme">@style/AppTheme</item>

        <!-- Bars initial styles: true = dark-content, false = light-content -->
        <item name="android:windowLightStatusBar">true</item>
        <item name="android:windowLightNavigationBar">true</item>
    </style>

</resources>
zoontek commented 2 years ago

That's normal, since at start the JS has to be loaded, parsed and executed first. If you want to support dark mode, you can duplicate your xml files and add a night suffix to the directory (ex: values-night, values-night-v27). More infos: https://developer.android.com/develop/ui/views/theming/darktheme

batuhansahan commented 1 year ago

@zoontek hey since i want to support both light and dark theme at the startup. I found a solution can you check it out. Its working without JS code. Do you think its a good idea doing like this.

Code


  @Override
  protected void onCreate(Bundle savedInstanceState) {
    RNBootSplash.init(this);
    super.onCreate(null);

    int currentNightMode = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
    if (currentNightMode == Configuration.UI_MODE_NIGHT_YES) {
      RNBars.init(this, "light-content");
    } else {
      RNBars.init(this, "dark-content");
    }
  }
zoontek commented 1 year ago

@batuhansahan It works yeah. Don't forget to also create a dedicated values-night-xxx.xml file too.