@@ -9,28 +9,62 @@ package com.facebook.react.modules.statusbar
99
1010import android.animation.ArgbEvaluator
1111import android.animation.ValueAnimator
12- import android.os.Build
13- import android.view.View
14- import android.view.WindowInsetsController
12+ import android.view.Window
1513import android.view.WindowManager
14+ import androidx.core.view.ViewCompat
15+ import androidx.core.view.WindowCompat
16+ import androidx.core.view.WindowInsetsCompat
1617import com.facebook.common.logging.FLog
1718import com.facebook.fbreact.specs.NativeStatusBarManagerAndroidSpec
1819import com.facebook.react.bridge.GuardedRunnable
1920import com.facebook.react.bridge.NativeModule
2021import com.facebook.react.bridge.ReactApplicationContext
2122import com.facebook.react.bridge.UiThreadUtil
2223import com.facebook.react.common.ReactConstants
24+ import com.facebook.react.interfaces.ExtraWindowEventListener
2325import com.facebook.react.module.annotations.ReactModule
2426import com.facebook.react.uimanager.DisplayMetricsHolder.getStatusBarHeightPx
2527import com.facebook.react.uimanager.PixelUtil
2628import com.facebook.react.views.view.isEdgeToEdgeFeatureFlagOn
29+ import com.facebook.react.views.view.setStatusBarStyle
2730import com.facebook.react.views.view.setStatusBarTranslucency
2831import com.facebook.react.views.view.setStatusBarVisibility
32+ import java.util.Collections
33+ import java.util.WeakHashMap
2934
3035/* * [NativeModule] that allows changing the appearance of the status bar. */
3136@ReactModule(name = NativeStatusBarManagerAndroidSpec .NAME )
3237internal class StatusBarModule (reactContext : ReactApplicationContext ? ) :
33- NativeStatusBarManagerAndroidSpec (reactContext) {
38+ NativeStatusBarManagerAndroidSpec (reactContext), ExtraWindowEventListener {
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+ UiThreadUtil .runOnUiThread {
51+ extraWindows.add(window)
52+
53+ reactApplicationContext.currentActivity?.window?.let {
54+ val controller = WindowCompat .getInsetsController(it, it.decorView)
55+ val insets = ViewCompat .getRootWindowInsets(it.decorView)
56+ val style = if (controller.isAppearanceLightStatusBars) " dark-content" else " light-content"
57+ val visible = insets?.isVisible(WindowInsetsCompat .Type .statusBars()) ? : true
58+
59+ window.setStatusBarStyle(style)
60+ window.setStatusBarVisibility(! visible)
61+ }
62+ }
63+ }
64+
65+ override fun onExtraWindowDestroy (window : Window ) {
66+ UiThreadUtil .runOnUiThread { extraWindows.remove(window) }
67+ }
3468
3569 @Suppress(" DEPRECATION" )
3670 override fun getTypedExportedConstants (): Map <String , Any > {
@@ -118,10 +152,12 @@ internal class StatusBarModule(reactContext: ReactApplicationContext?) :
118152 )
119153 return
120154 }
121- UiThreadUtil .runOnUiThread { activity.window?.setStatusBarVisibility(hidden) }
155+ UiThreadUtil .runOnUiThread {
156+ activity.window?.setStatusBarVisibility(hidden)
157+ extraWindows.forEach { it.setStatusBarVisibility(hidden) }
158+ }
122159 }
123160
124- @Suppress(" DEPRECATION" )
125161 override fun setStyle (style : String? ) {
126162 val activity = reactApplicationContext.getCurrentActivity()
127163 if (activity == null ) {
@@ -131,41 +167,16 @@ internal class StatusBarModule(reactContext: ReactApplicationContext?) :
131167 )
132168 return
133169 }
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- )
170+ UiThreadUtil .runOnUiThread {
171+ activity.window?.setStatusBarStyle(style)
172+ extraWindows.forEach { it.setStatusBarStyle(style) }
173+ }
164174 }
165175
166176 companion object {
167177 private const val HEIGHT_KEY = " HEIGHT"
168178 private const val DEFAULT_BACKGROUND_COLOR_KEY = " DEFAULT_BACKGROUND_COLOR"
169179 const val NAME : String = NativeStatusBarManagerAndroidSpec .NAME
180+ private val extraWindows = Collections .newSetFromMap<Window >(WeakHashMap ())
170181 }
171182}
0 commit comments