withoutVisualEffect

Function

Common
fun OverscrollEffect.withoutVisualEffect(): OverscrollEffect

Returns a wrapped version of this OverscrollEffect with an empty OverscrollEffect.node. This prevents the overscroll effect from applying any visual effect, but it will still handle events.

This can be used along with withoutEventHandling in cases where you wish to change where overscroll is rendered for a given component. Pass this wrapped instance that doesn't render to the component that handles events (such as androidx.compose.foundation.lazy.LazyColumn) to prevent it from drawing the overscroll effect. Then to separately render the original overscroll effect, you can directly pass it to Modifier.overscroll (since that modifier only renders, and does not handle events). If instead you want to draw the overscroll in another component that handles events, such as a different lazy list, you need to first wrap the original overscroll effect with withoutEventHandling to prevent it from also dispatching events.

Code Examples

OverscrollRenderedOnTopOfLazyListDecorations

@Composable
fun OverscrollRenderedOnTopOfLazyListDecorations() {
    val items = remember { (1..100).toList() }
    val state = rememberLazyListState()
    val overscroll = rememberOverscrollEffect()
    // Create a wrapped version of the above overscroll effect that does not apply a visual effect.
    // This will be used inside LazyColumn to provide events to overscroll, without letting
    // LazyColumn render the overscroll effect internally.
    val overscrollWithoutVisualEffect = overscroll?.withoutVisualEffect()
    LazyColumn(
        content = { items(items) { Text("Item $it") } },
        state = state,
        modifier =
            Modifier.size(300.dp)
                .clip(RectangleShape)
                // Manually render the overscroll on top of the lazy list _and_ the 'decorations' we
                // are
                // manually drawing, to make sure they will also be included in the overscroll
                // effect.
                .overscroll(overscroll)
                .drawBehind {
                    state.layoutInfo.visibleItemsInfo.drop(1).forEach { info ->
                        val verticalOffset = info.offset.toFloat()
                        drawLine(
                            color = Color.Red,
                            start = Offset(0f, verticalOffset),
                            end = Offset(size.width, verticalOffset),
                        )
                    }
                },
        // Pass the overscroll effect that does not apply a visual effect inside the LazyList to
        // receive overscroll events
        overscrollEffect = overscrollWithoutVisualEffect,
    )
}