Learn All Android Canvas Draw Functions

23 functions for drawing with Android Canvas

Aug 3, 2019 · 9 min read

If you would like to create custom view from ground up in Android, it’s helpful to know which draw functions are available on Canvas.

In this blog, I list every draw function available in Android Canvas: 23 of them. Do go through them. You might find some you never knew existed (I myself was surprised by some).

Below, I categorize them as:

1. Geometrical Drawing
2. Text Drawing
3. Color Drawing
4. Image Drawing

In case you don’t have experience making custom views, you can refer to the tutorials below:

Geometrical Drawing

Most people use Canvas to draw geometrical items.

1. `drawLine`

Simply draw one line.

`canvas.drawLine(startX, startY, endX, endY, paint)`

2. `drawLines`

If we want to draw more than a line, instead of performing `drawLine` multiple times, we could use `drawLines`. We just need to provide a flat float array list of the coordinate values as below.

`canvas.drawLines(    floatArrayOf(        startFirstX, startFirstY, endFirstX, endFirstY,        startSecondX, startSecondY, endSecondX, endSecondY),    paint)`

3. `drawPoint`

While you could draw a point by drawing a line with the same start and end coordinates, this is considered a hack. So a `drawPoint` function is provided.

`canvas.drawPoint(coordinateX, coordinateY, paint)`

4. `drawPoints`

As with lines, you can draw multiple points with a flat float coordinate array.

`canvas.drawPoints(    floatArrayOf(        startX, startY,        startSecondX, startSecondY),    paint)`

5. `drawRect`

Draw a rectangle using coordinates or a `Rect` class.

`canvas.drawRect(    Rect(startX, topY, endX, bottomY),     paint)`

6. `drawRoundRect`

If you want a rectangle with rounded corners, use `drawRoundedRect`. It’s similar to `drawRect` but with the addition of `radiusX` and `radiusY` to define the curvature of the rounded corners.

`canvas.drawRoundRect(rect, radiusX, radiusY, projectResources.paint)`

It draws an evenly rounded corner if `radiusX` equals `radiusY`.

When `radiusX` = `radiusY`, it will have the usual rounded corners as below:

If `radiusX` is bigger than `radiusY`, it will end up similar to below:

If `radiusX` is smaller than `radiusY`, it will end up like this:

7. `drawCircle`

`drawCircle` is simple. It only requires the center coordinate and the radius.

`canvas.drawCircle(    centerCoordinateX, centerCoordinateY,    radius,    paint)`

8. `drawOval`

Unlike drawing a circle, we don’t provide a radius. Instead, we provide a `rect`, and the oval will be drawn accordingly.

`canvas.drawOval(rect, paint)`

9. `drawArc`

Drawing an arc uses the same mechanism as drawing an oval: using a Rect. It has additional parameters, i.e. `startAngle`, `sweepAngle`, and `useCenter`.

`canvas.drawArc(rect, startAngle, sweepAngle, useCenter, paint)`

For the `startAngle`, count the middle end of the rect as the start, i.e. 90° clockwise. From there, the `startAngle` is considered 0°. The `sweepAngle` is then calculated from `startAngle`. Both use the angle degree ° value.

`useCenter` is a boolean variable to determine if the arc is connected to the center. The illustrations below depict the difference between `useCenter` as false and true.

10. `drawPath`

Sometimes, we want to draw something that’s not restricted to normal geometrical lines. We use `drawPath` here, where `Path` is an object that contains the paths we want to draw. It consists of functions such as `moveTo` and `lineTo,` like a pencil drawing and moving.

Below is an example where we `drawPath` of a cross mark.

`val path = Path()path.moveTo(startX, topY)path.lineTo(endX, bottomY)path.moveTo(startX, bottomY)path.lineTo(endX, topY)canvas.drawPath(path, paint)`

`drawPath` is a very useful function. Many use it to make drawing app programs in Android. Examples below:

11. `drawVertices`

This is a relatively complex function, which draws triangles or vertices with the minimal points. For example, with six coordinates, one can draw four triangles:

When repeated, it can be used for complex 3D modeling. The art below (a 3D rose) is drawn with `drawVertices`.

Here is a detailed explanation of its function.

Text Drawing

If we had to draw text ourselves, that would be super-tricky. Thankfully, we have several nice options:

12. `drawText`

On Android, we normally use `TextView` for all our text. However, if we’d like better control of the text, such as dynamic changes, exact positioning, etc, the canvas `drawText` comes in handy.

The function follows, with `text`, `coordinate`, and `paint`:

`canvas.drawText(text, coordinateX, coordinateY, paintText)`

These are fun to play with if set correctly, as shown below:

You can find more detail here.

13. Draw `StaticLayout`

`drawText` does have limitations. It doesn’t wrap the longer word to the second line. It also doesn’t handle the `/n` carry return.

For that, we need a `StaticLayout` to draw text that can wrap a long word to the second line.

