loloof64
11/27/2020, 4:34 PM@Preview
@Composable
fun DragNDropComponent() {
Column(modifier = Modifier.size(300.dp).background(Color.Red)) {
var x by remember { mutableStateOf(0f) }
var y by remember { mutableStateOf(0f) }
var animationActive by remember { mutableStateOf(false) }
val animatedX = FloatPropKey()
val animatedY = FloatPropKey()
val positionAnimation = transitionDefinition<DndResetState> {
state(DndResetState.Start) {
this[animatedX] = x
this[animatedY] = y
}
state(DndResetState.End) {
this[animatedX] = 0f
this[animatedY] = 0f
}
transition {
animatedX using tween(durationMillis = 700, easing = FastOutSlowInEasing)
animatedY using tween(durationMillis = 700, easing = FastOutSlowInEasing)
}
}
val positionAnimationState = transition(
definition = positionAnimation,
initState = DndResetState.Start,
toState = DndResetState.End,
onStateChangeFinished = {
animationActive = false
x = 0f
y = 0f
}
)
val offsetX = with(DensityAmbient.current) {
(
if (animationActive) positionAnimationState[animatedX]
else x
).toDp()
}
val offsetY = with(DensityAmbient.current) {
(
if (animationActive) positionAnimationState[animatedY]
else y
).toDp()
}
Column(
modifier = Modifier
.offset(offsetX, offsetY)
.size(10.dp)
.background(Color.Blue)
.dragGestureFilter(
dragObserver = object : DragObserver {
override fun onDrag(dragDistance: Offset): Offset {
x += dragDistance.x
y += dragDistance.y
return dragDistance
}
override fun onCancel() {
// animationActive = true
}
override fun onStart(downPosition: Offset) {
x = 0f
y = 0f
}
override fun onStop(velocity: Offset) {
// animationActive = true
}
}, startDragImmediately = true // better for experience on mobile/tablet
)
) {}
}
}
Joost Klitsie
11/27/2020, 5:16 PMloloof64
11/27/2020, 5:19 PMJoost Klitsie
11/27/2020, 5:23 PMloloof64
11/27/2020, 5:25 PMJoost Klitsie
11/27/2020, 5:30 PM@Preview
@Composable
fun DragAndDropComponent() {
Column(modifier = Modifier.size(300.dp).background(Color.Red)) {
val x = animatedFloat(0f)
val y = animatedFloat(0f)
Box(modifier = Modifier
.offset(
with(DensityAmbient.current) { x.value.toDp() },
with(DensityAmbient.current) { y.value.toDp() })
.size(10.dp)
.background(Color.Blue)
.dragGestureFilter(
object : DragObserver {
override fun onDrag(dragDistance: Offset): Offset {
x.animateTo(x.targetValue + dragDistance.x)
y.animateTo(y.targetValue + dragDistance.y)
return super.onDrag(dragDistance)
}
override fun onStop(velocity: Offset) {
super.onStop(velocity)
x.animateTo(0f)
y.animateTo(0f)
}
override fun onCancel() {
super.onCancel()
x.animateTo(0f)
y.animateTo(0f)
}
},
startDragImmediately = true
)
)
}
}
@Preview
@Composable
fun DragAndDropComponent() {
Column(modifier = Modifier.size(300.dp).background(Color.Red)) {
val x = animatedFloat(150f)
val y = animatedFloat(150f)
val bouncySpring = SpringSpec(
dampingRatio = DampingRatioMediumBouncy,
stiffness = StiffnessLow,
visibilityThreshold = DefaultDisplacementThreshold)
val stiffSpring = SpringSpec(
dampingRatio = DampingRatioLowBouncy,
stiffness = StiffnessHigh,
visibilityThreshold = DefaultDisplacementThreshold)
Box(modifier = Modifier
.offset(
with(DensityAmbient.current) { x.value.toDp() },
with(DensityAmbient.current) { y.value.toDp() })
.size(10.dp)
.background(Color.Blue)
.dragGestureFilter(
object : DragObserver {
override fun onDrag(dragDistance: Offset): Offset {
x.animateTo(
targetValue = x.targetValue + dragDistance.x,
anim = stiffSpring
)
y.animateTo(
targetValue = y.targetValue + dragDistance.y,
anim = stiffSpring
)
return super.onDrag(dragDistance)
}
override fun onStop(velocity: Offset) {
super.onStop(velocity)
reset()
}
override fun onCancel() {
super.onCancel()
reset()
}
private fun reset() {
x.animateTo(
targetValue = 150f,
anim = bouncySpring)
y.animateTo(
targetValue = 150f,
anim = bouncySpring)
}
},
startDragImmediately = true
)
)
}
}
loloof64
11/27/2020, 5:31 PM