安卓开发 jetpack compose 帮我封装一个实现拖动LazyColumn的item可改变item位置组件 kotlin代码
时间: 2023-06-14 18:04:51 浏览: 71
好的,以下是实现拖动LazyColumn的item可改变位置的组件的Kotlin代码,你可以参考使用:
```kotlin
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch
@Composable
fun DraggableLazyColumn(
items: List<Any>,
modifier: Modifier = Modifier,
dragEnabled: Boolean = true,
itemContent: @Composable (Any) -> Unit
) {
val listState = rememberLazyListState()
val draggingItemIndex = remember { mutableStateOf(-1) }
Box(
modifier = modifier.fillMaxSize(),
contentAlignment = Alignment.TopStart
) {
LazyColumn(
state = listState,
contentDirection = LayoutDirection.Ltr
) {
itemsIndexed(items) { index, item ->
DraggableItem(
itemIndex = index,
modifier = modifier,
dragEnabled = dragEnabled,
draggingItemIndex = draggingItemIndex,
onDragStart = { draggingItemIndex.value = index },
onDragEnd = { draggingItemIndex.value = -1 },
onNewPosition = { newPosition ->
if (newPosition != index) {
val newList = items.toMutableList()
val item = newList.removeAt(index)
newList.add(newPosition, item)
items.clear()
items.addAll(newList)
}
}
) {
itemContent(item)
}
}
}
}
}
@Composable
private fun DraggableItem(
itemIndex: Int,
modifier: Modifier,
dragEnabled: Boolean,
draggingItemIndex: androidx.compose.runtime.MutableState<Int>,
onDragStart: () -> Unit,
onDragEnd: () -> Unit,
onNewPosition: (Int) -> Unit,
content: @Composable () -> Unit
) {
val offsetY = remember { mutableStateOf(0f) }
val coroutineScope = rememberCoroutineScope()
Box(
modifier = modifier.pointerInput(Unit) {
if (dragEnabled) {
forEachGesture {
awaitPointerEventScope {
val originalIndex = itemIndex
if (it.down) {
onDragStart()
}
if (it.offsetChange().y != 0f && draggingItemIndex.value == originalIndex) {
offsetY.value += it.offsetChange().y
val currentPosition = offsetY.value / ITEM_HEIGHT_DP
coroutineScope.launch {
onNewPosition(currentPosition.toInt().coerceIn(0, Int.MAX_VALUE))
}
}
if (it.up) {
onDragEnd()
offsetY.value = 0f
}
}
}
}
}
) {
content()
}
}
private const val ITEM_HEIGHT_DP = 50.dp
```
在使用该组件时,需要将你的实际数据列表传入其中的`items`参数,并在`itemConent`中根据传入的数据绘制每一个item。同时,你可以自定义一些样式和形状等来符合你的实际需求。