diff --git a/android/src/main/java/com/zoontek/rnedgetoedge/RNEdgeToEdgeModuleImpl.kt b/android/src/main/java/com/zoontek/rnedgetoedge/RNEdgeToEdgeModuleImpl.kt
index bbf3e4c..f514440 100644
--- a/android/src/main/java/com/zoontek/rnedgetoedge/RNEdgeToEdgeModuleImpl.kt
+++ b/android/src/main/java/com/zoontek/rnedgetoedge/RNEdgeToEdgeModuleImpl.kt
@@ -1,10 +1,10 @@
package com.zoontek.rnedgetoedge
-import android.app.Activity
import android.content.res.Configuration
import android.graphics.Color
import android.os.Build
-import android.util.TypedValue
+import android.os.Handler
+import android.os.Looper
import android.view.WindowManager
import androidx.core.content.ContextCompat
@@ -13,36 +13,33 @@ import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
import com.facebook.common.logging.FLog
+import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.common.ReactConstants
object RNEdgeToEdgeModuleImpl {
const val NAME = "RNEdgeToEdge"
- private var isInitialHostResume = true
- fun onHostResume(activity: Activity?) {
- if (activity == null) {
- return FLog.w(ReactConstants.TAG, "$NAME: Ignored, current activity is null.")
- }
+ private fun applyEdgeToEdge(reactContext: ReactApplicationContext) {
+ val activity = reactContext.currentActivity
+ ?: return FLog.w(ReactConstants.TAG, "$NAME: Ignored, current activity is null.")
activity.runOnUiThread {
val window = activity.window
val view = window.decorView
val context = view.context
- val isDarkMode =
- view.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK ==
- Configuration.UI_MODE_NIGHT_YES
-
WindowCompat.setDecorFitsSystemWindows(window, false)
window.statusBarColor = Color.TRANSPARENT
+ window.navigationBarColor = ContextCompat.getColor(context, R.color.navigationBarColor)
- window.navigationBarColor = when {
- Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> Color.TRANSPARENT
- Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !isDarkMode ->
- ContextCompat.getColor(context, R.color.systemBarLightScrim)
- else -> ContextCompat.getColor(context, R.color.systemBarDarkScrim)
+ val isDarkMode =
+ view.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK ==
+ Configuration.UI_MODE_NIGHT_YES
+
+ WindowInsetsControllerCompat(window, view).run {
+ isAppearanceLightNavigationBars = !isDarkMode
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
@@ -50,38 +47,26 @@ object RNEdgeToEdgeModuleImpl {
window.isNavigationBarContrastEnforced = true
}
- WindowInsetsControllerCompat(window, view).run {
- if (isInitialHostResume) {
- val typedValue = TypedValue()
-
- isAppearanceLightStatusBars = activity
- .theme
- .resolveAttribute(android.R.attr.windowLightStatusBar, typedValue, true) &&
- typedValue.data != 0
- }
-
- isInitialHostResume = false
- isAppearanceLightNavigationBars = !isDarkMode
- }
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
window.attributes.layoutInDisplayCutoutMode = when {
- Build.VERSION.SDK_INT >= Build.VERSION_CODES.R ->
- WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
else -> WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
}
}
}
}
- fun onHostDestroy() {
- isInitialHostResume = true
+ fun onHostResume(reactContext: ReactApplicationContext) {
+ applyEdgeToEdge(reactContext)
}
- fun setSystemBarsConfig(activity: Activity?, config: ReadableMap) {
- if (activity == null) {
- return FLog.w(ReactConstants.TAG, "$NAME: Ignored, current activity is null.")
- }
+ fun onConfigChange(reactContext: ReactApplicationContext) {
+ Handler(Looper.getMainLooper()).postDelayed({ applyEdgeToEdge(reactContext) }, 100)
+ }
+
+ fun setSystemBarsConfig(reactContext: ReactApplicationContext, config: ReadableMap) {
+ val activity = reactContext.currentActivity
+ ?: return FLog.w(ReactConstants.TAG, "$NAME: Ignored, current activity is null.")
val statusBarHidden =
config.takeIf { it.hasKey("statusBarHidden") }?.getBoolean("statusBarHidden")
diff --git a/android/src/main/res/values-night-v27/styles.xml b/android/src/main/res/values-night-v27/styles.xml
new file mode 100644
index 0000000..35c64a3
--- /dev/null
+++ b/android/src/main/res/values-night-v27/styles.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/android/src/main/res/values-v26/styles.xml b/android/src/main/res/values-v26/styles.xml
deleted file mode 100644
index ad04568..0000000
--- a/android/src/main/res/values-v26/styles.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
diff --git a/android/src/main/res/values-v27/colors.xml b/android/src/main/res/values-v27/colors.xml
new file mode 100644
index 0000000..da6b559
--- /dev/null
+++ b/android/src/main/res/values-v27/colors.xml
@@ -0,0 +1,5 @@
+
+
+
+ #e6ffffff
+
diff --git a/android/src/main/res/values-v27/styles.xml b/android/src/main/res/values-v27/styles.xml
index c0fc338..61f85c2 100644
--- a/android/src/main/res/values-v27/styles.xml
+++ b/android/src/main/res/values-v27/styles.xml
@@ -1,8 +1,11 @@
+
+
diff --git a/android/src/main/res/values-v29/colors.xml b/android/src/main/res/values-v29/colors.xml
new file mode 100644
index 0000000..e6a17f3
--- /dev/null
+++ b/android/src/main/res/values-v29/colors.xml
@@ -0,0 +1,4 @@
+
+
+ @android:color/transparent
+
diff --git a/android/src/main/res/values-v29/styles.xml b/android/src/main/res/values-v29/styles.xml
index 83fe948..6658b45 100644
--- a/android/src/main/res/values-v29/styles.xml
+++ b/android/src/main/res/values-v29/styles.xml
@@ -4,6 +4,5 @@
- shortEdges
- false
- true
- - @android:color/transparent
diff --git a/android/src/main/res/values-v30/styles.xml b/android/src/main/res/values-v30/styles.xml
index d16c1bc..74e4539 100644
--- a/android/src/main/res/values-v30/styles.xml
+++ b/android/src/main/res/values-v30/styles.xml
@@ -4,6 +4,5 @@
- always
- false
- true
- - @android:color/transparent
diff --git a/android/src/main/res/values/colors.xml b/android/src/main/res/values/colors.xml
index fa8e93d..a45d90f 100644
--- a/android/src/main/res/values/colors.xml
+++ b/android/src/main/res/values/colors.xml
@@ -2,7 +2,5 @@
- #801b1b1b
-
- #e6ffffff
+ #801b1b1b
diff --git a/android/src/main/res/values/styles.xml b/android/src/main/res/values/styles.xml
index 8974fa4..39ba37e 100644
--- a/android/src/main/res/values/styles.xml
+++ b/android/src/main/res/values/styles.xml
@@ -8,9 +8,9 @@
- false
- true
- @android:color/transparent
+ - @color/navigationBarColor
diff --git a/android/src/newarch/com/zoontek/rnedgetoedge/RNEdgeToEdgeModule.kt b/android/src/newarch/com/zoontek/rnedgetoedge/RNEdgeToEdgeModule.kt
index 2651b4d..217c35b 100644
--- a/android/src/newarch/com/zoontek/rnedgetoedge/RNEdgeToEdgeModule.kt
+++ b/android/src/newarch/com/zoontek/rnedgetoedge/RNEdgeToEdgeModule.kt
@@ -1,19 +1,32 @@
package com.zoontek.rnedgetoedge
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+
import com.facebook.react.bridge.LifecycleEventListener
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.module.annotations.ReactModule
@ReactModule(name = RNEdgeToEdgeModuleImpl.NAME)
-class RNEdgeToEdgeModule(reactContext: ReactApplicationContext?) :
+class RNEdgeToEdgeModule(reactContext: ReactApplicationContext) :
NativeRNEdgeToEdgeSpec(reactContext), LifecycleEventListener {
+ private val configChangeReceiver = object : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) {
+ RNEdgeToEdgeModuleImpl.onConfigChange(reactContext)
+ }
+ }
+
init {
+ reactApplicationContext.registerReceiver(configChangeReceiver, IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED))
reactApplicationContext.addLifecycleEventListener(this)
}
override fun invalidate() {
+ reactApplicationContext.unregisterReceiver(configChangeReceiver)
reactApplicationContext.removeLifecycleEventListener(this)
}
@@ -22,16 +35,14 @@ class RNEdgeToEdgeModule(reactContext: ReactApplicationContext?) :
}
override fun onHostResume() {
- RNEdgeToEdgeModuleImpl.onHostResume(currentActivity)
+ RNEdgeToEdgeModuleImpl.onHostResume(reactApplicationContext)
}
override fun onHostPause() {}
- override fun onHostDestroy() {
- RNEdgeToEdgeModuleImpl.onHostDestroy()
- }
+ override fun onHostDestroy() {}
override fun setSystemBarsConfig(config: ReadableMap) {
- RNEdgeToEdgeModuleImpl.setSystemBarsConfig(currentActivity, config)
+ RNEdgeToEdgeModuleImpl.setSystemBarsConfig(reactApplicationContext, config)
}
}
diff --git a/android/src/oldarch/com/zoontek/rnedgetoedge/RNBarsModule.kt b/android/src/oldarch/com/zoontek/rnedgetoedge/RNBarsModule.kt
index 9f87282..455599b 100644
--- a/android/src/oldarch/com/zoontek/rnedgetoedge/RNBarsModule.kt
+++ b/android/src/oldarch/com/zoontek/rnedgetoedge/RNBarsModule.kt
@@ -1,5 +1,10 @@
package com.zoontek.rnedgetoedge
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+
import com.facebook.react.bridge.LifecycleEventListener
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
@@ -8,14 +13,22 @@ import com.facebook.react.bridge.ReadableMap
import com.facebook.react.module.annotations.ReactModule
@ReactModule(name = RNEdgeToEdgeModuleImpl.NAME)
-class RNEdgeToEdgeModule(reactContext: ReactApplicationContext?) :
+class RNEdgeToEdgeModule(reactContext: ReactApplicationContext) :
ReactContextBaseJavaModule(reactContext), LifecycleEventListener {
+ private val configChangeReceiver = object : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) {
+ RNEdgeToEdgeModuleImpl.onConfigChange(reactContext)
+ }
+ }
+
init {
+ reactApplicationContext.registerReceiver(configChangeReceiver, IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED))
reactApplicationContext.addLifecycleEventListener(this)
}
override fun invalidate() {
+ reactApplicationContext.unregisterReceiver(configChangeReceiver)
reactApplicationContext.removeLifecycleEventListener(this)
}
@@ -24,17 +37,15 @@ class RNEdgeToEdgeModule(reactContext: ReactApplicationContext?) :
}
override fun onHostResume() {
- RNEdgeToEdgeModuleImpl.onHostResume(currentActivity)
+ RNEdgeToEdgeModuleImpl.onHostResume(reactApplicationContext)
}
override fun onHostPause() {}
- override fun onHostDestroy() {
- RNEdgeToEdgeModuleImpl.onHostDestroy()
- }
+ override fun onHostDestroy() {}
@ReactMethod
fun setSystemBarsConfig(config: ReadableMap) {
- RNEdgeToEdgeModuleImpl.setSystemBarsConfig(currentActivity, config)
+ RNEdgeToEdgeModuleImpl.setSystemBarsConfig(reactApplicationContext, config)
}
}
diff --git a/package.json b/package.json
index ed6d72f..322b429 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "react-native-edge-to-edge",
- "version": "0.1.2",
+ "version": "0.2.0",
"license": "MIT",
"description": "Effortlessly enable edge-to-edge display in React Native",
"author": "Mathieu Acthernoene ",