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

如何在Jetpack Compose中创建带圆角的梯形卡片?

实现Jetpack Compose带圆角的梯形卡片

要实现这种带圆角的梯形卡片,自定义Shape类是最直接的方案,核心是通过Path手动绘制梯形轮廓并添加圆角。以下是完整的实现步骤和代码:

1. 自定义梯形Shape类

创建一个继承自Shape的类,通过参数控制圆角大小和梯形底部宽度比例,让形状更灵活:

import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Outline
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp

class TrapezoidShape(
    private val cornerRadius: Float = 16.dp.toPx(), // 圆角大小
    private val bottomWidthFraction: Float = 0.8f // 底部宽度占顶部宽度的比例,0.8表示底部是顶部的80%宽
) : Shape {
    override fun createOutline(
        size: Size,
        layoutDirection: LayoutDirection,
        density: Density
    ): Outline {
        val path = Path()
        val width = size.width
        val height = size.height

        // 计算四个关键顶点(圆角切点)
        val topLeft = Offset(cornerRadius, 0f)
        val topRight = Offset(width - cornerRadius, 0f)
        val bottomRight = Offset(width * bottomWidthFraction + cornerRadius, height)
        val bottomLeft = Offset(width * (1 - bottomWidthFraction) - cornerRadius, height)

        // 绘制路径:从顶部左圆角起点开始
        path.moveTo(topLeft.x, topLeft.y)
        // 顶部右圆角
        path.arcTo(
            rect = androidx.compose.ui.geometry.Rect(
                left = width - 2 * cornerRadius,
                top = 0f,
                right = width,
                bottom = 2 * cornerRadius
            ),
            startAngleDegrees = 180f,
            sweepAngleDegrees = 90f,
            forceMoveTo = false
        )
        // 右侧斜边(从顶部右圆角终点到底部右圆角起点)
        path.lineTo(bottomRight.x, bottomRight.y)
        // 底部右圆角
        path.arcTo(
            rect = androidx.compose.ui.geometry.Rect(
                left = width * bottomWidthFraction,
                top = height - 2 * cornerRadius,
                right = width * bottomWidthFraction + 2 * cornerRadius,
                bottom = height
            ),
            startAngleDegrees = 90f,
            sweepAngleDegrees = 90f,
            forceMoveTo = false
        )
        // 底部边(从底部右圆角终点到底部左圆角起点)
        path.lineTo(bottomLeft.x, bottomLeft.y)
        // 底部左圆角
        path.arcTo(
            rect = androidx.compose.ui.geometry.Rect(
                left = width * (1 - bottomWidthFraction) - 2 * cornerRadius,
                top = height - 2 * cornerRadius,
                right = width * (1 - bottomWidthFraction),
                bottom = height
            ),
            startAngleDegrees = 0f,
            sweepAngleDegrees = 90f,
            forceMoveTo = false
        )
        // 左侧斜边(从底部左圆角终点到顶部左圆角起点)
        path.lineTo(topLeft.x, topLeft.y)
        path.close()

        return Outline.Generic(path)
    }
}

2. 在Card中使用自定义Shape

直接把这个Shape传给Card的shape参数即可,搭配修饰符调整大小:

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

@Composable
fun TrapezoidCardDemo() {
    Card(
        shape = TrapezoidShape(
            cornerRadius = 16.dp.toPx(),
            bottomWidthFraction = 0.8f
        ),
        modifier = Modifier.size(width = 200.dp, height = 120.dp),
        colors = CardDefaults.cardColors(containerColor = Color(0xFF6200EE))
    ) {
        Box(
            modifier = Modifier.fillMaxSize(),
            contentAlignment = Alignment.Center
        ) {
            Text(text = "梯形卡片", color = Color.White)
        }
    }
}

关键细节说明

  • bottomWidthFraction:控制梯形底部的宽度比例,值越小底部越窄,可根据需求调整
  • cornerRadius:统一设置四个角的圆角大小,如果需要单独控制不同角的圆角,可以修改Shape类的参数和路径绘制逻辑
  • 路径绘制时使用arcTo实现圆角,确保圆弧和斜边/直边平滑衔接
  • 如果需要支持RTL布局,可在createOutline中根据layoutDirection调整顶点坐标

内容的提问来源于stack exchange,提问作者Ahmed El-Hady

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 22:50:21