Skip to content

Commit 324af75

Browse files
committed
fix(android): remeasure coordinator layout on configuration change
1 parent f0d71c5 commit 324af75

4 files changed

Lines changed: 48 additions & 42 deletions

File tree

android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -278,19 +278,8 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
278278
// Attach coordinator to the root container
279279
rootContainerView = findRootContainerView()
280280
viewController.coordinatorLayout?.let { coordinator ->
281-
rootContainerView?.let { container ->
282-
container.addView(coordinator)
283-
284-
// Manually measure and layout for React Native views (they don't layout native children)
285-
container.post {
286-
if (container.width > 0 && container.height > 0) {
287-
val widthSpec = View.MeasureSpec.makeMeasureSpec(container.width, View.MeasureSpec.EXACTLY)
288-
val heightSpec = View.MeasureSpec.makeMeasureSpec(container.height, View.MeasureSpec.EXACTLY)
289-
coordinator.measure(widthSpec, heightSpec)
290-
coordinator.layout(0, 0, container.width, container.height)
291-
}
292-
}
293-
}
281+
rootContainerView?.addView(coordinator)
282+
coordinator.post { measureCoordinatorLayout() }
294283
}
295284

296285
// Register with observer to track sheet stack hierarchy
@@ -447,6 +436,7 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
447436

448437
override fun viewControllerDidChangeSize(width: Int, height: Int) {
449438
updateState(width, height)
439+
measureCoordinatorLayout()
450440
}
451441

452442
override fun viewControllerWillFocus() {
@@ -491,6 +481,19 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
491481

492482
// ==================== Private Helpers ====================
493483

484+
private fun measureCoordinatorLayout() {
485+
val coordinator = viewController.coordinatorLayout ?: return
486+
val width = viewController.screenWidth
487+
val height = viewController.realScreenHeight
488+
489+
if (width > 0 && height > 0) {
490+
val widthSpec = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY)
491+
val heightSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY)
492+
coordinator.measure(widthSpec, heightSpec)
493+
coordinator.layout(0, 0, width, height)
494+
}
495+
}
496+
494497
/**
495498
* Find the root container view for presenting the sheet.
496499
* This traverses up the view hierarchy to find the content view (android.R.id.content)

android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,13 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
361361
}
362362
}
363363

364+
override fun coordinatorLayoutDidChangeConfiguration() {
365+
if (!isPresented) return
366+
367+
updateStateDimensions()
368+
sheetView?.let { emitChangePositionDelegate(it.top, realtime = false) }
369+
}
370+
364371
// =============================================================================
365372
// MARK: - TrueSheetDimViewDelegate
366373
// =============================================================================
@@ -664,15 +671,7 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
664671
animate = isPresented
665672
)
666673

667-
val offset = if (expandedOffset == 0) topInset else 0
668-
val newHeight = realScreenHeight - expandedOffset - offset
669-
val newWidth = minOf(screenWidth, DEFAULT_MAX_WIDTH.dpToPx().toInt())
670-
671-
if (lastStateWidth != newWidth || lastStateHeight != newHeight) {
672-
lastStateWidth = newWidth
673-
lastStateHeight = newHeight
674-
delegate?.viewControllerDidChangeSize(newWidth, newHeight)
675-
}
674+
updateStateDimensions(expandedOffset)
676675

677676
if (isPresented) {
678677
setStateForDetentIndex(currentDetentIndex)
@@ -922,6 +921,19 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
922921
// MARK: - Detent Helpers
923922
// =============================================================================
924923

924+
private fun updateStateDimensions(expandedOffset: Int? = null) {
925+
val offset = expandedOffset ?: (realScreenHeight - detentCalculator.getDetentHeight(detents.last()))
926+
val topOffset = if (offset == 0) topInset else 0
927+
val newHeight = realScreenHeight - offset - topOffset
928+
val newWidth = minOf(screenWidth, DEFAULT_MAX_WIDTH.dpToPx().toInt())
929+
930+
if (lastStateWidth != newWidth || lastStateHeight != newHeight) {
931+
lastStateWidth = newWidth
932+
lastStateHeight = newHeight
933+
delegate?.viewControllerDidChangeSize(newWidth, newHeight)
934+
}
935+
}
936+
925937
fun translateSheet(translationY: Int) {
926938
val sheet = sheetView ?: return
927939

@@ -966,22 +978,6 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
966978
(getTag(R.id.react_test_id) as? String)?.let { info.viewIdResourceName = it }
967979
}
968980

969-
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
970-
super.onSizeChanged(w, h, oldw, oldh)
971-
972-
if (w == oldw && h == oldh) return
973-
if (!isPresented) return
974-
975-
// Skip reconfiguration if expanded and only height changed (e.g., keyboard)
976-
if (h + topInset >= screenHeight && isExpanded && oldw == w) return
977-
978-
post {
979-
setupSheetDetents()
980-
positionFooter()
981-
sheetView?.let { emitChangePositionDelegate(it.top, realtime = false) }
982-
}
983-
}
984-
985981
// =============================================================================
986982
// MARK: - RootView Touch Handling
987983
// =============================================================================

android/src/main/java/com/lodev09/truesheet/core/TrueSheetCoordinatorLayout.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.lodev09.truesheet.core
22

33
import android.annotation.SuppressLint
44
import android.content.Context
5+
import android.content.res.Configuration
56
import android.view.MotionEvent
67
import android.view.ViewConfiguration
78
import android.view.ViewGroup
@@ -12,6 +13,7 @@ import com.facebook.react.uimanager.ReactPointerEventsView
1213

1314
interface TrueSheetCoordinatorLayoutDelegate {
1415
fun coordinatorLayoutDidLayout(changed: Boolean)
16+
fun coordinatorLayoutDidChangeConfiguration()
1517
}
1618

1719
/**
@@ -53,6 +55,11 @@ class TrueSheetCoordinatorLayout(context: Context) :
5355
delegate?.coordinatorLayoutDidLayout(changed)
5456
}
5557

58+
override fun onConfigurationChanged(newConfig: Configuration?) {
59+
super.onConfigurationChanged(newConfig)
60+
delegate?.coordinatorLayoutDidChangeConfiguration()
61+
}
62+
5663
override val pointerEvents: PointerEvents
5764
get() = PointerEvents.BOX_NONE
5865

example/shared/src/screens/MapScreen.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,11 +192,11 @@ const MapScreenInner = ({
192192
onPress={() => sheetRef.current?.dismiss()}
193193
/>
194194
</View>
195-
<BasicSheet ref={basicSheet} onNavigateToModal={onNavigateToModal} />
196-
<PromptSheet ref={promptSheet} />
197-
<ScrollViewSheet ref={scrollViewSheet} />
198-
<GestureSheet ref={gestureSheet} />
199195
</ReanimatedTrueSheet>
196+
<BasicSheet ref={basicSheet} onNavigateToModal={onNavigateToModal} />
197+
<PromptSheet ref={promptSheet} />
198+
<ScrollViewSheet ref={scrollViewSheet} />
199+
<GestureSheet ref={gestureSheet} />
200200
<FlatListSheet ref={flatListSheet} />
201201
</View>
202202
);

0 commit comments

Comments
 (0)