如何使用 Android Canvas 创建 'wave' 样式布局

How to create a 'wave' style layout using Android Canvas

我一直在尝试创建一个类似于下图的自定义视图,其中白色 'wave' 视图在右上角包含一个扩展的 'inverse rounded corner',在左下角包含一个圆角。

我曾尝试使用 Material Shape 主题实现此目的,但这似乎不支持 'inverse' 圆角。

为了实现这一点,我一直在其 Canvas 中使用 View 和自定义绘图,但无法使其正常工作,因为我不确定如何实现反向舍入转角效果。

如有任何帮助或指导,我们将不胜感激

class TestView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    private var mPath = Path()

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)

        val h = height.toFloat()
        val h2 = height.toFloat() / 2f
        val w = width.toFloat()
        val w2 = width.toFloat() / 2f

        mPath.reset()
        mPath.addArc(w2, 0f, w, h2, 0f, 90f)
        mPath.addArc(0f, h2, w2, h, 180f, 90f)
        mPath.lineTo(w, h2)
        mPath.lineTo(w, h)
        mPath.lineTo(0f, h)
        mPath.close()

        mPath.fillType = Path.FillType.WINDING
        canvas?.clipPath(mPath)
        canvas?.drawColor(Color.DKGRAY)
    }
}

我使用 Bezier curves and adapting the answer found in

解决了这个问题

我用来实现这个的代码如下:

class SweepView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    private val paint = Paint().apply {
        color = Color.RED
        isAntiAlias = true
        style = Paint.Style.FILL
    }

    private val path = Path()

    override fun onDraw(canvas: Canvas?) {

        val h = height.toFloat()
        val halfH = h / 2f
        val w = width.toFloat()
        val delta = width / 3f

        path.reset()
        path.moveTo(0f, h)
        path.cubicTo(0f, halfH, 0f, halfH, delta, halfH)
        path.lineTo(w - delta, halfH)
        path.cubicTo(w, halfH, w, halfH, w, 0f)
        path.lineTo(w, h)
        path.close()

        canvas?.drawPath(path, paint)
    }

}