Skip to content

Instantly share code, notes, and snippets.

@Ahmed-Sellami
Last active Sep 30, 2021
Embed
What would you like to do?
fun Modifier.dragToReorder(
shoesArticle: ShoesArticle,
shoesArticles: MutableList<ShoesArticle>,
itemHeight: Int,
updateSlideState: (shoesArticle: ShoesArticle, slideState: SlideState) -> Unit,
onDrag: () -> Unit,
onStopDrag: (currentIndex: Int, destinationIndex: Int) -> Unit,
): Modifier = composed {
/* ... */
pointerInput(Unit) {
// Wrap in a coroutine scope to use suspend functions for touch events and animation.
coroutineScope {
while (true) {
/* ... */
val shoesArticleIndex = shoesArticles.indexOf(shoesArticle)
val offsetToSlide = itemHeight / 4
var numberOfItems = 0
var previousNumberOfItems: Int
var listOffset = 0
// Wait for drag events.
awaitPointerEventScope {
drag(pointerId) { change ->
onDrag()
/* ... */
launch {
offsetY.snapTo(verticalDragOffset)
val offsetSign = offsetY.value.sign.toInt()
previousNumberOfItems = numberOfItems
numberOfItems = calculateNumberOfSlidItems(
offsetY.value * offsetSign,
itemHeight,
offsetToSlide,
previousNumberOfItems
)
if (previousNumberOfItems > numberOfItems) {
updateSlideState(
shoesArticles[shoesArticleIndex + previousNumberOfItems * offsetSign],
SlideState.NONE
)
} else if (numberOfItems != 0) {
try {
updateSlideState(
shoesArticles[shoesArticleIndex + numberOfItems * offsetSign],
if (offsetSign == 1) SlideState.UP else SlideState.DOWN
)
} catch (e: IndexOutOfBoundsException) {
numberOfItems = previousNumberOfItems
Log.i("DragToReorder", "Item is outside or at the edge")
}
}
listOffset = numberOfItems * offsetSign
}
/* ... */
}
}
/* ... */
launch {
offsetY.animateTo(itemHeight * numberOfItems * offsetY.value.sign)
onStopDrag(currentIndex, currentIndex + listOffset)
}
}
}
} /* ... */
}
private fun calculateNumberOfSlidItems(
offsetY: Float,
itemHeight: Int,
offsetToSlide: Int,
previousNumberOfItems: Int
): Int {
val numberOfItemsInOffset = (offsetY / itemHeight).toInt()
val numberOfItemsPlusOffset = ((offsetY + offsetToSlide) / itemHeight).toInt()
val numberOfItemsMinusOffset = ((offsetY - offsetToSlide - 1) / itemHeight).toInt()
return when {
offsetY - offsetToSlide - 1 < 0 -> 0
numberOfItemsPlusOffset > numberOfItemsInOffset -> numberOfItemsPlusOffset
numberOfItemsMinusOffset < numberOfItemsInOffset -> numberOfItemsInOffset
else -> previousNumberOfItems
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment