The
onDraw(canvas: Canvas) method is often necessary to override when
creating a custom view.
Canvas
and
Paint
are two primary objects used in the implementation of the
onDraw()
method.
The
Canvas is passed as a parameter to the
onDraw()
and is responsible for
what gets drawn. It defines the shapes that are drawn within the
onDraw()
through methods like
draw...()
. Most
draw...()
methods take a
Paint
object as a parameter.
Paint dictates
how things are drawn. It defines the color, font, style, etc., that are used when drawing a shape specified by the
Canvas
.
The
onDraw()
method is frequently called, and the speed at which this method executes affects how quickly the user interface renders. An essential rule in implementing
onDraw()
is to
avoid creating new objects within this method. This means all
Paint
objects used in
onDraw()
should be created before the method is called, such as when the view is created.
Proper rendering of a view requires considering its size. Sometimes, it is necessary to perform complex calculations of dimensions and positions based on the size of the view. As processing speed is crucial for the
onDraw()
, it is considered good practice
not to perform calculations within this method.
To handle changes in view size, the
onSizeChanged() method is overridden. This method is called when the view's size is initially set and each time the size changes, which occurs far less frequently than calls to the
onDraw()
method. The parameters of the
onSizeChanged()
method are four integers that represent the new and old values of width and height. The initial call has the old values set to zero.
The dimensions passed to
onSizeChanged()
include padding. This means that to calculate the actual size of the view's content, these paddings need to be subtracted. Padding values are retrieved using methods like
getPadding...()
.
All size calculations should be performed in
onSizeChanged()
and then used in
onDraw()
.
After defining the dimensions and positions of the view components, you proceed to drawing. Each view has a differently implemented
onDraw()
method, but there are common groups of operations on
Canvas
and
Paint
used in drawing:
- Text can be drawn using the Canvas.drawText()method, which takes the text to be drawn, coordinates for where to place it, and a
Paint
object. Paint
methods are used to set text parameters, such as setTypeface() for the font and setColor() for the color. Canvas
has methods for drawing simple geometric shapes such as drawLine(), drawOval(), and drawRect(). The Paint
object can specify whether to fill the shapes or not using the setStyle() method.- For drawing complex shapes, a Path object is used. It has methods for adding simple component shapes such as lineTo(), addOval(), and addRect(). The constructed shape is then drawn with drawPath().
- To color shapes with a gradient, the Paint.setShader() method is used, with a LinearGradient as a parameter.
Discussions on implementing the
onDraw()
method often touch on optimizations for this method and other UI-related topics.
Avoid performing calculations and creating objects in the
onDraw()
. Creating new objects can trigger garbage collection, leading to
Stop the World pauses and user interface lag. Create
Paint
objects during view initialization and reuse them in the
onDraw()
. Also, avoid creating objects during animations.
Another way to optimize the UI is to reduce the number of
onDraw()
calls. Most of them are caused by the execution of
invalidate(), so try to avoid frequently calling this method.
Another costly operation is traversing the view hierarchy. During the execution of
requestLayout(), the system goes through the entire hierarchy to determine the dimensions of each view. For some layouts, this traversal is performed multiple times, which can cause performance issues.
To create a smooth UI, it's necessary to reduce view nesting as much as possible. Try to create custom flat views instead of using several nested standard layouts. For non-universal views, it's easier to calculate dimensions based on their specific use in the application.