How to draw custom paths/lines in Android usign PathEffect

We can draw simple lines and shapes by using path.lineTo, path.moveTo etc. But sometimes we have requirements to draw a line in pattern, for example: simple dashed, two lines where 1 is continuous and other one is dashed etc.

Lines Drawn By PathEffects

Getting started

First we’ll have to create a small path that we want to repeat in the final path

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// These are some sample methods to generate a single block of path
// which will be repeated in the final path that we'll draw on canvas

// This will draw a small line with width 10px and length 30px
private fun makeDefaultLinePath(): Path {
val p = Path()
p.moveTo(-15f, 5f)
p.lineTo(15f, 5f)
p.lineTo(15f, -5f)
p.lineTo(-15f, -5f)
return p
}

// This will draw two small lines with width 4px and length 30px
// They'll have 4px space between them
private fun makeDoubleLinePath(): Path {
val p = Path()
p.moveTo(-15f, 6f)
p.lineTo(15f, 6f)
p.lineTo(15f, 2f)
p.lineTo(-15f, 2f)
p.close()
p.moveTo(-15f, -6f)
p.lineTo(15f, -6f)
p.lineTo(15f, -2f)
p.lineTo(-15f, -2f)
return p
}

// This will draw two small lines
// One with width 4px and length 15px
// Other with width 4px and length 30px
// They'll have 4px space between them
private fun makeBrokenSolidLinePath(): Path {
val p = Path()
p.moveTo(-15f, 6f)
p.lineTo(0f, 6f)
p.lineTo(0f, 2f)
p.lineTo(-15f, 2f)
p.close()
p.moveTo(-15f, -6f)
p.lineTo(15f, -6f)
p.lineTo(15f, -2f)
p.lineTo(-15f, -2f)
return p
}

We’ve create our building blocks of the final path. Now we’ll be setting PathEffect to the paint that will draw these blocks.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// First setup your paint object
val paint = Paint()
paint.style = Paint.Style.STROKE
paint.strokeWidth = 10f
paint.color = Color.YELLOW

// Declare your pathDashPathEffect
var pathDashPathEffect: PathDashPathEffect? = null

// Define your pathDashPathEffect
pathDashPathEffect = PathDashPathEffect(makeDoubleLanePath(), //Your building block
45f, //At how much distance the next block should be drawn from the current block's starting point
0f, //Phase value
PathDashPathEffect.Style.MORPH) //EffectStyle

// Set your defined pathDashPathEffect to your paint object
pathDashPathEffect?.let { effect ->
paint.pathEffect = effect
}

We have our paint object with pathEffect with us. Now we’ll be drawing a path that we actaully want to draw using this paint object.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var lineX1 = 0f
var lineX2 = 0f
var lineY1 = 0f
var lineY2 = 0f
val path = Path()

override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
path.reset()
path.moveTo(lineX1, lineY1)
path.lineTo(lineX2, lineY2)

canvas?.drawPath(path, //This final path that we are drawing now
paint) //The one that we created earlier
}

References:-

  1. Custom path line style when drawing on canvas
  2. what does path mean in PathDashPathEffect constructor
  3. PathDashPathEffect example

Some good reads you may like:-

  1. Paytm Gateway Integration
  2. Android Testing Strategy

p.s. Nayan is a platform that offers high precision services for traffic monitoring and road safety. Check out our website

Share

© 2019 NAYAN All Rights Reserved