Android Canvas: Basic to Advanced
Canvas Basics
Your Digital Easel
When you need to go beyond Android's standard UI components, you step into the world of custom drawing. Your primary tool is the Canvas. Think of it as a digital surface provided by the system, waiting for your instructions. You don't draw on a View directly; you draw on the Canvas that the View provides.
Android provides us with 2D drawing APIs that enable us to draw our custom drawing on the Canvas.
Every custom View's onDraw() method receives a Canvas object as a parameter. This is your gateway to creating anything from simple shapes to complex data visualizations. But before you can draw, you need to understand the lay of the land.
The Lay of the Land
The Canvas coordinate system is straightforward, but has one quirk that might trip you up if you're used to traditional Cartesian graphs. The origin point, (0,0), is at the top-left corner of the drawing area. The x-axis increases as you move to the right, which is standard. However, the y-axis increases as you move down.
Understanding this top-left origin is crucial. A circle drawn at (100, 50) will appear closer to the top of the screen than one drawn at (100, 200). Once you've oriented yourself, you need the right tools to start making marks.
The Artist's Toolkit
You can't draw on a Canvas without a Paint object. If the Canvas is your surface, the Paint is your brush, your color palette, and your style guide all in one. It holds all the stylistic information about what you're about to draw.
Canvas helps to create the skeleton and Paint helps in beautifying the design.
The Paint object dictates properties like color, line thickness, and whether a shape is filled in or just an outline. The two most fundamental style properties are FILL and STROKE.
Paint.Style.FILL: This fills the entire shape with color. If you draw a rectangle, the whole area becomes a solid block of color.Paint.Style.STROKE: This only draws the outline of the shape, using the specified stroke width. The inside of the shape remains empty.
Let's see the difference.
Beyond style, you can set other important properties on your Paint object. The color is set using an integer value, often from Android's Color class (e.g., Color.RED). You can also specify the strokeWidth for outlined shapes.
For professional-looking graphics, you'll almost always want to enable in your Paint object. This smooths out the jagged edges, or "jaggies," that can appear on curved or diagonal lines on a pixel grid. It makes your drawings look clean and polished.
A critical rule for performance is to create your Paint objects once during initialization, not inside the onDraw() method. The onDraw() method can be called frequently, and creating new objects within it leads to unnecessary memory allocation and can make your UI stutter. Create your Paint objects as member variables in your custom View class. You can always modify their properties later if needed.
// Good: Initialize Paint objects once as member variables
public class MyCustomView extends View {
private Paint circlePaint;
private Paint textPaint;
public MyCustomView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
circlePaint.setColor(Color.BLUE);
circlePaint.setStyle(Paint.Style.FILL);
textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(Color.BLACK);
textPaint.setTextSize(40f);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Bad: Don't create new objects here!
// Paint tempPaint = new Paint();
canvas.drawCircle(100f, 100f, 50f, circlePaint);
canvas.drawText("Hello", 200f, 200f, textPaint);
}
}
Drawing Basic Shapes
With your Canvas and Paint ready, you can start drawing. The Canvas class provides a set of methods for drawing primitive shapes. Each method requires coordinates and a Paint object to define the style.
Here are a few of the most common ones:
drawPoint(float x, float y, Paint paint): Draws a single point. The size of the point is controlled by thestrokeWidthon thePaintobject.drawLine(float startX, float startY, float stopX, float stopY, Paint paint): Draws a line between two points.drawRect(float left, float top, float right, float bottom, Paint paint): Draws a rectangle. The coordinates define the positions of the four edges.drawCircle(float cx, float cy, float radius, Paint paint): Draws a circle, where(cx, cy)is the center andradiusis self-explanatory.
These methods are the building blocks for all custom drawing in Android. By combining these primitives, you can construct nearly any 2D graphic you can imagine.
Now that you understand the coordinate system and how to use Paint to style basic shapes, you're ready to start putting these concepts into practice.