Skip to content

Commit 98c67ab

Browse files
committed
Fix StatusBar not applying to Modal windows on Android
1 parent f832c91 commit 98c67ab

2 files changed

Lines changed: 73 additions & 36 deletions

File tree

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/statusbar/StatusBarModule.kt

Lines changed: 44 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@ package com.facebook.react.modules.statusbar
99

1010
import android.animation.ArgbEvaluator
1111
import android.animation.ValueAnimator
12-
import android.os.Build
13-
import android.view.View
14-
import android.view.WindowInsetsController
12+
import android.view.Window
1513
import android.view.WindowManager
14+
import androidx.core.view.ViewCompat
15+
import androidx.core.view.WindowCompat
16+
import androidx.core.view.WindowInsetsCompat
1617
import com.facebook.common.logging.FLog
1718
import com.facebook.fbreact.specs.NativeStatusBarManagerAndroidSpec
19+
import com.facebook.react.bridge.ExtraWindowEventListener
1820
import com.facebook.react.bridge.GuardedRunnable
1921
import com.facebook.react.bridge.NativeModule
2022
import com.facebook.react.bridge.ReactApplicationContext
@@ -24,13 +26,43 @@ import com.facebook.react.module.annotations.ReactModule
2426
import com.facebook.react.uimanager.DisplayMetricsHolder.getStatusBarHeightPx
2527
import com.facebook.react.uimanager.PixelUtil
2628
import com.facebook.react.views.view.isEdgeToEdgeFeatureFlagOn
29+
import com.facebook.react.views.view.setStatusBarStyle
2730
import com.facebook.react.views.view.setStatusBarTranslucency
2831
import com.facebook.react.views.view.setStatusBarVisibility
2932

3033
/** [NativeModule] that allows changing the appearance of the status bar. */
3134
@ReactModule(name = NativeStatusBarManagerAndroidSpec.NAME)
3235
internal class StatusBarModule(reactContext: ReactApplicationContext?) :
33-
NativeStatusBarManagerAndroidSpec(reactContext) {
36+
NativeStatusBarManagerAndroidSpec(reactContext), ExtraWindowEventListener {
37+
38+
private val extraWindows = mutableSetOf<Window>()
39+
40+
init {
41+
reactApplicationContext.addExtraWindowEventListener(this)
42+
}
43+
44+
override fun invalidate() {
45+
super.invalidate()
46+
reactApplicationContext.removeExtraWindowEventListener(this)
47+
}
48+
49+
override fun onExtraWindowCreate(window: Window) {
50+
extraWindows.add(window)
51+
52+
UiThreadUtil.runOnUiThread {
53+
val controller = WindowCompat.getInsetsController(window, window.decorView)
54+
val insets = ViewCompat.getRootWindowInsets(window.decorView)
55+
val style = if (controller.isAppearanceLightStatusBars) "dark-content" else "light-content"
56+
val visible = insets?.isVisible(WindowInsetsCompat.Type.statusBars()) ?: true
57+
58+
window.setStatusBarStyle(style)
59+
window.setStatusBarVisibility(!visible)
60+
}
61+
}
62+
63+
override fun onExtraWindowDestroy(window: Window) {
64+
extraWindows.remove(window)
65+
}
3466

3567
@Suppress("DEPRECATION")
3668
override fun getTypedExportedConstants(): Map<String, Any> {
@@ -118,10 +150,12 @@ internal class StatusBarModule(reactContext: ReactApplicationContext?) :
118150
)
119151
return
120152
}
121-
UiThreadUtil.runOnUiThread { activity.window?.setStatusBarVisibility(hidden) }
153+
UiThreadUtil.runOnUiThread {
154+
activity.window?.setStatusBarVisibility(hidden)
155+
extraWindows.forEach { it.setStatusBarVisibility(hidden) }
156+
}
122157
}
123158

124-
@Suppress("DEPRECATION")
125159
override fun setStyle(style: String?) {
126160
val activity = reactApplicationContext.getCurrentActivity()
127161
if (activity == null) {
@@ -131,36 +165,10 @@ internal class StatusBarModule(reactContext: ReactApplicationContext?) :
131165
)
132166
return
133167
}
134-
UiThreadUtil.runOnUiThread(
135-
Runnable {
136-
val window = activity.window ?: return@Runnable
137-
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
138-
val insetsController = window.insetsController ?: return@Runnable
139-
if ("dark-content" == style) {
140-
// dark-content means dark icons on a light status bar
141-
insetsController.setSystemBarsAppearance(
142-
WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS,
143-
WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS,
144-
)
145-
} else {
146-
insetsController.setSystemBarsAppearance(
147-
0,
148-
WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS,
149-
)
150-
}
151-
} else {
152-
val decorView = window.decorView
153-
var systemUiVisibilityFlags = decorView.systemUiVisibility
154-
systemUiVisibilityFlags =
155-
if ("dark-content" == style) {
156-
systemUiVisibilityFlags or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
157-
} else {
158-
systemUiVisibilityFlags and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
159-
}
160-
decorView.systemUiVisibility = systemUiVisibilityFlags
161-
}
162-
}
163-
)
168+
UiThreadUtil.runOnUiThread {
169+
activity.window?.setStatusBarStyle(style)
170+
extraWindows.forEach { it.setStatusBarStyle(style) }
171+
}
164172
}
165173

166174
companion object {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/WindowUtil.kt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ package com.facebook.react.views.view
99

1010
import android.graphics.Color
1111
import android.os.Build
12+
import android.view.View
1213
import android.view.Window
14+
import android.view.WindowInsetsController
1315
import android.view.WindowManager
1416
import androidx.core.view.ViewCompat
1517
import androidx.core.view.WindowCompat
@@ -65,6 +67,33 @@ internal fun Window.setStatusBarVisibility(isHidden: Boolean) {
6567
}
6668
}
6769

70+
@Suppress("DEPRECATION")
71+
internal fun Window.setStatusBarStyle(style: String?) {
72+
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
73+
if ("dark-content" == style) {
74+
// dark-content means dark icons on a light status bar
75+
insetsController?.setSystemBarsAppearance(
76+
WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS,
77+
WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS,
78+
)
79+
} else {
80+
insetsController?.setSystemBarsAppearance(
81+
0,
82+
WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS,
83+
)
84+
}
85+
} else {
86+
var systemUiVisibilityFlags = decorView.systemUiVisibility
87+
systemUiVisibilityFlags =
88+
if ("dark-content" == style) {
89+
systemUiVisibilityFlags or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
90+
} else {
91+
systemUiVisibilityFlags and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
92+
}
93+
decorView.systemUiVisibility = systemUiVisibilityFlags
94+
}
95+
}
96+
6897
@Suppress("DEPRECATION")
6998
private fun Window.statusBarHide() {
7099
if (isEdgeToEdgeFeatureFlagOn) {

0 commit comments

Comments
 (0)