Skip to content

Grids with different spans lose drag focus #93

@HoracekPetr

Description

@HoracekPetr

Hi,

I tried using the library for a horizontal grid that uses differently spanned items, and I found an issue. In my example, there is a column containing two items in two rows, and then a large item spanning both rows that's next to it. When I drag the bottom item from this column over the big item and collision is detected, the dragged item jumps instantly behind the big item. Here's a video of the bug:

grid_reorder_spanned.mp4

Tried to play with it but haven't found a solution yet. Thanks for looking into it. Here's the code of the example:

import androidx.compose.animation.core.animateDpAsState
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import sh.calvin.reorderable.ReorderableItem
import sh.calvin.reorderable.rememberReorderableLazyGridState
import java.util.UUID

@Composable
fun CalvinReorderableGrid(modifier: Modifier = Modifier) {

    var list by remember {
        mutableStateOf(
            listOf(
                GridItem(text = "Item 1", spansWholeGrid = false),
                GridItem(text = "Item 2", spansWholeGrid = false),
                GridItem(text = "Item 3", spansWholeGrid = true),
                GridItem(text = "Item 4", spansWholeGrid = false),
                GridItem(text = "Item 5", spansWholeGrid = false),
                GridItem(text = "Item 6", spansWholeGrid = true),
            )
        )
    }
    val lazyGridState = rememberLazyGridState()
    val reorderableLazyListState = rememberReorderableLazyGridState(lazyGridState) { from, to ->
        list = list.toMutableList().apply {
            add(to.index, removeAt(from.index))
        }

    }

    LazyHorizontalGrid(
        modifier = modifier.fillMaxHeight(0.25f).fillMaxWidth(),
        rows = GridCells.Fixed(2),
        state = lazyGridState,
        contentPadding = PaddingValues(8.dp),
        horizontalArrangement = Arrangement.spacedBy(8.dp),
        verticalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        items(
            items = list,
            key = { it.id },
            span = { if (it.spansWholeGrid) GridItemSpan(maxLineSpan) else GridItemSpan(1) }
        ) {
            ReorderableItem(reorderableLazyListState, key = it.id) { isDragging ->
                val elevation by animateDpAsState(if (isDragging) 4.dp else 0.dp)

                Surface(
                    modifier = Modifier
                        .width(150.dp)
                        .fillMaxSize()
                        .border(1.dp, Color.Black)
                        .longPressDraggableHandle(),
                    shadowElevation = elevation
                ) {
                    Column {
                        Text(it.text, Modifier.padding(vertical = 8.dp))
                    }
                }
            }
        }
    }
}

data class GridItem(
    val id: String = UUID.randomUUID().toString(),
    val text: String,
    val spansWholeGrid: Boolean = false
)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions