I need to build my own custom TextView
so I have been learning about StaticLayout
to draw text on a canvas. This is preferable to using Canvas.drawText()
directly, or so the documentation says. However, the documentation doesn't give any examples for how do it. There is only a vague reference to StaticLayout.Builder
being the newer way to do it.
I found an example here but it seems a little dated.
I finally worked though how to do it so I am adding my explanation below.
StaticLayout
(similar toDynamicLayout
andBoringLayout
) is used to layout and draw text on a canvas. It is commonly used for the following tasks:TextView
).TextView
itself uses aStaticLayout
internally.Measuring text size
Single line
If you only have a single line of text, you can measure it with
Paint
orTextPaint
.Multiline
However, if there is line wrapping and you need the height, then it is better to use a
StaticLayout
. You provide the width and then you can get the height from theStaticLayout
.New API
If you want to use the newer
StaticLayout.Builder
(available from API 23), you can get your layout like this:You can tack on addition settings using dot notation:
Writing text on an image
I may expand this more in the future, but for now see this post for an example of a method that uses
StaticLayout
and returns a bitmap.Making a custom text handling View
Here is an example of a custom view using a
StaticLayout
. It behaves like a simpleTextView
. When the text is too long to fit on the screen, it automatically line wraps and increases its height.Code
MyView.java
activity_main.xml
Notes
This, this, and this were useful in learning how to make a custom text handling view.
See Creating a View Class if you would like to add custom attributes that can be set from code or xml.
Here is my explanation for drawing multiline text on canvas.
Declare Paint object. Use TextPaint which is an extension of Paint.
Initialize Paint object. Set your own color, size etc.
Add getTextHeight function
in your onDraw function put following lines like this
Courtesy goes to KOC's post