mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-17 07:23:21 +01:00
Rename DragAndDrop -> DragToReorder to differentiate it from Android's drag-and-drop framework.
This commit is contained in:
@@ -52,10 +52,10 @@ import org.signal.core.ui.compose.DropdownMenus
|
||||
import org.signal.core.ui.compose.Previews
|
||||
import org.signal.core.ui.compose.Scaffolds
|
||||
import org.signal.core.ui.compose.SignalIcons
|
||||
import org.signal.core.ui.compose.copied.androidx.compose.DragAndDropEvent
|
||||
import org.signal.core.ui.compose.copied.androidx.compose.DraggableItem
|
||||
import org.signal.core.ui.compose.copied.androidx.compose.dragContainer
|
||||
import org.signal.core.ui.compose.copied.androidx.compose.rememberDragDropState
|
||||
import org.signal.core.ui.compose.list.ReorderListEvent
|
||||
import org.signal.core.ui.compose.list.ReorderableItem
|
||||
import org.signal.core.ui.compose.list.rememberReorderableListState
|
||||
import org.signal.core.ui.compose.list.reorderableList
|
||||
import org.signal.core.util.toInt
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
@@ -101,11 +101,11 @@ class ChatFoldersFragment : ComposeFragment() {
|
||||
onDeleteDismissed = {
|
||||
viewModel.showDeleteDialog(false)
|
||||
},
|
||||
onDragAndDropEvent = { event ->
|
||||
onReorderListEvent = { event ->
|
||||
when (event) {
|
||||
is DragAndDropEvent.OnItemMove -> viewModel.updateItemPosition(event.fromIndex, event.toIndex)
|
||||
is DragAndDropEvent.OnItemDrop -> viewModel.saveItemPositions()
|
||||
is DragAndDropEvent.OnDragCancel -> {}
|
||||
is ReorderListEvent.ItemMoved -> viewModel.updateItemPosition(event.fromIndex, event.toIndex)
|
||||
is ReorderListEvent.ItemDropped -> viewModel.saveItemPositions()
|
||||
is ReorderListEvent.DragCanceled -> {}
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -123,10 +123,10 @@ fun FoldersScreen(
|
||||
onDeleteClicked: (ChatFolderRecord) -> Unit = {},
|
||||
onDeleteConfirmed: () -> Unit = {},
|
||||
onDeleteDismissed: () -> Unit = {},
|
||||
onDragAndDropEvent: (DragAndDropEvent) -> Unit = {}
|
||||
onReorderListEvent: (ReorderListEvent) -> Unit = {}
|
||||
) {
|
||||
val listState = rememberLazyListState()
|
||||
val dragDropState = rememberDragDropState(listState, includeHeader = true, includeFooter = true, onEvent = onDragAndDropEvent)
|
||||
val reorderableListState = rememberReorderableListState(listState, includeHeader = true, includeFooter = true, onEvent = onReorderListEvent)
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
if (!SignalStore.uiHints.hasSeenChatFoldersEducationSheet) {
|
||||
@@ -147,14 +147,14 @@ fun FoldersScreen(
|
||||
}
|
||||
|
||||
LazyColumn(
|
||||
modifier = Modifier.dragContainer(
|
||||
dragDropState = dragDropState,
|
||||
modifier = Modifier.reorderableList(
|
||||
reorderableListState = reorderableListState,
|
||||
dragHandleWidth = 56.dp
|
||||
),
|
||||
state = listState
|
||||
) {
|
||||
item {
|
||||
DraggableItem(dragDropState, 0) {
|
||||
ReorderableItem(reorderableListState, 0) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.ChatFoldersFragment__organize_your_chats),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
@@ -175,7 +175,7 @@ fun FoldersScreen(
|
||||
}
|
||||
|
||||
itemsIndexed(state.folders) { index, folder ->
|
||||
DraggableItem(dragDropState, 1 + index) { isDragging ->
|
||||
ReorderableItem(reorderableListState, 1 + index) { isDragging ->
|
||||
val elevation = if (isDragging) 1.dp else 0.dp
|
||||
val isAllChats = folder.folderType == ChatFolderRecord.FolderType.ALL
|
||||
FolderRow(
|
||||
@@ -193,7 +193,7 @@ fun FoldersScreen(
|
||||
}
|
||||
|
||||
item {
|
||||
DraggableItem(dragDropState, 1 + state.folders.size) {
|
||||
ReorderableItem(reorderableListState, 1 + state.folders.size) {
|
||||
if (state.suggestedFolders.isNotEmpty()) {
|
||||
Dividers.Default()
|
||||
|
||||
|
||||
@@ -59,10 +59,10 @@ import org.signal.core.ui.compose.Previews
|
||||
import org.signal.core.ui.compose.Rows
|
||||
import org.signal.core.ui.compose.Scaffolds
|
||||
import org.signal.core.ui.compose.SignalIcons
|
||||
import org.signal.core.ui.compose.copied.androidx.compose.DragAndDropEvent
|
||||
import org.signal.core.ui.compose.copied.androidx.compose.DraggableItem
|
||||
import org.signal.core.ui.compose.copied.androidx.compose.dragContainer
|
||||
import org.signal.core.ui.compose.copied.androidx.compose.rememberDragDropState
|
||||
import org.signal.core.ui.compose.list.ReorderListEvent
|
||||
import org.signal.core.ui.compose.list.ReorderableItem
|
||||
import org.signal.core.ui.compose.list.rememberReorderableListState
|
||||
import org.signal.core.ui.compose.list.reorderableList
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.polls.Poll
|
||||
@@ -154,15 +154,15 @@ private fun CreatePollScreen(
|
||||
|
||||
// Drag and drop
|
||||
val listState = rememberLazyListState()
|
||||
val dragDropState = rememberDragDropState(listState, includeHeader = true, includeFooter = true, onEvent = { event ->
|
||||
val reorderableListState = rememberReorderableListState(listState, includeHeader = true, includeFooter = true, onEvent = { event ->
|
||||
when (event) {
|
||||
is DragAndDropEvent.OnItemMove -> {
|
||||
is ReorderListEvent.ItemMoved -> {
|
||||
val oldIndex = options[event.fromIndex]
|
||||
options[event.fromIndex] = options[event.toIndex]
|
||||
options[event.toIndex] = oldIndex
|
||||
}
|
||||
|
||||
is DragAndDropEvent.OnItemDrop, is DragAndDropEvent.OnDragCancel -> Unit
|
||||
is ReorderListEvent.ItemDropped, is ReorderListEvent.DragCanceled -> Unit
|
||||
}
|
||||
})
|
||||
|
||||
@@ -204,14 +204,14 @@ private fun CreatePollScreen(
|
||||
modifier = Modifier
|
||||
.fillMaxHeight()
|
||||
.imePadding()
|
||||
.dragContainer(
|
||||
dragDropState = dragDropState,
|
||||
.reorderableList(
|
||||
reorderableListState = reorderableListState,
|
||||
dragHandleWidth = 56.dp
|
||||
),
|
||||
state = listState
|
||||
) {
|
||||
item {
|
||||
DraggableItem(dragDropState, 0) {
|
||||
ReorderableItem(reorderableListState, 0) {
|
||||
Text(
|
||||
text = stringResource(R.string.CreatePollFragment__question),
|
||||
modifier = Modifier.padding(vertical = 12.dp, horizontal = 24.dp),
|
||||
@@ -246,7 +246,7 @@ private fun CreatePollScreen(
|
||||
}
|
||||
|
||||
itemsIndexed(options) { index, option ->
|
||||
DraggableItem(dragDropState, 1 + index) {
|
||||
ReorderableItem(reorderableListState, 1 + index) {
|
||||
TextFieldWithCountdown(
|
||||
value = option,
|
||||
label = { Text(text = stringResource(R.string.CreatePollFragment__option_n, index + 1)) },
|
||||
@@ -273,7 +273,7 @@ private fun CreatePollScreen(
|
||||
}
|
||||
|
||||
item {
|
||||
DraggableItem(dragDropState, 1 + options.size) {
|
||||
ReorderableItem(reorderableListState, 1 + options.size) {
|
||||
Dividers.Default()
|
||||
Rows.ToggleRow(checked = allowMultiple, text = stringResource(R.string.CreatePollFragment__allow_multiple_votes), onCheckChanged = { allowMultiple = it })
|
||||
Spacer(modifier = Modifier.size(60.dp))
|
||||
|
||||
@@ -16,7 +16,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import kotlinx.coroutines.launch
|
||||
import org.signal.core.ui.compose.copied.androidx.compose.DragAndDropEvent
|
||||
import org.signal.core.ui.compose.list.ReorderListEvent
|
||||
import org.signal.core.ui.compose.theme.SignalTheme
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActivity
|
||||
import org.thoughtcrime.securesms.R
|
||||
@@ -73,11 +73,11 @@ class StickerManagementActivity : PassphraseRequiredActivity() {
|
||||
override fun onRemoveStickerPacksCanceled() = viewModel.onUninstallStickerPacksCanceled()
|
||||
override fun onSelectionToggle(pack: InstalledStickerPack) = viewModel.toggleSelection(pack)
|
||||
override fun onSelectAllToggle() = viewModel.toggleSelectAll()
|
||||
override fun onDragAndDropEvent(event: DragAndDropEvent) {
|
||||
override fun onReorderableEvent(event: ReorderListEvent) {
|
||||
when (event) {
|
||||
is DragAndDropEvent.OnItemMove -> viewModel.updatePosition(event.fromIndex, event.toIndex)
|
||||
is DragAndDropEvent.OnItemDrop -> viewModel.saveInstalledPacksSortOrder()
|
||||
is DragAndDropEvent.OnDragCancel -> {}
|
||||
is ReorderListEvent.ItemMoved -> viewModel.updatePosition(event.fromIndex, event.toIndex)
|
||||
is ReorderListEvent.ItemDropped -> viewModel.saveInstalledPacksSortOrder()
|
||||
is ReorderListEvent.DragCanceled -> {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import kotlinx.coroutines.launch
|
||||
import org.signal.core.ui.compose.BottomSheets
|
||||
import org.signal.core.ui.compose.ComposeBottomSheetDialogFragment
|
||||
import org.signal.core.ui.compose.copied.androidx.compose.DragAndDropEvent
|
||||
import org.signal.core.ui.compose.list.ReorderListEvent
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragment
|
||||
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs
|
||||
@@ -120,11 +120,11 @@ class StickerManagementBottomSheet : ComposeBottomSheetDialogFragment() {
|
||||
override fun onRemoveStickerPacksCanceled() = viewModel.onUninstallStickerPacksCanceled()
|
||||
override fun onSelectionToggle(pack: InstalledStickerPack) = viewModel.toggleSelection(pack)
|
||||
override fun onSelectAllToggle() = viewModel.toggleSelectAll()
|
||||
override fun onDragAndDropEvent(event: DragAndDropEvent) {
|
||||
override fun onReorderableEvent(event: ReorderListEvent) {
|
||||
when (event) {
|
||||
is DragAndDropEvent.OnItemMove -> viewModel.updatePosition(event.fromIndex, event.toIndex)
|
||||
is DragAndDropEvent.OnItemDrop -> viewModel.saveInstalledPacksSortOrder()
|
||||
is DragAndDropEvent.OnDragCancel -> {}
|
||||
is ReorderListEvent.ItemMoved -> viewModel.updatePosition(event.fromIndex, event.toIndex)
|
||||
is ReorderListEvent.ItemDropped -> viewModel.saveInstalledPacksSortOrder()
|
||||
is ReorderListEvent.DragCanceled -> {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,10 +69,10 @@ import org.signal.core.ui.compose.Previews
|
||||
import org.signal.core.ui.compose.Scaffolds
|
||||
import org.signal.core.ui.compose.SignalIcons
|
||||
import org.signal.core.ui.compose.Snackbars
|
||||
import org.signal.core.ui.compose.copied.androidx.compose.DragAndDropEvent
|
||||
import org.signal.core.ui.compose.copied.androidx.compose.DraggableItem
|
||||
import org.signal.core.ui.compose.copied.androidx.compose.dragContainer
|
||||
import org.signal.core.ui.compose.copied.androidx.compose.rememberDragDropState
|
||||
import org.signal.core.ui.compose.list.ReorderListEvent
|
||||
import org.signal.core.ui.compose.list.ReorderableItem
|
||||
import org.signal.core.ui.compose.list.rememberReorderableListState
|
||||
import org.signal.core.ui.compose.list.reorderableList
|
||||
import org.signal.core.ui.compose.showSnackbar
|
||||
import org.signal.core.ui.getWindowSizeClass
|
||||
import org.thoughtcrime.securesms.R
|
||||
@@ -140,7 +140,7 @@ interface InstalledStickersContentCallbacks {
|
||||
fun onRemoveStickerPacksCanceled()
|
||||
fun onSelectionToggle(pack: InstalledStickerPack)
|
||||
fun onSelectAllToggle()
|
||||
fun onDragAndDropEvent(event: DragAndDropEvent)
|
||||
fun onReorderableEvent(event: ReorderListEvent)
|
||||
fun onShowPreviewClick(pack: InstalledStickerPack)
|
||||
|
||||
object Empty : InstalledStickersContentCallbacks {
|
||||
@@ -150,7 +150,7 @@ interface InstalledStickersContentCallbacks {
|
||||
override fun onRemoveStickerPacksCanceled() = Unit
|
||||
override fun onSelectionToggle(pack: InstalledStickerPack) = Unit
|
||||
override fun onSelectAllToggle() = Unit
|
||||
override fun onDragAndDropEvent(event: DragAndDropEvent) = Unit
|
||||
override fun onReorderableEvent(event: ReorderListEvent) = Unit
|
||||
override fun onShowPreviewClick(pack: InstalledStickerPack) = Unit
|
||||
}
|
||||
}
|
||||
@@ -456,7 +456,7 @@ private fun InstalledStickersContent(
|
||||
EmptyView(text = stringResource(R.string.StickerManagement_installed_tab_empty_text))
|
||||
} else {
|
||||
val listState = rememberLazyListState()
|
||||
val dragDropState = rememberDragDropState(lazyListState = listState, includeHeader = true, includeFooter = false, onEvent = callbacks::onDragAndDropEvent)
|
||||
val reorderableListState = rememberReorderableListState(lazyListState = listState, includeHeader = true, includeFooter = false, onEvent = callbacks::onReorderableEvent)
|
||||
|
||||
val density = LocalDensity.current
|
||||
val haptics = LocalHapticFeedback.current
|
||||
@@ -473,13 +473,13 @@ private fun InstalledStickersContent(
|
||||
state = listState,
|
||||
modifier = modifier
|
||||
.fillMaxHeight()
|
||||
.dragContainer(
|
||||
dragDropState = dragDropState,
|
||||
.reorderableList(
|
||||
reorderableListState = reorderableListState,
|
||||
dragHandleWidth = 56.dp
|
||||
)
|
||||
) {
|
||||
item(key = "installed_section_header") {
|
||||
DraggableItem(dragDropState, 0) {
|
||||
ReorderableItem(reorderableListState, 0) {
|
||||
StickerPackSectionHeader(
|
||||
text = stringResource(R.string.StickerManagement_installed_stickers_header),
|
||||
modifier = Modifier.animateItem()
|
||||
@@ -493,9 +493,9 @@ private fun InstalledStickersContent(
|
||||
) { index, pack ->
|
||||
val menuController = remember { DropdownMenus.MenuController() }
|
||||
|
||||
DraggableItem(
|
||||
ReorderableItem(
|
||||
index = index + 1,
|
||||
dragDropState = dragDropState
|
||||
reorderableListState = reorderableListState
|
||||
) { isDragging ->
|
||||
InstalledStickerPackRow(
|
||||
pack = pack,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.signal.core.ui.compose.copied.androidx.compose
|
||||
package org.signal.core.ui.compose.list
|
||||
|
||||
import androidx.compose.foundation.gestures.awaitEachGesture
|
||||
import androidx.compose.foundation.gestures.awaitFirstDown
|
||||
@@ -1,4 +1,9 @@
|
||||
package org.signal.core.ui.compose.copied.androidx.compose
|
||||
/*
|
||||
* Copyright 2026 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.signal.core.ui.compose.list
|
||||
|
||||
import androidx.compose.animation.core.Animatable
|
||||
import androidx.compose.animation.core.Spring
|
||||
@@ -32,29 +37,30 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.zIndex
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.signal.core.ui.compose.copied.androidx.compose.DragAndDropEvent.OnItemMove
|
||||
import org.signal.core.ui.compose.list.ReorderListEvent.ItemMoved
|
||||
|
||||
/**
|
||||
* From AndroidX Compose demo
|
||||
* Adapted from the AndroidX Compose demo
|
||||
* https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/LazyColumnDragAndDropDemo.kt
|
||||
*
|
||||
* Allows for dragging and dropping to reorder within lazy columns
|
||||
* Supports adding non-draggable headers and footers.
|
||||
* - Allows for dragging and dropping to reorder within lazy columns.
|
||||
* - Supports adding non-draggable headers and footers.
|
||||
*/
|
||||
@Composable
|
||||
fun rememberDragDropState(
|
||||
fun rememberReorderableListState(
|
||||
lazyListState: LazyListState,
|
||||
includeHeader: Boolean,
|
||||
includeFooter: Boolean,
|
||||
onEvent: (DragAndDropEvent) -> Unit = {}
|
||||
): DragDropState {
|
||||
onEvent: (ReorderListEvent) -> Unit = {}
|
||||
): ReorderableListState {
|
||||
val scope = rememberCoroutineScope()
|
||||
val state = remember(lazyListState) {
|
||||
DragDropState(state = lazyListState, onEvent = onEvent, includeHeader = includeHeader, includeFooter = includeFooter, scope = scope)
|
||||
ReorderableListState(state = lazyListState, onEvent = onEvent, includeHeader = includeHeader, includeFooter = includeFooter, scope = scope)
|
||||
}
|
||||
val maxAutoScrollSpeed = with(LocalDensity.current) { 30.dp.toPx() }
|
||||
val baseAutoScrollSpeed = with(LocalDensity.current) { 10.dp.toPx() }
|
||||
val scrollAcceleration = 2f
|
||||
|
||||
LaunchedEffect(state) {
|
||||
while (true) {
|
||||
withFrameNanos { }
|
||||
@@ -73,13 +79,12 @@ fun rememberDragDropState(
|
||||
return state
|
||||
}
|
||||
|
||||
class DragDropState
|
||||
internal constructor(
|
||||
class ReorderableListState internal constructor(
|
||||
private val state: LazyListState,
|
||||
private val scope: CoroutineScope,
|
||||
private val includeHeader: Boolean,
|
||||
private val includeFooter: Boolean,
|
||||
private val onEvent: (DragAndDropEvent) -> Unit
|
||||
private val onEvent: (ReorderListEvent) -> Unit
|
||||
) {
|
||||
var draggingItemIndex by mutableStateOf<Int?>(null)
|
||||
private set
|
||||
@@ -119,12 +124,12 @@ internal constructor(
|
||||
|
||||
internal fun onDragEnd() {
|
||||
onDragInterrupted()
|
||||
onEvent(DragAndDropEvent.OnItemDrop)
|
||||
onEvent(ReorderListEvent.ItemDropped)
|
||||
}
|
||||
|
||||
internal fun onDragCancel() {
|
||||
onDragInterrupted()
|
||||
onEvent(DragAndDropEvent.OnDragCancel)
|
||||
onEvent(ReorderListEvent.DragCanceled)
|
||||
}
|
||||
|
||||
private fun onDragInterrupted() {
|
||||
@@ -221,9 +226,9 @@ internal constructor(
|
||||
|
||||
private fun performSwap(draggingItem: LazyListItemInfo, targetItem: LazyListItemInfo) {
|
||||
if (includeHeader) {
|
||||
onEvent.invoke(OnItemMove(fromIndex = draggingItem.index - 1, toIndex = targetItem.index - 1))
|
||||
onEvent.invoke(ItemMoved(fromIndex = draggingItem.index - 1, toIndex = targetItem.index - 1))
|
||||
} else {
|
||||
onEvent.invoke(OnItemMove(fromIndex = draggingItem.index, toIndex = targetItem.index))
|
||||
onEvent.invoke(ItemMoved(fromIndex = draggingItem.index, toIndex = targetItem.index))
|
||||
}
|
||||
draggingItemIndex = targetItem.index
|
||||
}
|
||||
@@ -232,38 +237,38 @@ internal constructor(
|
||||
get() = this.offset + this.size
|
||||
}
|
||||
|
||||
sealed interface DragAndDropEvent {
|
||||
sealed interface ReorderListEvent {
|
||||
/**
|
||||
* Triggered when an item is moving from one position to another.
|
||||
*
|
||||
* The ordering of the corresponding UI state should be updated when this event is received.
|
||||
*/
|
||||
data class OnItemMove(val fromIndex: Int, val toIndex: Int) : DragAndDropEvent
|
||||
data class ItemMoved(val fromIndex: Int, val toIndex: Int) : ReorderListEvent
|
||||
|
||||
/**
|
||||
* Triggered when a dragged item is dropped into its final position.
|
||||
*/
|
||||
data object OnItemDrop : DragAndDropEvent
|
||||
data object ItemDropped : ReorderListEvent
|
||||
|
||||
/**
|
||||
* Triggered when a drag gesture is canceled.
|
||||
*/
|
||||
data object OnDragCancel : DragAndDropEvent
|
||||
data object DragCanceled : ReorderListEvent
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables drag-to-reorder functionality within a container.
|
||||
*
|
||||
* @param dragDropState The state managing the drag operation.
|
||||
* @param reorderableListState The state managing the drag operation.
|
||||
* @param dragHandleWidth Width of the draggable area (positioned at the end of the container).
|
||||
*/
|
||||
@Composable
|
||||
fun Modifier.dragContainer(
|
||||
dragDropState: DragDropState,
|
||||
fun Modifier.reorderableList(
|
||||
reorderableListState: ReorderableListState,
|
||||
dragHandleWidth: Dp
|
||||
): Modifier {
|
||||
val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl
|
||||
return pointerInput(dragDropState, dragHandleWidth, isRtl) {
|
||||
return pointerInput(reorderableListState, dragHandleWidth, isRtl) {
|
||||
val containerWidthPx = size.width.toFloat()
|
||||
val handleWidthPx = dragHandleWidth.toPx()
|
||||
|
||||
@@ -275,31 +280,31 @@ fun Modifier.dragContainer(
|
||||
|
||||
detectDragGestures(
|
||||
dragHandleXRange = dragHandleXRange,
|
||||
onDrag = { change, offset -> dragDropState.onDrag(offset = offset, change = change) },
|
||||
onDragStart = { offset -> dragDropState.onDragStart(offset) },
|
||||
onDragEnd = { dragDropState.onDragEnd() },
|
||||
onDragCancel = { dragDropState.onDragCancel() }
|
||||
onDrag = { change, offset -> reorderableListState.onDrag(offset = offset, change = change) },
|
||||
onDragStart = { offset -> reorderableListState.onDragStart(offset) },
|
||||
onDragEnd = { reorderableListState.onDragEnd() },
|
||||
onDragCancel = { reorderableListState.onDragCancel() }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun LazyItemScope.DraggableItem(
|
||||
dragDropState: DragDropState,
|
||||
fun LazyItemScope.ReorderableItem(
|
||||
reorderableListState: ReorderableListState,
|
||||
index: Int,
|
||||
modifier: Modifier = Modifier,
|
||||
content: @Composable ColumnScope.(isDragging: Boolean) -> Unit
|
||||
) {
|
||||
val dragging = index == dragDropState.draggingItemIndex
|
||||
val dragging = index == reorderableListState.draggingItemIndex
|
||||
val draggingModifier =
|
||||
if (dragging) {
|
||||
Modifier
|
||||
.zIndex(1f)
|
||||
.graphicsLayer { translationY = dragDropState.draggingItemOffset }
|
||||
} else if (index == dragDropState.previousIndexOfDraggedItem) {
|
||||
.graphicsLayer { translationY = reorderableListState.draggingItemOffset }
|
||||
} else if (index == reorderableListState.previousIndexOfDraggedItem) {
|
||||
Modifier
|
||||
.zIndex(1f)
|
||||
.graphicsLayer { translationY = dragDropState.previousItemOffset.value }
|
||||
.graphicsLayer { translationY = reorderableListState.previousItemOffset.value }
|
||||
} else {
|
||||
Modifier.animateItem(fadeInSpec = null, fadeOutSpec = null)
|
||||
}
|
||||
Reference in New Issue
Block a user