简体   繁体   中英

Shadow clipping in LazyColumn/LazyRow

The shadow is clipping in a very odd way when it's overlapping other items in a LazyRow and I can't figure out why. I'm running this code on TV emulator but I can't imagine that would make any difference.

Attempt 1: Modifier.shadow()

val colors = listOf(
    Color.Red,
    Color.Blue,
    Color.Green,
    Color.Yellow
)

@Composable
fun ListTest() {
    LazyColumn {
        items(30) {
            Column {
                Text("This is row $it")
                LazyRow {
                    items(colors) {
                        var isFocused by remember { mutableStateOf(false) }
                        val alpha = if (isFocused) 1f else 0.25f
                        val elevation = if (isFocused) 40.dp else 0.dp
                        Surface(
                            shape = RoundedCornerShape(8.dp),
                            color = it.copy(alpha = alpha),
                            modifier = Modifier
                                .width(240.dp)
                                .height(150.dp)
                                .padding(start = 16.dp)
                                // 🔴 Look here
                                .shadow(elevation)
                                .onFocusChanged { state ->
                                    isFocused = state.isFocused
                                }
                                .focusable(),
                        ) {
                           // Content here
                        }
                    }
                }
            }
        }
    }
}

显示阴影剪切问题的图像

Attempt 2: Modifier.drawBehind {}

I was referred to these lines in the Android code that limits elevation to 30.dp .


val colors = listOf(
    Color.Red,
    Color.Blue,
    Color.Green,
    Color.Yellow
)

@Composable
fun ListTest() {
    LazyColumn {
        items(30) {
            Column {
                Text("This is row $it")
                LazyRow {
                    items(colors) {
                        var isFocused by remember { mutableStateOf(false) }
                        val alpha = if (isFocused) 1f else 0.25f
                        val shadowColor = if (isFocused) Color.Black else Color.Transparent
                        Surface(
                            shape = RoundedCornerShape(8.dp),
                            color = it.copy(alpha = alpha),
                            modifier = Modifier
                                .width(240.dp)
                                .height(150.dp)
                                .padding(start = 16.dp)
                                // 🔴 Look here
                                .coloredShadow(shadowColor)
                                .onFocusChanged { state ->
                                    isFocused = state.isFocused
                                }
                                .focusable(),
                        ) {
                            // Content here
                        }
                    }
                }
            }
        }
    }
}


fun Modifier.coloredShadow(color: Color) = drawBehind {
    val shadowColor = color.toArgb()
    val transparentColor = color.copy(alpha = 0f).toArgb()
    val offsetX = 0.dp
    val offsetY = 8.dp
    val cornerRadius = 4.dp
    drawIntoCanvas {
        val paint = Paint()
        val frameworkPaint = paint.asFrameworkPaint()
        frameworkPaint.color = transparentColor
        frameworkPaint.setShadowLayer(
            // 🔴 Set to 400.dp as radius
            400.dp.toPx(), 
            offsetX.toPx(),
            offsetY.toPx(),
            shadowColor
        )
        it.drawRoundRect(
            0f,
            0f,
            this.size.width,
            this.size.height,
            cornerRadius.toPx(),
            cornerRadius.toPx(),
            paint
        )
    }
}

第二次尝试后显示阴影剪切问题的图像

How can I get rid of this clipping issue?

I don't think it's a clipping issue. You just have the elevation set too high, so the surface's shadow has to reach across another row/column, and display on top of another Surface, but because they're not children of the same view, it's not processing the shadow blurring properly.

Maybe you should try setting the elevation to 30dp or 24dp?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM