An easy Drop And Drag Api provider for Jetpack Compose
Dropper
An easy Drop And Drag Api provider for Jetpack Compose.
Usage
Implementation
Add it in your root build.gradle at the end of repositories:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
Add the dependency
dependencies {
implementation 'com.github.fogsong233:Dropper:v1.0.0'
}
first, create a new Dropper
instance, and you can create DroppableRef
and DraggableRef
// <String> is which type of addition info the draggable provides to droppable with
val dropper by remember { mutableStateOf(Dropper<String>()) }
Now you can create refs. Info is the addition type, Dropper
can automatically check the position of draggable and invoke the callback.
val dropRef = dropper.createDroppableRef(DroppableEventCallBack(
onEnter = { name, info ->
Log.d(tag, "enter: $name, info: $info")
},
onDrop = { name, info ->
Log.d(tag, "drop: $name, info: $info")
},
onLeave = { name ->
Log.d(tag, "leave: $name")
}
))
then create draggable:
val dragRef = dropper.createDraggableRef("name", "info: T", DraggableEventCallBack(
// where you can listen drop, drag, dragStart, dragCancelled events.
onDrop = {}
...
))
Now bind them to component:
Box(modifier = Modifier.draggable(dragRef, afterLongPress = true/false))
Box( modifier = Modifier.droppable(dropRef))
Custom Offset Behavior
The offset of draggable can be processed by Dragger
, but if you intend to add animation to offset, for example, when the draggable
isn’t drop in a droppable, and onCancelled
is invoked, you can write like that:
val offset = remember {
Animatable(Offset.Zero, Offset.VectorConverter)
}
val scope = rememberCoroutineScope()
val dragRef = dropper.createDraggableRef("name", "info", DraggableEventCallBack(
onDrag = {
scope.launch { offset.snapTo(offset.value + it) }
},
onDragStart = {
scope.launch { offset.snapTo(offset.value + it) }
},
onDropped = {
scope.launch { offset.snapTo(Offset.Zero) }
},
onCancelled = {
scope.launch { offset.animateTo(Offset.Zero) }
}
))
Box(modifier = Modifier.offset {
offset.value.let {
IntOffset(x = it.x.roundToInt(), y = it.y.roundToInt())
}
}.draggable(dragRef, isSetOffset = false))
You can also do other transform like scale.
__But Dropper
doesn’t surpport rotation, as the size and location of Draggable
may get wrong.
Multiple Draggable and Droppable
Dropper
surpports lots of Draggables
and Droppables
. However, each of thems belong to one Dropper
must have a common addition info type. It is the T in Dropper<T>()
.
Dropper
can automatically process every event to Draggable
and Droppable
.