Canvas: How to draw text in Jetpack Compose?

Canvas: How to draw text in Jetpack Compose?

In this blog, learn how to drawText in your Canvas in jetpack compose. Also learn how to draw different shapes and the basics of canvas.

I am writing after ages and it seems the world has taken a huge leap in Jetpack Compose where Compose needs no introduction in the Android ecosystem.

With Compose, designing UI has become easy and fun. You can create almost anything using out of the box solution in compose. But as engineers, sometimes you get a design that has to be drawn and designs that are not present in Compose UI kit. Here, comes the use of Canvas and its features.

Canvas is like an art book for developers where we can create our expected masterpiece.

Canvas in Android lets us create a custom shape, fill colors to them and create crazy stuff. But when it comes to drawing a text in compose's canvas, you don't have an out-of-the-box solution to draw a text.

Enough of theory, let us see how can you drawText using Jetpack Compose's canvas. In this blog, you will see,

  • Basic intro to Canvas.
  • How to draw different shapes on Canvas using Compose?
  • How to draw text in Canvas?

Intro to Canvas

Canvas in Android devices is nothing but your screen. Anything that you want to show a user in your device is basically you are showing it in canvas.

So, basically, a phone's screen real-estate is the canvas for a developer to paint its masterpiece.

Canvas works in the co-ordinate system, like how you had back in your school days. X-Axis and Y-Axis.

Canvas in mobile looks like,

canvas-image.png

How to draw different shapes on Canvas using Compose?

It is very straightforward to draw on the Canvas of your phone using Compose.

To draw in canvas you need to create Canvas composable, that takes Modifier as a parameter and onDraw is the lambda inside which you are going to draw your shapes.

It looks like,

@Composable
fun CanvasDemo() {
    Canvas(modifier = Modifier, onDraw = {})
}

Now, from here onwards whatever you draw will be in onDraw function as it has the DrawScope. Let us see few small basic shapes that can be drawn.

1. Line


drawLine(
                color = Color.Blue,
                start = Offset.Zero,
                end = Offset(size.width, size.height),
                strokeWidth = 10f
            )

Here, inside onDraw, you can call drawLine directly to draw line from (0,0) i.e Offset.Zero and (x,y). You can see the reference above in the image. Here, Offset takes co-ordinates of point to draw a line.

Size here gives us the dimensions of the canvas The output of the above line is,

Screenshot 2022-01-06 at 01.13.30.png

2. Circle


drawCircle(
                color = Color.Blue,
                center = Offset(size.width / 2, size.height / 2),
            )

Here, inside onDraw, you can call drawCircle with color and center. By default the center is the center of screen but here you have passed on the explicit one which is also the center of the screen.

The output looks like,

Screenshot 2022-01-06 at 01.12.54.png

In similar way, you can draw arc, path, rectangle etc. This is just a refresher how you can draw shapes in Canvas.

How to draw text in Canvas?

Now, here comes the best part. Like the way how you can create different shapes in compose's canvas you can't draw text in it.

But, it was easily possible in Android's XML View system where you had a function called drawText and using that you could draw any text you want.

To do the same in this ecosystem, you will be utilising the same but in different way.

 drawContext.canvas.nativeCanvas.apply {
                drawText(
                    "Hey, Himanshu",
                    size.width / 2,
                    size.height / 2,
                    Paint().apply {
                        textSize = 100
                        color = Color.BLUE
                        textAlign = Paint.Align.CENTER
                    }
                )
            }

Here,

  • drawContext is responsible to have all the dependency you need to create your drawing.
  • canvas gives access to the canvas you want to draw into.
  • nativeCanvas gives the instance of the native Canvas interface.

Since, you can access the canvas directly you can now use it's drawText method with the Paint object and using it you can create your expected design.

The output looks like,

Screenshot 2022-01-06 at 01.10.20.png

PS: You can also use drawIntoCanvas in place of drawContext.canvas and it will work fine.

This is how you can drawText in your canvas using Jetpack Compose.

Let's keep in touch. Follow me here .

Did you find this article valuable?

Support Himanshu Singh by becoming a sponsor. Any amount is appreciated!