@@ -7,6 +7,7 @@ import android.app.Activity
77import android.content.res.Configuration
88import android.graphics.Color
99import android.util.TypedValue
10+ import android.view.Window
1011import android.view.WindowManager
1112
1213import androidx.core.view.WindowCompat
@@ -26,6 +27,9 @@ object EdgeToEdgeModuleImpl {
2627 private const val NO_ACTIVITY_ERROR = " $NAME : Ignored system bars change, current activity is null."
2728 private val boolAttributes = mutableMapOf<Int , Boolean >()
2829
30+ private var statusBarHidden = false
31+ private var navigationBarHidden = false
32+
2933 private fun resolveBoolAttribute (activity : Activity , resId : Int ): Boolean =
3034 boolAttributes.getOrPut(resId) {
3135 val value = TypedValue ()
@@ -40,14 +44,30 @@ object EdgeToEdgeModuleImpl {
4044 private fun isNavigationBarTransparent (activity : Activity ): Boolean =
4145 ! resolveBoolAttribute(activity, R .attr.enforceNavigationBarContrast)
4246
47+ // re-apply statusBarHidden / navigationBarHidden each time we instantiate a WindowInsetsControllerCompat
48+ // see https://github.com/zoontek/react-native-edge-to-edge/issues/66
49+ private fun initInsetsController (window : Window ): WindowInsetsControllerCompat =
50+ WindowInsetsControllerCompat (window, window.decorView).apply {
51+ systemBarsBehavior = WindowInsetsControllerCompat .BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
52+
53+ when (statusBarHidden) {
54+ true -> hide(WindowInsetsCompat .Type .statusBars())
55+ else -> show(WindowInsetsCompat .Type .statusBars())
56+ }
57+ when (navigationBarHidden) {
58+ true -> hide(WindowInsetsCompat .Type .navigationBars())
59+ else -> show(WindowInsetsCompat .Type .navigationBars())
60+ }
61+ }
62+
4363 @Suppress(" DEPRECATION" )
4464 fun applyEdgeToEdge (reactContext : ReactApplicationContext ? ) {
4565 val activity = reactContext?.currentActivity
4666 ? : return FLog .w(ReactConstants .TAG , " $NAME : Ignored, current activity is null." )
4767
4868 activity.runOnUiThread {
4969 val window = activity.window
50- val insetsController = WindowInsetsControllerCompat (window, window.decorView )
70+ val insetsController = initInsetsController (window)
5171
5272 WindowCompat .setDecorFitsSystemWindows(window, false )
5373
@@ -88,11 +108,6 @@ object EdgeToEdgeModuleImpl {
88108 else -> WindowManager .LayoutParams .LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
89109 }
90110 }
91-
92- // re-apply WindowInsetsController systemBarsBehavior each time
93- // see https://github.com/zoontek/react-native-edge-to-edge/issues/66
94- insetsController.systemBarsBehavior =
95- WindowInsetsControllerCompat .BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
96111 }
97112 }
98113
@@ -101,16 +116,12 @@ object EdgeToEdgeModuleImpl {
101116 ? : return FLog .w(ReactConstants .TAG , NO_ACTIVITY_ERROR )
102117
103118 activity.runOnUiThread {
104- val window = activity.window
105- val insetsController = WindowInsetsControllerCompat (window, window.decorView)
106-
107- insetsController.systemBarsBehavior =
108- WindowInsetsControllerCompat .BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
109-
110- insetsController.isAppearanceLightStatusBars = when (style) {
111- " dark-content" -> true
112- " light-content" -> false
113- else -> isDefaultLightSystemBars(activity)
119+ initInsetsController(activity.window).run {
120+ isAppearanceLightStatusBars = when (style) {
121+ " light-content" -> false
122+ " dark-content" -> true
123+ else -> isDefaultLightSystemBars(activity)
124+ }
114125 }
115126 }
116127 }
@@ -121,16 +132,12 @@ object EdgeToEdgeModuleImpl {
121132
122133 if (VERSION .SDK_INT >= VERSION_CODES .O_MR1 && isNavigationBarTransparent(activity)) {
123134 activity.runOnUiThread {
124- val window = activity.window
125- val insetsController = WindowInsetsControllerCompat (window, window.decorView)
126-
127- insetsController.systemBarsBehavior =
128- WindowInsetsControllerCompat .BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
129-
130- insetsController.isAppearanceLightNavigationBars = when (style) {
131- " dark-content" -> true
132- " light-content" -> false
133- else -> isDefaultLightSystemBars(activity)
135+ initInsetsController(activity.window).run {
136+ isAppearanceLightNavigationBars = when (style) {
137+ " light-content" -> false
138+ " dark-content" -> true
139+ else -> isDefaultLightSystemBars(activity)
140+ }
134141 }
135142 }
136143 }
@@ -140,35 +147,15 @@ object EdgeToEdgeModuleImpl {
140147 val activity = reactContext?.currentActivity
141148 ? : return FLog .w(ReactConstants .TAG , NO_ACTIVITY_ERROR )
142149
143- activity.runOnUiThread {
144- val window = activity.window
145- val insetsController = WindowInsetsControllerCompat (window, window.decorView)
146-
147- insetsController.systemBarsBehavior =
148- WindowInsetsControllerCompat .BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
149-
150- when (hidden) {
151- true -> insetsController.hide(WindowInsetsCompat .Type .statusBars())
152- else -> insetsController.show(WindowInsetsCompat .Type .statusBars())
153- }
154- }
150+ statusBarHidden = hidden
151+ activity.runOnUiThread { initInsetsController(activity.window) }
155152 }
156153
157154 fun setNavigationBarHidden (reactContext : ReactApplicationContext ? , hidden : Boolean ) {
158155 val activity = reactContext?.currentActivity
159156 ? : return FLog .w(ReactConstants .TAG , NO_ACTIVITY_ERROR )
160157
161- activity.runOnUiThread {
162- val window = activity.window
163- val insetsController = WindowInsetsControllerCompat (window, window.decorView)
164-
165- insetsController.systemBarsBehavior =
166- WindowInsetsControllerCompat .BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
167-
168- when (hidden) {
169- true -> insetsController.hide(WindowInsetsCompat .Type .navigationBars())
170- else -> insetsController.show(WindowInsetsCompat .Type .navigationBars())
171- }
172- }
158+ navigationBarHidden = hidden
159+ activity.runOnUiThread { initInsetsController(activity.window) }
173160 }
174161}
0 commit comments