Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

The Canvas class holds the “draw” calls. To draw something, you need 4 basic components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect, Path, text, Bitmap), and a paint (to describe the colors and styles for the drawing).

Canvas has the right to draw. To complete the drawing, it needs four basic elements:

  • Saves a Bitmap of pixels
  • A canvas that can call the draw method
  • Description of the content to draw
  • A brush.

With these four elements you can draw onto a bitmap and render it to the screen.

1. Initialization method

// Construct an empty canvas, and then use setBitmap to set a bitmap for the canvas, specify the canvas to draw on, the final thing is drawn on the bitmap public canvas ();

// All canvas states like Layer,filters and save/restore stacks will be reset. Public void setBitmap(@nullable bitmap bitmap)

Canvas public Canvas(@nonnull bitmap bitmap);

How to use it, if you want to use it directly, you can rewrite view’s onDraw method directly, you can get canvas.

2. The Save function

/**
 * Saves the current matrix and clip onto a private stack.
 * <p>
 * Subsequent calls to translate,scale,rotate,skew,concat or clipRect,
 * clipPath will all operate as usual, but when the balancing call to
 * restore() is made, those calls will be forgotten, and the settings that
 * existed before the save() will be reinstated.
 *
 * @return The value to pass to restoreToCount() to balance this save()
 */
public int save(a)
Copy the code
  • The Save function saves the matrix and Clip information of the current canvas into the stack.
  • After the save call translate, scale, rotate, skew, concat or clipRect, clipPath will apply to the Canvas
  • These operations are forgotten when the restore function is called, restoring the canvas state before save.

3.saveLayer

/**
     * This behaves the same as save(), but in addition it allocates and
     * redirects drawing to an offscreen bitmap.
     * <p class="note"><strong>Note:</strong> this method is very expensive,
     * incurring more than double rendering cost for contained content. Avoid
     * using this method, especially if the bounds provided are large. It is
     * recommended to use a {@linkandroid.view.View#LAYER_TYPE_HARDWARE hardware layer} on a View * to apply an xfermode, color filter, or alpha, as it will perform much * better than this method. * <p> * All drawing calls are directed to a newly allocated offscreen  bitmap. * Only when the balancing call to restore() is made, is that offscreen * buffer drawn back to the current target of the Canvas (either the * screen, it's target Bitmap, or the previous layer). * <p> * / public int saveLayer(@Nullable RectF bounds, 
@Nullable Paint paint, @Saveflags int saveFlags)
Copy the code

The saveLayer function acts like the save function, except that calling saveLayer allocates and generates an off-screen bitmap (meaning not on the original bitmap), and all subsequent operations are performed on the new offscreen bitmap. Savelayer This is a very performance-intensive approach, resulting in a rendering that uses twice as many resources to draw the same content. Disable this method when the desired shape is large (hyperscreen). When applying an XferMode, Color Filter or Alpha is recommended to use hardware acceleration for better performance.

3.1 Summary

Everything is drawn on the bitmap. Canvas is a virtual concept, which is connected to a bitmap. Everything is drawn on the bitmap, and every time drawxx function is called, a transparent layer is generated. A Canvas can be much larger than the screen, but the image beyond the screen will not be displayed and we will not see it.

3.2 SaveLayer refers to layers. What is layer?

The Canvas setBitmap function has a comment: Specify a bitmap for the canvas to draw into. All canvas state such as layers, filters, and the save/restore stack are reset. When setBitmap is called, a bitmap is connected to the Canvas, and all canvas states are similar to layers. The filters and save/ Restore stacks are reset. Therefore, layer is a state of canvas and can be saved. It can carry information such as clip, matrix, graph, color and so on. Therefore, each call to draw method will generate a new layer layer. The layer generated by calling Draw ends up overlaying the bitmap to which it is attached. After calling restore() and resoreToCount(), it will revert to the original bitmap corresponding to the Canvas for drawing.

We have an understanding of the bitmap corresponding to layer and canvas. Bitmap can be regarded as the canvas we usually say, and the final things are drawn on it. Each call to drawXXX method will generate a new transparent layer, and the things are drawn on the layer. It will then eventually be drawn on a Bitmap.

Calling savelayer will generate a new Bitmap, so I think calling Savelayer will generate a new Canvas to connect to a new Bitmap (or change the reference point of the original Canvas’s Bitmap), and then calling drawXX will also generate a new layer. The layer will be drawn to the newly generated Bitmap, and all the rotate, clip and other operations will be applied to the new Canvas (or the newly pointed Bitmap) and will not affect the original Canvas (the original Bitmap) until restore is called. It will be drawn to the bitmap of the original Canvas connection. Therefore, Canvas is a class containing various states (clip, matrix, etc.), which is similar to coordinate system (specifying the position of drawing graph). All operations will not affect the graph already drawn on it, but will connect to a Bitmap, and everything will be drawn on the Bitmap eventually.