From 573288ec7966754cc17cd7c79d771da72d3cb24e Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Fri, 20 Mar 2026 17:40:26 +0200 Subject: [PATCH] fix screenHeight crash on API <30, wrong height on API <35 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit currentWindowMetrics requires API 30 — crashes on Android 9. Split into 3 tiers: - API 35+: heightPixels (reliable, edge-to-edge mandatory) - API 30-34: currentWindowMetrics (includes nav bar) - API <30: getRealSize (full display, pre-WindowMetrics) Also set elevation=0 on bottom sheet FrameLayout to remove Material shadow visible at the corners. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../expo/modules/bottomsheet/BottomSheetView.kt | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/modules/bottom-sheet/android/src/main/java/expo/modules/bottomsheet/BottomSheetView.kt b/modules/bottom-sheet/android/src/main/java/expo/modules/bottomsheet/BottomSheetView.kt index 86a9317874..b7e81a61f6 100644 --- a/modules/bottom-sheet/android/src/main/java/expo/modules/bottomsheet/BottomSheetView.kt +++ b/modules/bottom-sheet/android/src/main/java/expo/modules/bottomsheet/BottomSheetView.kt @@ -33,17 +33,27 @@ class BottomSheetView( private var eventDispatcher: EventDispatcher? = null // Native content height observation (eliminates JS bridge round-trip) - private var contentLayoutListener: View.OnLayoutChangeListener? = null + private var contentLayoutListener: OnLayoutChangeListener? = null private var observedChildren: List = emptyList() private var lastObservedContentHeight: Float = 0f private var pendingLayoutUpdate: Boolean = false private val screenHeight: Float = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.VANILLA_ICE_CREAM) { + // API 35+: edge-to-edge is mandatory, heightPixels is the full display context.resources.displayMetrics.heightPixels.toFloat() - } else { + } else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) { + // API 30-34: heightPixels may exclude nav bar, use currentWindowMetrics val wm = context.getSystemService(Context.WINDOW_SERVICE) as android.view.WindowManager wm.currentWindowMetrics.bounds.height().toFloat() + } else { + // API < 30: currentWindowMetrics not available, use getRealSize + // which includes system bars (heightPixels may exclude them) + val wm = context.getSystemService(Context.WINDOW_SERVICE) as android.view.WindowManager + val size = android.graphics.Point() + @Suppress("DEPRECATION") + wm.defaultDisplay.getRealSize(size) + size.y.toFloat() } private fun getNavigationBarHeight(): Int { @@ -355,7 +365,7 @@ class BottomSheetView( val innerViewGroup = this.innerView as? ViewGroup ?: return - val listener = View.OnLayoutChangeListener { _, _, top, _, bottom, _, _, oldTop, oldBottom -> + val listener = OnLayoutChangeListener { _, _, top, _, bottom, _, _, oldTop, oldBottom -> val newHeight = bottom - top val oldHeight = oldBottom - oldTop if (newHeight != oldHeight) {