Is there any possibility to add an alpha to a lazy...
# compose
p
Is there any possibility to add an alpha to a lazyRow component, so for example 30% of width will have some level of transparency, and that will change dynamically on user scroll? I have tried modifier.background, adding a box with alpha on top of the lazyRow, but this things do not modify the child views of Row. These are additional composables that render in background or in front. Picture in thread 🧵
image.png
I do think the only way to do this is using new RenderEffect API, but I have no idea how to use it in compose. Anyone has any example?
e
no need for render effects
Copy code
Modifier
    .drawWithCache {
        val brush = Brush.horizontalGradient(
            0f to Color.Transparent,
            0.35f to Color.Black,
            0.65f to Color.Black,
            1f to Color.Transparent,
        )
        onDrawWithContent {
            drawContent()
            drawRect(brush = brush, blendMode = BlendMode.DstIn)
        }
    }
p
Thanks for reply! As I understand this snippet, you are drawing a RECT on top of a Row with black and transparent colors. This will not add a dynamic alpha to my child items as presented on the screen
e
DstIn will discard the colors in the gradient and only multiply the alpha through
p
This is the effect of a snippet:
a
You also need to add
.graphicsLayer(compositingStrategy = CompositingStrategy.Offscreen)
(or
.graphicsLayer(alpha = 0.99f)
if you are using stable version) before
.drawWithCache
.
e
yes, without being composited separately, the alpha multiply applies all the way through
if you wanted to use a RenderEffect, you could
Copy code
val shader = remember {
    RuntimeShader(
        """
        uniform shader image;
        uniform float width;
        half4 main(vec2 coords) {
            float alpha = saturate((0.5 - abs(coords.x / width - 0.5)) / 0.35);
            half4 color = image.eval(coords);
            return half4(color.rgb, color.a * alpha);
        }
        """.trimIndent()
    )
}
var width by remember { mutableStateOf(0) }
Modifier
    .onSizeChanged { width = it.width }
    .graphicsLayer {
        shader.setFloatUniform("width", width.toFloat())
        renderEffect = RenderEffect.createRuntimeShaderEffect(shader, "image").asComposeRenderEffect()
    }
but RuntimeShader is Android 13+ and it really doesn't seem worthwhile to choose to go down that path
p
Thank you so much. I added the
.graphicsLayer(compositingStrategy = CompositingStrategy.Offscreen)
and it works!! 🎉