Tweak BottomSheet code
This commit is contained in:
parent
fd4a1611e2
commit
87b2ff3788
1 changed files with 49 additions and 90 deletions
|
@ -3,12 +3,9 @@ package it.vfsfitvnm.vimusic.ui.components
|
|||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.animation.core.Animatable
|
||||
import androidx.compose.animation.core.VectorConverter
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.gestures.DraggableState
|
||||
import androidx.compose.foundation.gestures.Orientation
|
||||
import androidx.compose.foundation.gestures.detectTapGestures
|
||||
import androidx.compose.foundation.gestures.draggable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.gestures.detectVerticalDragGestures
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
|
@ -23,41 +20,18 @@ import androidx.compose.ui.graphics.Shape
|
|||
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
|
||||
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.input.pointer.util.VelocityTracker
|
||||
import androidx.compose.ui.input.pointer.util.addPointerInputChange
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.*
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.Velocity
|
||||
import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.math.absoluteValue
|
||||
import kotlin.ranges.coerceAtMost
|
||||
|
||||
|
||||
@Composable
|
||||
@NonRestartableComposable
|
||||
fun BottomSheet(
|
||||
lowerBound: Dp,
|
||||
upperBound: Dp,
|
||||
modifier: Modifier = Modifier,
|
||||
peekHeight: Dp = 0.dp,
|
||||
elevation: Dp = 8.dp,
|
||||
shape: Shape = RectangleShape,
|
||||
handleOutsideInteractionsWhenExpanded: Boolean = false,
|
||||
interactionSource: MutableInteractionSource? = null,
|
||||
collapsedContent: @Composable BoxScope.() -> Unit,
|
||||
content: @Composable BoxScope.() -> Unit
|
||||
) {
|
||||
BottomSheet(
|
||||
state = rememberBottomSheetState(lowerBound, upperBound),
|
||||
modifier = modifier,
|
||||
peekHeight = peekHeight,
|
||||
elevation = elevation,
|
||||
shape = shape,
|
||||
handleOutsideInteractionsWhenExpanded = handleOutsideInteractionsWhenExpanded,
|
||||
interactionSource = interactionSource,
|
||||
collapsedContent = collapsedContent,
|
||||
content = content
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun BottomSheet(
|
||||
state: BottomSheetState,
|
||||
|
@ -66,45 +40,19 @@ fun BottomSheet(
|
|||
elevation: Dp = 8.dp,
|
||||
shape: Shape = RectangleShape,
|
||||
handleOutsideInteractionsWhenExpanded: Boolean = false,
|
||||
interactionSource: MutableInteractionSource? = null,
|
||||
collapsedContent: @Composable BoxScope.() -> Unit,
|
||||
content: @Composable BoxScope.() -> Unit
|
||||
) {
|
||||
var lastOffset by remember {
|
||||
mutableStateOf(state.value)
|
||||
}
|
||||
|
||||
Box {
|
||||
if (handleOutsideInteractionsWhenExpanded && !state.isCollapsed) {
|
||||
Spacer(
|
||||
modifier = Modifier
|
||||
.pointerInput(Unit) {
|
||||
.pointerInput(state) {
|
||||
detectTapGestures {
|
||||
state.collapse()
|
||||
}
|
||||
}
|
||||
.draggable(
|
||||
state = state,
|
||||
onDragStarted = {
|
||||
lastOffset = state.value
|
||||
},
|
||||
onDragStopped = { velocity ->
|
||||
if (velocity.absoluteValue > 300 && lastOffset != state.value) {
|
||||
if (lastOffset > state.value) {
|
||||
state.collapse()
|
||||
} else {
|
||||
state.expand()
|
||||
}
|
||||
} else {
|
||||
if (state.upperBound - state.value > state.value - state.lowerBound) {
|
||||
state.collapse()
|
||||
} else {
|
||||
state.expand()
|
||||
}
|
||||
}
|
||||
},
|
||||
orientation = Orientation.Vertical
|
||||
)
|
||||
.draggableBottomSheet(state)
|
||||
.drawBehind {
|
||||
drawRect(color = Color.Black.copy(alpha = 0.5f * state.progress))
|
||||
}
|
||||
|
@ -122,36 +70,14 @@ fun BottomSheet(
|
|||
}
|
||||
.shadow(elevation = elevation, shape = shape)
|
||||
.clip(shape)
|
||||
.draggable(
|
||||
state = state,
|
||||
interactionSource = interactionSource,
|
||||
onDragStarted = {
|
||||
lastOffset = state.value
|
||||
},
|
||||
onDragStopped = { velocity ->
|
||||
if (velocity.absoluteValue > 300 && lastOffset != state.value) {
|
||||
if (lastOffset > state.value) {
|
||||
state.collapse()
|
||||
} else {
|
||||
state.expand()
|
||||
}
|
||||
} else {
|
||||
if (state.upperBound - state.value > state.value - state.lowerBound) {
|
||||
state.collapse()
|
||||
} else {
|
||||
state.expand()
|
||||
}
|
||||
.draggableBottomSheet(state)
|
||||
.pointerInput(state) {
|
||||
if (!state.isRunning && state.isCollapsed) {
|
||||
detectTapGestures {
|
||||
state.expand()
|
||||
}
|
||||
},
|
||||
orientation = Orientation.Vertical
|
||||
)
|
||||
.clickable(
|
||||
enabled = !state.isRunning && state.isCollapsed,
|
||||
indication = null,
|
||||
interactionSource = interactionSource
|
||||
?: remember { MutableInteractionSource() },
|
||||
onClick = state.expand
|
||||
)
|
||||
}
|
||||
}
|
||||
.fillMaxSize()
|
||||
) {
|
||||
if (!state.isCollapsed) {
|
||||
|
@ -299,3 +225,36 @@ fun rememberBottomSheetState(lowerBound: Dp, upperBound: Dp): BottomSheetState {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Modifier.draggableBottomSheet(state: BottomSheetState) = pointerInput(state) {
|
||||
var initialValue = 0.dp
|
||||
val velocityTracker = VelocityTracker()
|
||||
|
||||
detectVerticalDragGestures(
|
||||
onDragStart = {
|
||||
initialValue = state.value
|
||||
},
|
||||
onVerticalDrag = { change, dragAmount ->
|
||||
velocityTracker.addPointerInputChange(change)
|
||||
state.dispatchRawDelta(dragAmount)
|
||||
},
|
||||
onDragEnd = {
|
||||
val velocity = velocityTracker.calculateVelocity().y.absoluteValue
|
||||
velocityTracker.resetTracking()
|
||||
|
||||
if (velocity.absoluteValue > 300 && initialValue != state.value) {
|
||||
if (initialValue > state.value) {
|
||||
state.collapse()
|
||||
} else {
|
||||
state.expand()
|
||||
}
|
||||
} else {
|
||||
if (state.upperBound - state.value > state.value - state.lowerBound) {
|
||||
state.collapse()
|
||||
} else {
|
||||
state.expand()
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
Loading…
Add table
Reference in a new issue