`StaticLayout` is not really a draw function of the canvas, but instead draws itself into the canvas. Below is how it is drawn:

`val staticLayout =    StaticLayout.Builder.obtain(        TEXT, 0, TEXT.length, textPaint, width    ).build()canvas.save()canvas.translate(coordinateX, coordinateY)staticLayout.draw(canvas)canvas.restore()`

The result:

14. drawPosText

`drawPosText` enables each character to be placed at a specified position. Below, the word fly is written at different Y positions.

The API is below:

`val posArray = listOf(x1, y1, x2, y2, x3, y3 ...).toFloatArray()canvas.drawPosText(TEXT, startIndex, endIndex, posArray, paint)`

The provided coordinate points need to be at least same as the letters to be drawn, or it will crash. The documentation notes:

[This API is deprecated] because this method does not support glyph composition and decomposition and should therefore not be used to render complex scripts. It also doesn’t handle supplementary characters (eg emoji)

15. drawTextOnPath

Coupled with a `path`, we can position our text along the provided `path`.

The `x` and `y` positions are relative to the position of the given `path`.

`canvas.drawTextOnPath(TEXT, path, x, y, paint)`

Below is an example of a V-shaped path, and we draw our text along the path.

16. `drawTextRun`

This is a little more complicated, as it is generally not used with English words. It only applies to language with letters that are drawn differently depending on the visibility of surrounding letters.

For example, the image below has two lines of two letters. The two letters in both lines are the same. However, they are written differently. In the first line, they are part of a larger word, while the second line states the two letters individually.

To understand better, refer to this blog.

Color Drawing

Coloring is useful for the foreground and background of the canvas we’re drawing on. Check it out, as there’s a fancy one…

17. `drawRGB`

This is just drawing a color over the canvas. This is useful for setting a background color.

`canvas.drawRGB(red, green, blue)// Each is between 0 and 255, where 0 is not there, and 255 is full.// When alpha is 255, it is opaque, and 0 is transparent.`

18. `drawARGB`

Similar to `drawRGB`, this adds the ability to make the color semi-transparent.

`canvas.drawARGB(alpha, red, green, blue)// When alpha is 255, it is opaque, and 0 is transparent.`

This is useful to set the front color and dim the item behind.

19. `drawColor`

In case we’d like to use a resource’s color instead of setting our own ARGB color, we can use this API.

`canvas.drawColor(context.getColor(R.color.colorPrimary))`

20. `drawPaint`

Sometimes, we like to paint fancier colors. Instead of using ARGB or a resource color, we could create a `Paint` object. Below is an example:

`val gradientPaint by lazy {    Paint().apply {        shader = RadialGradient(            width/2f,            height/2f,            height/2f,            Color.GREEN,            Color.RED,            Shader.TileMode.MIRROR        )    }canvas.drawPaint(gradientPaint)`

Image Drawing

Without the ability to load images to draw and manipulate them, canvas drawing would be incomplete. So let’s explore what we have…

21. `drawBitmap`

Given a bitmap, we can draw it into the canvas.

`private val bitmap by lazy {    BitmapFactory.decodeResource(resources, R.drawable.image)}canvas.drawBitmap(bitmap, sourceRect, destRect, paint)`

The required parameters are `bitmap` and `destRect`.

• The `bitmap` can be extracted from resources.
• `destRect` is the rectangle area of the `canvas` to be drawn onto.

The optional ones (could be null) are `sourceRect` and `paint`.

• `sourceRect` is a rectangle representing which subset of the picture to draw. When it is null, the entire picture is taken. (Note: this is very useful for some animation, when a picture of the entire animated drawing is added, and only a subset is shown at a time, as seen here.)
• `paint` could be set to null, and the Bitmap will still be drawn as usual. `paint` is useful if we plan to mask it out with another image. An example is shown in this StackOverflow.

22. `drawPicture`

If you have a combination of things to draw, and this happens multiple times, and you don’t want the processing to be slow and have to redraw them each tim, you could put your entire drawing into `Picture`.

Below is a simple example where we store our drawing into a `Picture`:

`private val picture by lazy {    val picture = Picture()    val pCanvas = picture.beginRecording(width, height)    pCanvas.drawBitmap(bitmap, null, rect, null)    picture.endRecording()    picture}`

When needed, just perform this:

`canvas.drawPicture(picture)`

This would speed up your entire process of drawing for things that need to be drawn over and over again.

23. `drawBitmapMesh`

This is to manipulate the bitmap image drawn. Given an image, we could set coordinates within the image, and translate a point to another position, hence transforming the image of it.

E.g. the below image with the center X, Y is shown in the white line cross-section.

However, using `drawBitmapMesh`, we could shift the coordinate and transform the image accordingly.

You can find all these code examples of Canvas drawing here.

Have fun with Android Canvas Drawing!

Written by

Written by