Fix content scrolling not working in the RTE (#6492)
Implement a `customDetectVerticalDragGestures` that matches the original `detectVerticalDragGestures` expect we conditionally consume the initial DOWN event in compose to decide whether we need to drag the bottom sheet or scroll inside the Android `EditText`
This commit is contained in:
parent
786c260fc2
commit
ba81e44052
1 changed files with 53 additions and 3 deletions
|
|
@ -16,7 +16,10 @@ import android.widget.EditText
|
||||||
import androidx.appcompat.app.ActionBar.LayoutParams
|
import androidx.appcompat.app.ActionBar.LayoutParams
|
||||||
import androidx.compose.animation.core.Animatable
|
import androidx.compose.animation.core.Animatable
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.gestures.detectVerticalDragGestures
|
import androidx.compose.foundation.gestures.awaitEachGesture
|
||||||
|
import androidx.compose.foundation.gestures.awaitFirstDown
|
||||||
|
import androidx.compose.foundation.gestures.awaitVerticalPointerSlopOrCancellation
|
||||||
|
import androidx.compose.foundation.gestures.verticalDrag
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.BoxScope
|
import androidx.compose.foundation.layout.BoxScope
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
|
@ -41,10 +44,14 @@ import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.geometry.Offset
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.RectangleShape
|
import androidx.compose.ui.graphics.RectangleShape
|
||||||
import androidx.compose.ui.graphics.Shape
|
import androidx.compose.ui.graphics.Shape
|
||||||
|
import androidx.compose.ui.input.pointer.PointerInputChange
|
||||||
|
import androidx.compose.ui.input.pointer.PointerInputScope
|
||||||
import androidx.compose.ui.input.pointer.pointerInput
|
import androidx.compose.ui.input.pointer.pointerInput
|
||||||
|
import androidx.compose.ui.input.pointer.positionChange
|
||||||
import androidx.compose.ui.layout.Layout
|
import androidx.compose.ui.layout.Layout
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
|
@ -94,7 +101,7 @@ fun ExpandableBottomSheetLayout(
|
||||||
.run {
|
.run {
|
||||||
if (isSwipeGestureEnabled) {
|
if (isSwipeGestureEnabled) {
|
||||||
pointerInput(maxBottomSheetContentHeight) {
|
pointerInput(maxBottomSheetContentHeight) {
|
||||||
detectVerticalDragGestures(
|
customDetectVerticalDragGestures(
|
||||||
onVerticalDrag = { _, dragAmount ->
|
onVerticalDrag = { _, dragAmount ->
|
||||||
val calculatedHeight = max(minBottomContentHeightPx, currentBottomContentHeightPx - dragAmount.roundToInt())
|
val calculatedHeight = max(minBottomContentHeightPx, currentBottomContentHeightPx - dragAmount.roundToInt())
|
||||||
val newHeight = min(calculatedMaxBottomContentHeightPx, calculatedHeight)
|
val newHeight = min(calculatedMaxBottomContentHeightPx, calculatedHeight)
|
||||||
|
|
@ -120,7 +127,11 @@ fun ExpandableBottomSheetLayout(
|
||||||
|
|
||||||
animatable.animateTo(destination)
|
animatable.animateTo(destination)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
canScroll = {
|
||||||
|
// We only consider we can scroll in the contents if the min size matches the max size so it's maximized
|
||||||
|
minBottomContentHeightPx == calculatedMaxBottomContentHeightPx
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -189,6 +200,45 @@ fun ExpandableBottomSheetLayout(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The original detectVerticalDragGestures doesn't allow us to conditionally consume the initial slop event that triggers the drag,
|
||||||
|
// which is necessary in our case to allow inner scrollables to work when the sheet is not fully expanded, so we need to re-implement it here
|
||||||
|
private suspend fun PointerInputScope.customDetectVerticalDragGestures(
|
||||||
|
onDragStart: (Offset) -> Unit = {},
|
||||||
|
onDragEnd: () -> Unit = {},
|
||||||
|
onDragCancel: () -> Unit = {},
|
||||||
|
canScroll: () -> Boolean = { false },
|
||||||
|
onVerticalDrag: (change: PointerInputChange, dragAmount: Float) -> Unit,
|
||||||
|
) {
|
||||||
|
awaitEachGesture {
|
||||||
|
val down = awaitFirstDown(requireUnconsumed = false)
|
||||||
|
var overSlop = 0f
|
||||||
|
val drag =
|
||||||
|
awaitVerticalPointerSlopOrCancellation(down.id, down.type) { change, over ->
|
||||||
|
// Consuming this event is what triggers the dragging instead of the inner content scrolling
|
||||||
|
// We should only consume it if we can't scroll in the inner content so we drag the bottom sheet instead, otherwise we let it pass through
|
||||||
|
// This is the only change compared to the original detectVerticalDragGestures implementation
|
||||||
|
if (!canScroll()) {
|
||||||
|
change.consume()
|
||||||
|
}
|
||||||
|
overSlop = over
|
||||||
|
}
|
||||||
|
if (drag != null) {
|
||||||
|
onDragStart.invoke(drag.position)
|
||||||
|
onVerticalDrag.invoke(drag, overSlop)
|
||||||
|
if (
|
||||||
|
verticalDrag(drag.id) {
|
||||||
|
onVerticalDrag(it, it.positionChange().y)
|
||||||
|
it.consume()
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
onDragEnd()
|
||||||
|
} else {
|
||||||
|
onDragCancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Preview(showBackground = true)
|
@Preview(showBackground = true)
|
||||||
@Composable
|
@Composable
|
||||||
@Suppress("UnusedPrivateMember")
|
@Suppress("UnusedPrivateMember")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue