kadiraydinli / react-native-system-navigation-bar

React Native lets you customize the navigation bar for Android.
https://www.npmjs.com/package/react-native-system-navigation-bar
MIT License
270 stars 19 forks source link

Bug by selecting preferred system navigation from settings #39

Closed ashok3 closed 1 year ago

ashok3 commented 1 year ago

Bug:

I found an interesting bug trying to test the different system navigations from Settings on API 33 (emulator - I haven't been able to test on a real device). Default navigation is Gesture navigation, with which everything seems to be going well.

Screenshot_1675853153

I'm explicitly setting the system navigation color like this:

SystemNavigationBar.setNavigationColor(
  'white',
  'dark',
  'navigation',
);

The bug happens when I set 3-button navigation or 2-button navigation from Settings:

Screenshot_1675854305

As you can see, the bar style is 'light' instead of 'dark' (explicitly set).

Additional tests:

Versions:

ashok3 commented 1 year ago

Hi @kadiraydinli @cemocanon @zolbooo here is a temporary fix which I'm sure you could do better since I'm not so familiar with android.

diff --git a/node_modules/react-native-system-navigation-bar/android/src/main/java/com/.DS_Store b/node_modules/react-native-system-navigation-bar/android/src/main/java/com/.DS_Store
new file mode 100644
index 0000000..9858899
Binary files /dev/null and b/node_modules/react-native-system-navigation-bar/android/src/main/java/com/.DS_Store differ
diff --git a/node_modules/react-native-system-navigation-bar/android/src/main/java/com/reactnativesystemnavigationbar/SystemNavigationBarModule.java b/node_modules/react-native-system-navigation-bar/android/src/main/java/com/reactnativesystemnavigationbar/SystemNavigationBarModule.java
index 6ec70ac..145f8f6 100644
--- a/node_modules/react-native-system-navigation-bar/android/src/main/java/com/reactnativesystemnavigationbar/SystemNavigationBarModule.java
+++ b/node_modules/react-native-system-navigation-bar/android/src/main/java/com/reactnativesystemnavigationbar/SystemNavigationBarModule.java
@@ -17,6 +17,7 @@ import com.facebook.react.uimanager.IllegalViewOperationException;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
+import android.view.WindowInsetsController;

 @ReactModule(name = SystemNavigationBarModule.NAME)
 public class SystemNavigationBarModule extends ReactContextBaseJavaModule {
@@ -281,16 +282,41 @@ public class SystemNavigationBarModule extends ReactContextBaseJavaModule {
     if (getCurrentActivity() == null) {
       throw new IllegalViewOperationException("current activity is null");
     }
-    View decorView = getCurrentActivity().getWindow().getDecorView();
-    int bit = decorView.getSystemUiVisibility();

-    if (light) {
-      bit |= visibility;
+    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+      View decorView = getCurrentActivity().getWindow().getDecorView();
+      int bit = decorView.getSystemUiVisibility();
+
+      if (light) {
+        bit |= visibility;
+      } else {
+        bit &= ~visibility;
+      }
+
+      decorView.setSystemUiVisibility(bit);
     } else {
-      bit &= ~visibility;
-    }
+      WindowInsetsController insetsController = getCurrentActivity().getWindow().getInsetsController();

-    decorView.setSystemUiVisibility(bit);
+      if (visibility == View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR) {
+        if (light) {
+          insetsController.setSystemBarsAppearance(WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS, WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS);
+        } else {
+          insetsController.setSystemBarsAppearance(0, WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS);
+        }
+      } else if (visibility == View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) {
+        if (light) {
+          insetsController.setSystemBarsAppearance(WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS, WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS);
+        } else {
+          insetsController.setSystemBarsAppearance(0, WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS);
+        }
+      } else if (visibility == (View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR)) {
+        if (light) {
+          insetsController.setSystemBarsAppearance(WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS | WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS, WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS | WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS);
+        } else {
+          insetsController.setSystemBarsAppearance(0, WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS | WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS);
+        }
+      }
+    }
   }

   private void setModeStyle(Boolean light, Integer bar) {
diff --git a/node_modules/react-native-system-navigation-bar/src/index.tsx b/node_modules/react-native-system-navigation-bar/src/index.tsx
index cab6100..bb54f4a 100644
--- a/node_modules/react-native-system-navigation-bar/src/index.tsx
+++ b/node_modules/react-native-system-navigation-bar/src/index.tsx
@@ -80,7 +80,7 @@ const setNavigationColor = async (
   if (Platform.OS === 'android') {
     const { modeStyle, mode } = getBarModeTypes(style, bar);
     return await NavigationBar.setNavigationColor(
-      color === 'translucent' ? 0 : processColor(color),
+      color === 'translucent' ? 1 : processColor(color),
       color === 'translucent',
       modeStyle,
       mode

And here some references that could help you:

kadiraydinli commented 1 year ago

Thank you for the solution suggestion. You can access API Level 30 support from the latest version.