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

Android中如何创建带有凹面的Shape图形

Hey there! 虽然看不到你提到的目标图形,但从你说普通圆角不是需求来看,大概率是那种非对称圆角、斜切角或者其他特殊异形吧?我给你整理几种常见场景的实现方案,你可以对照着试试:

自定义特殊形状的几种实现方案

1. 仅部分角为圆角(非对称圆角)

如果你的需求是只有特定几个角是圆角(比如左上+右下圆角,其余直角),直接修改你现有的<shape>标签就行,不用统一设置所有角的半径:

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#FFFFFF"/>
    <!-- 单独设置每个角的半径,不需要圆角的设为0dp即可 -->
    <corners
        android:topLeftRadius="10dp"
        android:topRightRadius="0dp"
        android:bottomLeftRadius="0dp"
        android:bottomRightRadius="10dp"/>
    <!-- 注意你原来的padding属性拼写有误,修正后示例如下 -->
    <padding
        android:left="8dp"
        android:top="8dp"
        android:right="8dp"
        android:bottom="8dp"/>
</shape>

2. 斜切角/多边形类形状

如果是类似卡片带斜切角、梯形这类形状,普通<shape>标签无法实现,推荐两种方式:

方式一:自定义Path Drawable

创建一个Kotlin/Java类继承Drawable,通过绘制自定义路径实现:

class CutCornerDrawable(private val cornerSize: Float, private val shapeColor: Int) : Drawable() {
    private val drawPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = shapeColor
        style = Paint.Style.FILL
    }
    private val shapePath = Path()

    override fun onBoundsChange(bounds: Rect) {
        super.onBoundsChange(bounds)
        shapePath.reset()
        // 示例:绘制左上角斜切的矩形
        shapePath.moveTo(cornerSize, 0f)
        shapePath.lineTo(bounds.width().toFloat(), 0f)
        shapePath.lineTo(bounds.width().toFloat(), bounds.height().toFloat())
        shapePath.lineTo(0f, bounds.height().toFloat())
        shapePath.lineTo(0f, cornerSize)
        shapePath.close()
    }

    override fun draw(canvas: Canvas) {
        canvas.drawPath(shapePath, drawPaint)
    }

    override fun setAlpha(alpha: Int) {
        drawPaint.alpha = alpha
    }

    override fun setColorFilter(colorFilter: ColorFilter?) {
        drawPaint.colorFilter = colorFilter
    }

    override fun getOpacity(): Int = PixelFormat.TRANSLUCENT
}

之后在代码里给View设置这个Drawable:

val customDrawable = CutCornerDrawable(30f, Color.WHITE)
yourTargetView.background = customDrawable

方式二:使用VectorDrawable

创建res/drawable/custom_shape.xml,通过矢量图形定义路径:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="200dp"
    android:height="100dp"
    android:viewportWidth="200"
    android:viewportHeight="100">
    <!-- pathData里的坐标可按需调整,示例为右上角斜切的矩形 -->
    <path
        android:fillColor="#FFFFFF"
        android:pathData="M0,0 L180,0 L200,20 L200,100 L0,100 Z"/>
</vector>

3. 复杂曲线/异形(波浪边、圆弧组合等)

如果是波浪底边、不规则圆弧这类更复杂的形状,依然可以用自定义Path结合贝塞尔曲线实现,比如绘制波浪底边:

override fun onBoundsChange(bounds: Rect) {
    super.onBoundsChange(bounds)
    shapePath.reset()
    // 绘制顶部直线+底部波浪的形状
    shapePath.moveTo(0f, 0f)
    shapePath.lineTo(bounds.width().toFloat(), 0f)
    // 用二次贝塞尔曲线绘制波浪
    shapePath.quadTo(bounds.width()*0.25f, bounds.height()-10f, bounds.width()*0.5f, bounds.height())
    shapePath.quadTo(bounds.width()*0.75f, bounds.height()+10f, bounds.width().toFloat(), bounds.height())
    shapePath.lineTo(0f, bounds.height())
    shapePath.close()
}

如果能补充一下目标图形的具体描述(比如是斜切角、单边波浪还是其他样式),可以给你更精准的代码哦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:05:17