Search code examples
androidandroid-jetpack-composescrollviewandroid-jetpackhorizontalscrollview

How to create a fade effect in Column (Jetpack Compose)


I need to implement a fade effect in my scrollable column:

val modifier = Modifier
         .horizontalScroll(rememberScrollState())

Column(modifier) {
    // my code
}

If user starts scroll to the left, then a fade effect will be appearing on the left side. I tried to apply the solution from here for the horizontal fade effect, but this solution doesn't work for me.

fun Modifier.horizontalFadingEdge(
    scrollState: ScrollState,
    length: Dp,
    edgeColor: Color? = null,
) = composed(
    debugInspectorInfo {
        name = "length"
        value = length
    }
) {
    val color = edgeColor ?: MaterialTheme.colors.surface

    drawWithContent {
        val lengthValue = length.toPx()
        val scrollFromStart = scrollState.value
        val scrollFromEnd = scrollState.maxValue - scrollState.value

        val startFadingEdgeStrength = lengthValue * (scrollFromStart / lengthValue).coerceAtMost(1f)

        val endFadingEdgeStrength = lengthValue * (scrollFromEnd / lengthValue).coerceAtMost(1f)

        drawContent()

        drawRect(
            brush = Brush.horizontalGradient(
                colors = listOf(
                    color,
                    Color.Transparent,
                ),
                startX = 0f,
                endX = startFadingEdgeStrength,
            ),
            size = Size(
                startFadingEdgeStrength,
                this.size.height,
            ),
        )

        drawRect(
            brush = Brush.horizontalGradient(
                colors = listOf(
                    Color.Transparent,
                    color,
                ),
                startX = size.width - endFadingEdgeStrength,
                endX = size.width,
            ),
            topLeft = Offset(x = size.width - endFadingEdgeStrength, y = 0f),
        )
    }
}

Question: How to implement a fade effect in horizontal scrollable column?

I expecting this behaviour (it's a table implement via a SwiftUI framework


Solution

  • You can apply it using:

        val state = rememberScrollState()
    
        Row(
            Modifier.horizontalFadingEdge(state, 20.dp, Yellow).horizontalScroll(state)
        ) {
            //....
        }
    

    enter image description here

    In the Modifier.horizontalFadingEdge is better to change scrollFromStart and scrollFromEnd to

        val scrollFromStart by derivedStateOf { scrollState.value }
        val scrollFromEnd by derivedStateOf { scrollState.maxValue - scrollState.value }