You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose:如何对角分割Card并在分区内填充图片?

Got it, let's tackle that diagonal split for your Jetpack Compose Card! The vertical split you've got works, but to get that diagonal divide between the two images, we need to use path clipping—here's how to do it right.

Solution for Diagonally Split Image Card in Jetpack Compose

The core idea is to clip each image to half the Card along a diagonal line, using Jetpack Compose's path-based clipping. Here's a complete, reusable implementation:

Step 1: Create a Custom Clipping Modifier

First, we'll build a reusable modifier that clips a composable to either the top-left or bottom-right triangular half of its parent (easy to adjust for other diagonal directions too):

fun Modifier.clipDiagonal(isTopLeftHalf: Boolean = true) = this.then(
    Modifier.drawWithContent {
        val clipPath = Path().apply {
            if (isTopLeftHalf) {
                // Define the top-left triangle: top edge -> left edge -> bottom-left corner
                moveTo(0f, 0f)
                lineTo(size.width, 0f)
                lineTo(0f, size.height)
                close()
            } else {
                // Define the bottom-right triangle: right edge -> bottom edge -> top-right corner
                moveTo(size.width, 0f)
                lineTo(size.width, size.height)
                lineTo(0f, size.height)
                close()
            }
        }
        // Clip the content to our path before drawing
        clipPath(clipPath) {
            this@drawWithContent.drawContent()
        }
    }
)

Step 2: Implement the Split Card

Replace your Row with a Box (so both images fill the entire Card space, stacked on top of each other) and apply the custom modifier to each AsyncImage:

Card(
    modifier = Modifier
        .fillMaxWidth()
        .constrainAs(image) {
            top.linkTo(parent.top)
            start.linkTo(parent.start)
            end.linkTo(parent.end)
            width = Dimension.fillToConstraints
        }
        .fillMaxSize(0.3f)
) {
    Box(modifier = Modifier.fillMaxSize()) {
        // Top-left diagonal half
        AsyncImage(
            model = url1,
            contentDescription = "Product Image (Top-Left)",
            modifier = Modifier
                .fillMaxSize()
                .clipDiagonal(isTopLeftHalf = true),
            contentScale = ContentScale.Crop
        )
        // Bottom-right diagonal half
        AsyncImage(
            model = url2,
            contentDescription = "Product Image (Bottom-Right)",
            modifier = Modifier
                .fillMaxSize()
                .clipDiagonal(isTopLeftHalf = false),
            contentScale = ContentScale.Crop
        )
    }
}

Quick Customization Options

  • Reverse the Diagonal: To split from top-right to bottom-left, adjust the path in the clipDiagonal modifier:
    if (isTopRightHalf) {
        moveTo(size.width, 0f)
        lineTo(0f, 0f)
        lineTo(size.width, size.height)
        close()
    } else {
        moveTo(0f, 0f)
        lineTo(0f, size.height)
        lineTo(size.width, size.height)
        close()
    }
    
  • Add a Divider Line: If you want a thin border between the two halves, add a Canvas inside the Box to draw the diagonal:
    Canvas(modifier = Modifier.fillMaxSize()) {
        drawLine(
            color = Color.Gray,
            start = Offset(0f, 0f),
            end = Offset(size.width, size.height),
            strokeWidth = 2.dp.toPx()
        )
    }
    

This approach ensures both images fill the Card properly, stay cropped to the exact diagonal, and preserves the Card's built-in elevation and shape.

内容的提问来源于stack exchange,提问作者Webster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 18:22:34