Skip to content

Commit da22c23

Browse files
authored
White stripes as statusbar and navigation bar on android (#8270)
* https://wix.atlassian.net/browse/WOAINFRA-3301 * lazy loading * No more white statusbar in dark mode
1 parent d872cce commit da22c23

File tree

2 files changed

+65
-8
lines changed

2 files changed

+65
-8
lines changed

android/src/main/java/com/reactnativenavigation/NavigationActivity.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,16 @@ public void onPostCreate(@Nullable Bundle savedInstanceState) {
7070
ViewGroup contentLayout = findViewById(android.R.id.content);
7171
navigator.setContentLayout(contentLayout);
7272
SystemUiUtils.setupSystemBarBackgrounds(this, contentLayout);
73+
applyThemeStatusBarColor();
74+
}
75+
76+
private void applyThemeStatusBarColor() {
77+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM
78+
&& SystemUiUtils.needsManualStatusBarBackground()) {
79+
//noinspection deprecation
80+
getWindow().setStatusBarColor(android.graphics.Color.TRANSPARENT);
81+
SystemUiUtils.setStatusBarColor(getWindow(), android.graphics.Color.TRANSPARENT);
82+
}
7383
}
7484

7585
@Override

android/src/main/java/com/reactnativenavigation/utils/SystemUiUtils.kt

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ object SystemUiUtils {
2525
private const val THREE_BUTTON_NAV_BAR_OPACITY = 0.8f
2626

2727
private var statusBarBackgroundView: View? = null
28+
private var statusBarBackgroundActivity: java.lang.ref.WeakReference<Activity>? = null
2829
private var navBarBackgroundView: View? = null
2930
@JvmStatic
3031
var isEdgeToEdgeActive = false
@@ -69,11 +70,11 @@ object SystemUiUtils {
6970
* Initializes view-based system bar backgrounds for edge-to-edge.
7071
* Call from Activity.onPostCreate after the navigator content layout is set.
7172
*
72-
* Status bar: reuses the system's android:id/statusBarBackground DecorView child.
73+
* Status bar: reuses the system's android:id/statusBarBackground DecorView child
74+
* when available. On API 35+ with EdgeToEdge, this view may not exist, so a
75+
* manual view is created in the content layout, sized by status bar insets.
7376
* Navigation bar: creates a view in [contentLayout] sized by WindowInsets,
7477
* since the system's navigationBarBackground is not available with EdgeToEdge.
75-
*
76-
* Both fall back to deprecated window APIs when the views are unavailable.
7778
*/
7879
@JvmStatic
7980
fun setupSystemBarBackgrounds(activity: Activity, contentLayout: ViewGroup) {
@@ -85,9 +86,35 @@ object SystemUiUtils {
8586
if (statusBarBackgroundView != null) return
8687
val sbView = activity.window.decorView.findViewById<View>(android.R.id.statusBarBackground)
8788
if (sbView != null) {
88-
sbView.setBackgroundColor(Color.BLACK)
8989
statusBarBackgroundView = sbView
90+
} else {
91+
statusBarBackgroundActivity = java.lang.ref.WeakReference(activity)
92+
}
93+
}
94+
95+
private fun ensureStatusBarBackgroundView(): View? {
96+
statusBarBackgroundView?.let { return it }
97+
val activity = statusBarBackgroundActivity?.get() ?: return null
98+
val contentLayout = activity.findViewById<ViewGroup>(android.R.id.content) ?: return null
99+
val view = View(activity)
100+
val params = FrameLayout.LayoutParams(
101+
FrameLayout.LayoutParams.MATCH_PARENT, 0, Gravity.TOP
102+
)
103+
contentLayout.addView(view, params)
104+
statusBarBackgroundView = view
105+
statusBarBackgroundActivity = null
106+
107+
ViewCompat.setOnApplyWindowInsetsListener(view) { v, insets ->
108+
val sbHeight = insets.getInsets(WindowInsetsCompat.Type.statusBars()).top
109+
val lp = v.layoutParams
110+
if (lp.height != sbHeight) {
111+
lp.height = sbHeight
112+
v.layoutParams = lp
113+
}
114+
insets
90115
}
116+
view.requestApplyInsets()
117+
return view
91118
}
92119

93120
private fun setupNavigationBarBackground(contentLayout: ViewGroup) {
@@ -131,6 +158,14 @@ object SystemUiUtils {
131158
return Color.argb(alpha, Color.red(DEFAULT_NAV_BAR_COLOR), Color.green(DEFAULT_NAV_BAR_COLOR), Color.blue(DEFAULT_NAV_BAR_COLOR))
132159
}
133160

161+
/**
162+
* Returns true when the system statusBarBackground view was not found during setup,
163+
* meaning a manual view will be lazily created on the first setStatusBarColor call.
164+
* Use this to decide whether to apply a theme-based initial status bar color.
165+
*/
166+
@JvmStatic
167+
fun needsManualStatusBarBackground(): Boolean = statusBarBackgroundActivity != null
168+
134169
/**
135170
* Marks edge-to-edge as active. Call after EdgeToEdge.enable() in the activity.
136171
* This flag controls whether navigation bar insets are forwarded to SafeAreaView
@@ -148,6 +183,7 @@ object SystemUiUtils {
148183
@JvmStatic
149184
fun tearDown() {
150185
statusBarBackgroundView = null
186+
statusBarBackgroundActivity = null
151187
navBarBackgroundView = null
152188
isEdgeToEdgeActive = false
153189
isThreeButtonNav = false
@@ -196,15 +232,26 @@ object SystemUiUtils {
196232
Color.green(color),
197233
Color.blue(color)
198234
)
199-
setStatusBarColor(window, opaqueColor)
235+
applyStatusBarColor(window, opaqueColor)
200236
}
201237

202238
/**
203-
* Sets the status bar background color.
204-
* Uses the view-based background when available (edge-to-edge),
205-
* falls back to the deprecated window API on older configurations.
239+
* Sets the status bar background color, lazily creating a manual view on API 35+
240+
* if the system view wasn't available at setup time. Use this for explicit app-level
241+
* color requests (e.g. from MainActivity or NavigationActivity).
206242
*/
243+
@JvmStatic
207244
fun setStatusBarColor(window: Window?, color: Int) {
245+
val view = ensureStatusBarBackgroundView()
246+
if (view != null) {
247+
view.setBackgroundColor(color)
248+
} else {
249+
@Suppress("DEPRECATION")
250+
window?.statusBarColor = color
251+
}
252+
}
253+
254+
private fun applyStatusBarColor(window: Window?, color: Int) {
208255
statusBarBackgroundView?.setBackgroundColor(color) ?: run {
209256
@Suppress("DEPRECATION")
210257
window?.statusBarColor = color

0 commit comments

Comments
 (0)