2017-09-20 19 views
0

私は、すべてのコーナーを描く方法を制御できるパスでカスタム矩形を作成しました:丸みを帯びていない丸い「内側」(普通の丸い角)、丸みを帯びた「外側」コード:Androidパスの形状が正しく塗りつぶされていません

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) 
    } 

stroke, all corners outside しかし、私はそれが下の絵のように塗りつぶし塗りつぶしタイプで描くとき: enter image description here 私はすべてのPath.FillTypesを試してみたが、それらのどれもが適切に矩形を塗りつぶしていません。 私のコードで何が問題になっていますか?

+0

しかし閉じる()だけ現在の点から最初の点までのセグメントを追加し、それはないですか? –

+0

あなたは常に90度を持っていて、外には~90度でなければならないのですか? – pskink

+0

@pskink、ありがとう、あなたが絶対に正しい、私は "外側"円弧セグメントを描画するとき、それはセグメントの端点を開始点に描画され、これはパス内の分割を引き起こします。 –

答えて

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) 
     } 
    } 
} 

final result

関連する問題