Hi All, I’m running into an issue with the `graphi...
# compose
p
Hi All, I’m running into an issue with the
graphicsLayer?
. I have a
LazyRow
, each item is a
Column
with a
Surface
containing an image that expands on focus (with rounded corners, borders, etc.), and some
Text
underneath the
Surface
. When navigating through the row, I’m applying an
alpha(targetValue)
modifier to fade some non-focused items. The problem is that this seems to mess up the scaling animation of the focused item. If I remove the
alpha
, the animation runs perfectly smooth. Does anyone know why applying
Modifier.alpha()
affects the animation?
simple sample code:
Copy code
@Composable
fun MyRowOfItems(modifier: Modifier = Modifier) {
    val lazyListState = rememberLazyListState()
    var focusedIndex by remember { mutableIntStateOf(0) }
    LazyRow(
        modifier = modifier.padding(top = 20.dp),
        state = lazyListState,
        horizontalArrangement = Arrangement.spacedBy(12.dp),
        contentPadding = PaddingValues(horizontal = 30.dp)
    ) {
        items(25) { index ->
            val alphaAnimation: Float by animateFloatAsState(
                label = "fade RowItem #$index",
                targetValue = if (index < focusedIndex) 0.25f else 1f
            )
            Column(
                modifier = Modifier
                    .zIndex(if (index == focusedIndex) 1f else 0f)
                    .alpha(alphaAnimation),
                verticalArrangement = Arrangement.spacedBy(20.dp)
            ) {
                Surface(
                    modifier = Modifier
                        .size(200.dp, 150.dp)
                        .onFocusChanged { focusState ->
                            if (focusState.isFocused) {
                                focusedIndex = index
                            }
                        },
                    border = ClickableSurfaceDefaults.border(
                        border = Border.None,
                        focusedBorder = Border(border = BorderStroke(width = 2.dp, color = Color.Cyan), shape = MaterialTheme.shapes.medium)
                    ),
                    scale = ClickableSurfaceDefaults.scale(
                        scale = 1.0f,
                        focusedScale = 1.2f
                    ),
                    glow = ClickableSurfaceDefaults.glow(Glow.None),
                    onClick = {  }
                ) {
                    Box(
                        modifier = Modifier
                            .fillMaxSize()
                            .background(
                                color = Color(
                                    red = (0..255).random(),
                                    green = (0..255).random(),
                                    blue = (0..255).random()
                                )
                            )
                    )
                }

                Text(text = "Item #$index")
            }
        }
    }
}
j
try to replace
.alpha(value)
with
Copy code
.graphicsLayer {
  alpha = value
  compositingStrategy = CompositingStrategy.ModulateAlpha
}
❤️ 1
👆 1
s
For animation, specifically when animating graphics layer properties, it’s recommended to use the lambda variant of this modifier. This approach prevents the entire chain of recompositions and instead applies property changes directly within the drawing phase. In your case, since you’re animating the alpha value, the widget is rendered into an offscreen buffer(a separate texture). The clipping you’re observing may be caused by the texture boundary clipping. Try animating both the scale and alpha within a single .graphicsLayer { ... } block and set compositingStrategy = CompositingStrategy.ModulateAlpha.
❤️ 1
p
thank you!