我创建了一个带路径的自定义矩形形状,您可以在其中控制如何绘制所有角落:不是圆角,圆形“内部”(它是普通的圆角),圆形“外部”(见图片)。代码:
enum class CornerType {
NOT_ROUNDED,
ROUNDED_INSIDE,
ROUNDED_OUTSIDE
}
object CustomShapes {
fun rectangleWithRoundedCorners(path: Path, rect: Rect, cornerRadius: Int,
topLeft: CornerType, topRight: CornerType,
bottomLeft: CornerType, bottomRight: CornerType){
val topLeftX = when(topLeft){
CornerType.NOT_ROUNDED -> rect.left
CornerType.ROUNDED_INSIDE -> rect.left + cornerRadius
CornerType.ROUNDED_OUTSIDE -> rect.left - cornerRadius
}.toFloat()
val topLeftY = rect.top.toFloat()
val topRightX = when(topRight){
CornerType.NOT_ROUNDED -> rect.right
CornerType.ROUNDED_INSIDE -> rect.right - cornerRadius
CornerType.ROUNDED_OUTSIDE -> rect.right + cornerRadius
}.toFloat()
val topRightY = rect.top.toFloat()
val bottomLeftX = when(bottomLeft){
CornerType.NOT_ROUNDED -> rect.left
CornerType.ROUNDED_INSIDE -> rect.left + cornerRadius
CornerType.ROUNDED_OUTSIDE -> rect.left - cornerRadius
}.toFloat()
val bottomLeftY = rect.bottom.toFloat()
val bottomRightX = when(bottomRight){
CornerType.NOT_ROUNDED -> rect.right
CornerType.ROUNDED_INSIDE -> rect.right - cornerRadius
CornerType.ROUNDED_OUTSIDE -> rect.right + cornerRadius
}.toFloat()
val bottomRightY = rect.bottom.toFloat()
path.reset()
//1
path.moveTo(topLeftX, topLeftY)
//2
path.lineTo(topRightX, topRightY)
//3
when(topRight){
CornerType.NOT_ROUNDED -> path.lineTo(topRightX, topRightY + cornerRadius.toFloat())
CornerType.ROUNDED_INSIDE -> {
path.arcTo(RectF(topRightX - cornerRadius, topRightY,
topRightX + cornerRadius, topRightY + 2*cornerRadius), 270f, 90f, true)
path.moveTo(topRightX + cornerRadius, topRightY + cornerRadius)
}
CornerType.ROUNDED_OUTSIDE -> {
path.arcTo(RectF(topRightX - cornerRadius, topRightY,
topRightX + cornerRadius, topRightY + 2*cornerRadius), 180f, 90f, true)
path.moveTo(topRightX - cornerRadius, topRightY + cornerRadius)
}
}
//4
path.lineTo(rect.right.toFloat(), bottomRightY - cornerRadius)
//5
when(bottomRight){
CornerType.NOT_ROUNDED -> path.lineTo(bottomRightX, bottomRightY)
CornerType.ROUNDED_INSIDE -> {
path.arcTo(RectF(bottomRightX - cornerRadius, bottomRightY - 2*cornerRadius,
bottomRightX + cornerRadius, bottomRightY), 0f, 90f, true)
path.moveTo(bottomRightX, bottomRightY)
}
CornerType.ROUNDED_OUTSIDE -> {
path.arcTo(RectF(bottomRightX - cornerRadius, bottomRightY - 2*cornerRadius,
bottomRightX + cornerRadius, bottomRightY), 90f, 90f, true)
path.moveTo(bottomRightX, bottomRightY)
}
}
//6
path.lineTo(bottomLeftX, bottomLeftY)
//7
when(bottomLeft){
CornerType.NOT_ROUNDED -> path.lineTo(bottomLeftX, bottomRightY - cornerRadius)
CornerType.ROUNDED_INSIDE -> {
path.arcTo(RectF(bottomLeftX - cornerRadius, bottomLeftY - 2 * cornerRadius,
bottomLeftX + cornerRadius, bottomLeftY), 90f, 90f, true)
path.moveTo(bottomLeftX - cornerRadius, bottomLeftY - cornerRadius)
}
CornerType.ROUNDED_OUTSIDE -> {
path.arcTo(RectF(bottomLeftX - cornerRadius, bottomLeftY - 2*cornerRadius,
bottomLeftX + cornerRadius, bottomLeftY), 0f, 90f, true)
path.moveTo(bottomLeftX + cornerRadius, bottomLeftY - cornerRadius)
}
}
//8
path.lineTo(rect.left.toFloat(), topLeftY + cornerRadius)
//9
when(topLeft){
CornerType.NOT_ROUNDED -> path.lineTo(topLeftX, topLeftY)
CornerType.ROUNDED_INSIDE -> path.arcTo(RectF(topLeftX - cornerRadius, topLeftY,
topLeftX + cornerRadius, topLeftY + 2*cornerRadius), 180f, 90f, true)
CornerType.ROUNDED_OUTSIDE -> path.arcTo(RectF(topLeftX - cornerRadius, topLeftY,
topLeftX + cornerRadius, topLeftY + 2*cornerRadius), 270f, 90f, true)
}
}
}
当我尝试用笔划绘制它时,似乎一切都按预期工作。
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val paint = Paint()
paint.color = Color.RED
//paint.strokeWidth = 3f
paint.style = Paint.Style.STROKE
paint.isAntiAlias = true
val path = Path()
path.fillType = Path.FillType.EVEN_ODD
CustomShapes.rectangleWithRoundedCorners(path, Rect(100, 100, 600, 600), 50, CornerType.ROUNDED_OUTSIDE, CornerType.ROUNDED_OUTSIDE, CornerType.ROUNDED_OUTSIDE, CornerType.ROUNDED_OUTSIDE)
canvas.drawPath(path, paint)
}
但是当我用填充类型绘制时,它填充如下图所示: 我已经尝试了所有Path.FillTypes,但它们都没有正确填充矩形。 我的代码出了什么问题?
答案 0 :(得分:0)
@pskink正确地指出这个问题是因为"外面"的错误绘制方向弧。 更正了图纸代码:
path.reset()
//1
path.moveTo(topLeftX, topLeftY)
//2
path.lineTo(topRightX, topRightY)
//3
when(topRight){
CornerType.NOT_ROUNDED -> path.lineTo(topRightX, topRightY + cornerRadius.toFloat())
CornerType.ROUNDED_INSIDE -> {
path.arcTo(RectF(topRightX - cornerRadius, topRightY,
topRightX + cornerRadius, topRightY + 2*cornerRadius), 270f, 90f, false)
//path.moveTo(topRightX + cornerRadius, topRightY + cornerRadius)
}
CornerType.ROUNDED_OUTSIDE -> {
path.arcTo(RectF(topRightX - cornerRadius, topRightY,
topRightX + cornerRadius, topRightY + 2*cornerRadius), 270f, -90f, false)
//path.moveTo(topRightX - cornerRadius, topRightY + cornerRadius)
}
}
//4
path.lineTo(rect.right.toFloat(), bottomRightY - cornerRadius)
//5
when(bottomRight){
CornerType.NOT_ROUNDED -> path.lineTo(bottomRightX, bottomRightY)
CornerType.ROUNDED_INSIDE -> {
path.arcTo(RectF(bottomRightX - cornerRadius, bottomRightY - 2*cornerRadius,
bottomRightX + cornerRadius, bottomRightY), 0f, 90f, false)
//path.moveTo(bottomRightX, bottomRightY)
}
CornerType.ROUNDED_OUTSIDE -> {
path.arcTo(RectF(bottomRightX - cornerRadius, bottomRightY - 2*cornerRadius,
bottomRightX + cornerRadius, bottomRightY), 180f, -90f, false)
//path.moveTo(bottomRightX, bottomRightY)
}
}
//6
path.lineTo(bottomLeftX, bottomLeftY)
//7
when(bottomLeft){
CornerType.NOT_ROUNDED -> path.lineTo(bottomLeftX, bottomRightY - cornerRadius)
CornerType.ROUNDED_INSIDE -> {
path.arcTo(RectF(bottomLeftX - cornerRadius, bottomLeftY - 2 * cornerRadius,
bottomLeftX + cornerRadius, bottomLeftY), 90f, 90f, false)
//path.moveTo(bottomLeftX - cornerRadius, bottomLeftY - cornerRadius)
}
CornerType.ROUNDED_OUTSIDE -> {
path.arcTo(RectF(bottomLeftX - cornerRadius, bottomLeftY - 2*cornerRadius,
bottomLeftX + cornerRadius, bottomLeftY), 90f, -90f, false)
//path.moveTo(bottomLeftX + cornerRadius, bottomLeftY - cornerRadius)
}
}
//8
path.lineTo(rect.left.toFloat(), topLeftY + cornerRadius)
//9
when(topLeft){
CornerType.NOT_ROUNDED -> path.lineTo(topLeftX, topLeftY)
CornerType.ROUNDED_INSIDE -> path.arcTo(RectF(topLeftX - cornerRadius, topLeftY,
topLeftX + cornerRadius, topLeftY + 2*cornerRadius), 180f, 90f, false)
CornerType.ROUNDED_OUTSIDE -> path.arcTo(RectF(topLeftX - cornerRadius, topLeftY,
topLeftX + cornerRadius, topLeftY + 2*cornerRadius), 0f, -90f, false)
}
}
}