Skip to content

Commit

Permalink
Improve compose-reordering (vfsfitvnm#176)
Browse files Browse the repository at this point in the history
  • Loading branch information
vfsfitvnm committed Aug 16, 2022
1 parent 4ae3c60 commit 1682228
Show file tree
Hide file tree
Showing 8 changed files with 539 additions and 194 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.text.BasicText
Expand All @@ -35,10 +34,11 @@ import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex
import it.vfsfitvnm.reordering.ReorderingLazyColumn
import it.vfsfitvnm.reordering.animateItemPlacement
import it.vfsfitvnm.reordering.draggedItem
import it.vfsfitvnm.reordering.rememberReorderingState
import it.vfsfitvnm.reordering.verticalDragToReorder
import it.vfsfitvnm.reordering.reorder
import it.vfsfitvnm.route.RouteHandler
import it.vfsfitvnm.vimusic.Database
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
Expand Down Expand Up @@ -92,7 +92,8 @@ fun LocalPlaylistScreen(playlistId: Long) {
val thumbnailSize = Dimensions.thumbnails.song.px

val reorderingState = rememberReorderingState(
items = playlistWithSongs.songs,
lazyListState = lazyListState,
key = playlistWithSongs.songs,
onDragStart = {
hapticFeedback.performHapticFeedback(
HapticFeedbackType.LongPress
Expand Down Expand Up @@ -123,11 +124,7 @@ fun LocalPlaylistScreen(playlistId: Long) {
)
}
},
itemSizeProvider = { index ->
lazyListState.layoutInfo.visibleItemsInfo.find {
it.index == index + 3
}?.size
}
extraItemCount = 3
)

var isRenaming by rememberSaveable {
Expand Down Expand Up @@ -164,8 +161,8 @@ fun LocalPlaylistScreen(playlistId: Long) {
)
}

LazyColumn(
state = lazyListState,
ReorderingLazyColumn(
reorderingState = reorderingState,
contentPadding = WindowInsets.systemBars.asPaddingValues()
.add(bottom = Dimensions.collapsedPlayer),
modifier = Modifier
Expand Down Expand Up @@ -311,7 +308,7 @@ fun LocalPlaylistScreen(playlistId: Long) {
colorFilter = ColorFilter.tint(colorPalette.textSecondary),
modifier = Modifier
.clickable { }
.verticalDragToReorder(
.reorder(
reorderingState = reorderingState,
index = index
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
Expand All @@ -37,10 +36,11 @@ import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import com.valentinilk.shimmer.shimmer
import it.vfsfitvnm.reordering.ReorderingLazyColumn
import it.vfsfitvnm.reordering.animateItemPlacement
import it.vfsfitvnm.reordering.draggedItem
import it.vfsfitvnm.reordering.rememberReorderingState
import it.vfsfitvnm.reordering.verticalDragToReorder
import it.vfsfitvnm.reordering.reorder
import it.vfsfitvnm.vimusic.LocalPlayerServiceBinder
import it.vfsfitvnm.vimusic.R
import it.vfsfitvnm.vimusic.enums.ThumbnailRoundness
Expand Down Expand Up @@ -79,11 +79,9 @@ fun CurrentPlaylistView(
val windows by rememberWindows(binder.player)
val shouldBePlaying by rememberShouldBePlaying(binder.player)

val lazyListState =
rememberLazyListState(initialFirstVisibleItemIndex = mediaItemIndex)

val reorderingState = rememberReorderingState(
items = windows,
lazyListState = rememberLazyListState(initialFirstVisibleItemIndex = mediaItemIndex),
key = windows,
onDragStart = {
hapticFeedback.performHapticFeedback(
HapticFeedbackType.LongPress
Expand All @@ -92,24 +90,20 @@ fun CurrentPlaylistView(
onDragEnd = { fromIndex, toIndex ->
binder.player.moveMediaItem(fromIndex, toIndex)
},
itemSizeProvider = { index ->
lazyListState.layoutInfo.visibleItemsInfo.find {
it.index == index
}?.size
}
extraItemCount = 0
)

val paddingValues = WindowInsets.systemBars.asPaddingValues()
val bottomPadding = paddingValues.calculateBottomPadding()

Column {
LazyColumn(
state = lazyListState,
ReorderingLazyColumn(
reorderingState = reorderingState,
contentPadding = paddingValues.add(bottom = -bottomPadding),
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier
.nestedScroll(remember {
layoutState.nestedScrollConnection(lazyListState.firstVisibleItemIndex == 0 && lazyListState.firstVisibleItemScrollOffset == 0)
layoutState.nestedScrollConnection(reorderingState.lazyListState.firstVisibleItemIndex == 0 && reorderingState.lazyListState.firstVisibleItemScrollOffset == 0)
})
.background(colorPalette.background1)
.weight(1f)
Expand Down Expand Up @@ -182,7 +176,7 @@ fun CurrentPlaylistView(
colorFilter = ColorFilter.tint(colorPalette.textSecondary),
modifier = Modifier
.clickable { }
.verticalDragToReorder(
.reorder(
reorderingState = reorderingState,
index = window.firstPeriodIndex
)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fun Modifier.draggedItem(
val translation by reorderingState.translationFor(index)

offset {
when (reorderingState.orientation) {
when (reorderingState.lazyListState.layoutInfo.orientation) {
Orientation.Vertical -> IntOffset(0, translation)
Orientation.Horizontal -> IntOffset(translation, 0)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package it.vfsfitvnm.reordering

import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.gestures.detectDragGesturesAfterLongPress
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.pointer.PointerInputChange
import androidx.compose.ui.input.pointer.PointerInputScope
import androidx.compose.ui.input.pointer.pointerInput

private fun Modifier.reorder(
reorderingState: ReorderingState,
index: Int,
detectDragGestures: DetectDragGestures,
): Modifier = pointerInput(reorderingState) {
with(detectDragGestures) {
detectDragGestures(
onDragStart = { reorderingState.onDragStart(index) },
onDrag = reorderingState::onDrag,
onDragEnd = reorderingState::onDragEnd,
onDragCancel = reorderingState::onDragEnd,
)
}
}

fun Modifier.reorder(
reorderingState: ReorderingState,
index: Int,
): Modifier = reorder(
reorderingState = reorderingState,
index = index,
detectDragGestures = PointerInputScope::detectDragGestures,
)

fun Modifier.reorderAfterLongPress(
reorderingState: ReorderingState,
index: Int
): Modifier = reorder(
reorderingState = reorderingState,
index = index,
detectDragGestures = PointerInputScope::detectDragGesturesAfterLongPress,
)

private fun interface DetectDragGestures {
suspend fun PointerInputScope.detectDragGestures(
onDragStart: (Offset) -> Unit,
onDragEnd: () -> Unit,
onDragCancel: () -> Unit,
onDrag: (change: PointerInputChange, dragAmount: Offset) -> Unit
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")

package it.vfsfitvnm.reordering

import androidx.compose.foundation.gestures.FlingBehavior
import androidx.compose.foundation.gestures.ScrollableDefaults
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

@Composable
fun ReorderingLazyColumn(
reorderingState: ReorderingState,
modifier: Modifier = Modifier,
contentPadding: PaddingValues = PaddingValues(0.dp),
reverseLayout: Boolean = false,
verticalArrangement: Arrangement.Vertical =
if (!reverseLayout) Arrangement.Top else Arrangement.Bottom,
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
userScrollEnabled: Boolean = true,
content: LazyListScope.() -> Unit
) {
ReorderingLazyList(
modifier = modifier,
state = reorderingState.lazyListState,
reorderingState = reorderingState,
contentPadding = contentPadding,
flingBehavior = flingBehavior,
horizontalAlignment = horizontalAlignment,
verticalArrangement = verticalArrangement,
isVertical = true,
reverseLayout = reverseLayout,
userScrollEnabled = userScrollEnabled,
content = content
)
}
Loading

0 comments on commit 1682228

Please sign in to comment.