0

I have a scrollable Column. At the bottom of the Column I want to disable scrolling and enable dragging in order to reveal an Image "behind" the Column.

This is what I've tried:

@Composable
fun DraggableScrollable() {
    var offset by remember { mutableStateOf(0.dp) }
    var dragging by remember { mutableStateOf(false) }
    val interactionSource = remember { MutableInteractionSource() }

    Box {
        Column (
            modifier = Modifier
                .verticalScroll(
                    enabled = !dragging,
                    state = scrollState
                )
                .offset(y = offset.value)
                .pointerInput(Unit) {
                    if (dragging) {
                        val interaction = DragInteraction.Start()
                        detectDragGestures (
                            onDragStart = { interactionSource.tryEmit(interaction) },
                            onDrag = { _, _ ->
                                // drag while offset != 0
                                // when offset is back to 0 enable scrolling again
                            },
                            onDragCancel = {
                                interactionSource.tryEmit(DragInteraction.Cancel(interaction))
                            },
                            onDragEnd = {
                                interactionSource.tryEmit(DragInteraction.Stop(interaction))
                            }
                        )
                    }
                }
        ) {
            repeat(100) {
                Text(
                    text = "Item $it",
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(24.dp)
                )
            }
            Button(onClick = { dragging = true }) { Text(text = "Reveal secret") }
        }
        Image(
            painter = painterResource(id = R.drawable.foo),
            contentDescription = "Secret image",
            modifier = Modifier.fillMaxWidth().align(Alignment.BottomCenter)
        )
    }
}

However, that seems to only disable scrolling. Drag gestures do not register at all

Elkbender
  • 23
  • 3

1 Answers1

0

Replace Modifier.pointerInput(Unit) with Modifier.pointerInput(dragging) and it will work.

The reason is you need to restart pointerInput because you already create closure block. After that gesture loops, detecX functions, run and next time you need to run loop or change MutableState that is read inside that loop you need to restart Modifier.pointerInput. That's why it has overloads with keys.

You can also check this answer to use them interchangeably and why it didn't work as in your case

https://stackoverflow.com/a/72775597/5457853

You can see my answer below where i was holding to previous instance of MutableState, this is not your case but holding previous instance of MutableState also causes unexpected behavour.

Value of mutableState captured by remember with keys doesn't get updated if remember keys change

Thracian
  • 43,021
  • 16
  • 133
  • 222