From 18f8b9bc9dde6070973af7d6b8b0cc4f6db8bb18 Mon Sep 17 00:00:00 2001 From: gusgushz Date: Mon, 4 May 2026 15:49:18 -0600 Subject: [PATCH] fix(android): prevent double status bar offset in legacy non edge-to-edge mode In legacy mode (edgeToEdgeEnabled=false), applyDecorViewTopInsetIfNeeded was applying topInset as paddingTop to the toolbar even though the system already positions the toolbar below the status bar. This caused the toolbar height to be inflated, resulting in unexpected bottom padding when headerShown=true. Fix detects legacy mode by comparing toolbar's Y position on screen with the status bar inset. In edge-to-edge the toolbar starts at y=0, in legacy it starts at y=statusBarInset, so paddingTop is only applied in edge-to-edge. --- .../com/swmansion/rnscreens/CustomToolbar.kt | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt b/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt index 21d334f1f9..8adf8c25ab 100644 --- a/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +++ b/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt @@ -7,6 +7,7 @@ import android.view.Choreographer import android.view.WindowInsets import android.view.WindowManager import androidx.appcompat.widget.Toolbar +import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import com.facebook.react.modules.core.ReactChoreographer import com.facebook.react.uimanager.ThemedReactContext @@ -125,7 +126,20 @@ open class CustomToolbar( val topInset = getDecorViewTopInset(decorView) if (topInset > 0) { - applyExactPadding(paddingLeft, topInset, paddingRight, paddingBottom) + // In legacy (non edge-to-edge) mode, the system already positions the toolbar + // below the status bar, so applying paddingTop would cause double offset. + // We detect this by comparing toolbar's position on screen with the status bar inset: + // in edge-to-edge the toolbar starts at y=0, in legacy it starts at y=statusBarInset. + val insetsCompat = ViewCompat.getRootWindowInsets(decorView) + val statusBarInset = insetsCompat?.getInsets(WindowInsetsCompat.Type.statusBars())?.top ?: 0 + val locationOnScreen = IntArray(2) + getLocationOnScreen(locationOnScreen) + val toolbarTopOnScreen = locationOnScreen[1] + val isEdgeToEdge = toolbarTopOnScreen < statusBarInset + + if (isEdgeToEdge) { + applyExactPadding(paddingLeft, topInset, paddingRight, paddingBottom) + } } }