如何使用 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)
}
}
我一直在尝试创建一个类似于下图的自定义视图,其中白色 '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)
}
}