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

On Android, when I open the app for the second time, the barStyle setting is invalid #2

Closed 1280103995 closed 2 years ago

1280103995 commented 2 years ago

Bug summary

In order to cooperate with the library react-native-bootsplash, a dark style is set in MainActivity: RNBars.init(MainActivity.this, "dark-content");(this is no problem).

Then set the default light-content in App.tsx. After exiting the app, restart the app and you will see that the status bar style has changed to dark-content.

Library version

1.0.4

Environment info

System:
    OS: macOS 11.5.2
    CPU: (6) x64 Intel(R) Core(TM) i5-8500B CPU @ 3.00GHz
    Memory: 62.12 MB / 8.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 15.4.0 - /usr/local/bin/node
    Yarn: 1.22.17 - /usr/local/bin/yarn
    npm: 7.0.15 - /usr/local/bin/npm
    Watchman: Not Found
  Managers:
    CocoaPods: 1.11.2 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 14.5, DriverKit 20.4, macOS 11.3, tvOS 14.5, watchOS 7.4
    Android SDK: Not Found
  IDEs:
    Android Studio: 4.2 AI-202.7660.26.42.7486908
    Xcode: 12.5/12E262 - /usr/bin/xcodebuild
  Languages:
    Java: 11.0.8 - /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/javac
    Python: 2.7.16 - /usr/bin/python
  npmPackages:
    @react-native-community/cli: Not Found
    react: 17.0.2 => 17.0.2 
    react-native: 0.66.3 => 0.66.3 
  npmGlobalPackages:
    *react-native*: Not Found

Steps to reproduce

1.Modify App.tsx in the example: Change const [isLightStatus, setIsLightStatus] = React.useState(false); to const [isLightStatus, setIsLightStatus] = React.useState(true);.

2.Exit the app, restart the app. (Click the virtual back button, the app is still on the recently used app screen)

Reproducible sample code

I used your sample project to debug, so you only need to modify the code according to the reproduction steps.
zoontek commented 2 years ago

@1280103995 Can you publish all your styles.xml? Give more info about how you tested it? (device, android version)

1280103995 commented 2 years ago

@1280103995 Can you publish all your styles.xml? Give more info about how you tested it? (device, android version)

I cloned your repository and only modified the content of App.txs in the example, so you can read the source code for the content of style.xml.

My device is: Samsung Galaxy A51 (Android 11)

style.xml

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
        <!-- 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>
</resources>

styles-v27.xml

<resources xmlns:tools="http://schemas.android.com/tools">
    <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
        <!-- 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 (on Android 10+) -->
        <item name="android:enforceStatusBarContrast" tools:targetApi="q">false</item>
        <item name="android:enforceNavigationBarContrast" tools:targetApi="q">false</item>
    </style>
</resources>
1280103995 commented 2 years ago

I guess the problem is here in StatusBar.tsx:

if (
      lastEntry != null &&
      // Update only if style have changed.
      (!oldProps || oldProps.barStyle !== lastEntry.barStyle)
) {

When I changed to: if (oldProps?.barStyle !== lastEntry.barStyle), this problem can be solved.

I found a new problem. Set light-content and dark-content on the two pages in BottomTabNavigator (react-navigation) respectively. After switching tabs back and forth, the status bar color will remain one color.

zoontek commented 2 years ago

@1280103995 You removed the lastEntry != null check?

A neat solution could be to exposes initial setting (set in MainActivity) and put it in propsStack at start.

1280103995 commented 2 years ago

@1280103995你取消了lastEntry != null支票?

一个巧妙的解决方案可能是公开初始设置(在 中设置MainActivity)并propsStack在开始时将其放入。

Canceling lastEntry != null is just a preliminary judgment, and the condition of if needs more detailed debugging.

zoontek commented 2 years ago

✅ Solved. The issue was a bit tedious: on pressing back to quit the app the propsStack was emptied (because all components are unmounted, each one will pop from the stack on componentWillUnmount), but mergedProps wasn't reset to null.

Now when calling updatePropsStack if the stack size is zero, mergedProps is resetted. Update and check by yourself 🙂

1280103995 commented 2 years ago

On v1.1.0, this issue has been resolved.:clap::clap:

Some extra words (not related to the library): Setting up a transparent Bar on Android is indeed a difficult task. :sweat_smile:

For example: 1.TextInput is covered by the keyboard.

  1. UI rendering is inaccurate due to the height of the Bar.
zoontek commented 2 years ago

Use react-native-safe-area-context. It exposes a hook to update insets dynamically 🙂