diff --git a/android/src/main/java/com/swmansion/rnscreens/Screen.kt b/android/src/main/java/com/swmansion/rnscreens/Screen.kt index a1e24fd6b0..dc2d437a48 100644 --- a/android/src/main/java/com/swmansion/rnscreens/Screen.kt +++ b/android/src/main/java/com/swmansion/rnscreens/Screen.kt @@ -134,16 +134,21 @@ class Screen( if (usesFormSheetPresentation()) { if (isSheetFitToContents()) { - sheetBehavior?.useSingleDetent(height) + sheetBehavior?.useSingleDetent(height, screen = this) } if (!BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { // On old architecture we delay enter transition in order to wait for initial frame. shouldTriggerPostponedTransitionAfterLayout = true + } + + println("onContentWrapperLayout $height, ${sheetBehavior?.maxHeight}, ${sheetBehavior?.peekHeight}") + if (height > (sheetBehavior?.peekHeight ?: Int.MAX_VALUE)) { val parent = parentAsViewGroup() if (parent != null && !parent.isInLayout) { // There are reported cases (irreproducible) when Screen is not laid out after // maxHeight is set on behaviour. + println("request") parent.requestLayout() } } @@ -200,6 +205,11 @@ class Screen( // glitchy. *This seems to not be needed on Fabric*. triggerPostponedEnterTransitionIfNeeded() } + println("onBottomSheetBehaviorDidLayout $height, ${sheetBehavior?.maxHeight}, ${sheetBehavior?.peekHeight}") + if (sheetBehavior!!.peekHeight < sheetBehavior!!.maxHeight) { + sheetBehavior?.setPeekHeight(height, true) + } + sheetBehavior?.isDraggable = true } private fun triggerPostponedEnterTransitionIfNeeded() { diff --git a/android/src/main/java/com/swmansion/rnscreens/bottomsheet/BottomSheetBehaviorExt.kt b/android/src/main/java/com/swmansion/rnscreens/bottomsheet/BottomSheetBehaviorExt.kt index 5e1d1b5683..e34c814ca5 100644 --- a/android/src/main/java/com/swmansion/rnscreens/bottomsheet/BottomSheetBehaviorExt.kt +++ b/android/src/main/java/com/swmansion/rnscreens/bottomsheet/BottomSheetBehaviorExt.kt @@ -2,18 +2,53 @@ package com.swmansion.rnscreens.bottomsheet import android.view.View import com.google.android.material.bottomsheet.BottomSheetBehavior +import com.google.android.material.bottomsheet.BottomSheetBehavior.BottomSheetCallback +import com.swmansion.rnscreens.Screen +import com.swmansion.rnscreens.ext.parentAsViewGroup +import kotlin.math.max internal fun BottomSheetBehavior.useSingleDetent( height: Int? = null, forceExpandedState: Boolean = true, + screen: Screen? = null ): BottomSheetBehavior { - this.skipCollapsed = true + this.skipCollapsed = false this.isFitToContents = true if (forceExpandedState) { - this.state = BottomSheetBehavior.STATE_EXPANDED + this.state = BottomSheetBehavior.STATE_COLLAPSED } + isDraggable = false + println("useSingleDetent $height $maxHeight $peekHeight") height?.let { - maxHeight = height + this.state = BottomSheetBehavior.STATE_COLLAPSED + if (height > maxHeight) { + maxHeight = height + } else if (height < maxHeight) { + println("height <= maxHeight, adding callback") + addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() { + override fun onStateChanged(bottomSheet: View, newState: Int) { + println(newState) + if (newState == BottomSheetBehavior.STATE_COLLAPSED) { + removeBottomSheetCallback(this) + maxHeight = height + screen?.apply { + val parent = parentAsViewGroup() + if (parent != null && !parent.isInLayout) { + // There are reported cases (irreproducible) when Screen is not laid out after + // maxHeight is set on behaviour. + println("request inner") + parent.requestLayout() + } + } + } + } + + override fun onSlide(bottomSheet: View, slideOffset: Float) { + } + + }) + setPeekHeight(height, true) + } } return this } diff --git a/android/src/main/java/com/swmansion/rnscreens/bottomsheet/SheetUtils.kt b/android/src/main/java/com/swmansion/rnscreens/bottomsheet/SheetUtils.kt index ce131ca8ac..e28c84e1c9 100644 --- a/android/src/main/java/com/swmansion/rnscreens/bottomsheet/SheetUtils.kt +++ b/android/src/main/java/com/swmansion/rnscreens/bottomsheet/SheetUtils.kt @@ -85,7 +85,7 @@ object SheetUtils { 1 -> when (state) { STATE_HIDDEN -> -1 - STATE_EXPANDED -> 0 + STATE_COLLAPSED, STATE_EXPANDED -> 0 else -> throw IllegalArgumentException("[RNScreens] Invalid state $state for detentCount $detentCount") }