The use of save and restore methods of custom View-canvas in advanced android development - high-frequency interview questions from Dachang

background:

Hi, fans and friends:
Hello everyone! In the framework mock interview event held last week, many fans were also actively discussing some issues during the interview process. For example, the question I want to explain today:
Generally, many application students will write "skilled custom view" on their resumes. This skill is basically written by many students in advanced Android application development. The easiest question for the interviewer to examine in the interview for this skill is:
Do you know that there is a save and restore method in canvas? Can you talk about your understanding of the save and restore method of this canvas?

Hahaha, are you familiar with this interview question? Let me first tell you why you need to test this question?
In fact, many advanced UIs actually require relatively complex drawing most of the time. Most of the time, they need to flexibly master drawing-related methods. Canvas is the most frequent one, and complex UIs often require rotation, translation, and other operations. This At this time, save and restore are needed.

Introduction to save and restore of Canvas

/**
 * 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() {
    
    
    return nSave(mNativeCanvasWrapper, MATRIX_SAVE_FLAG | CLIP_SAVE_FLAG);
}

You can see that the comments here are relatively clear. Save the matrix matrix and clip data of the current canvas into a stack.

Let’s take a look at the restore method:

/**
     * This call balances a previous call to save(), and is used to remove all
     * modifications to the matrix/clip state since the last save call. It is
     * an error to call restore() more times than save() was called.
     */
    public void restore() {
    
    
        if (!nRestore(mNativeCanvasWrapper)
                && (!sCompatibilityRestore || !isHardwareAccelerated())) {
    
    
            throw new IllegalStateException("Underflow in restore - more restores than saves");
        }
    }

The restore and save here generally correspond to each other. The previous save is to save the matrix and clip of the canvas to the stack. The restore here is to take out the top matrix and clip from the stack and apply them.
As shown in the figure below:
Insert image description here
save1, save2, and save3 here can actually be considered as matrix and clip data at a certain moment. When restoring, the save data is obtained and then applied to the canvas. Of course, the canvas will be reset before application.

To summarize the common understanding:
canvas may often need to be rotated and translated due to drawing requirements. However, the entire coordinate system changes after rotation and translation. When the next part is drawn, you may want to draw it based on the original coordinates, but they have been translated. It's rotated, how to get it back to the original position?
Do we still need to rotate and translate back one by one? Of course not, everyone would feel too stupid to do this, so the save and restore explained today appeared. Save before canvas translation and rotation, and then you can adjust restore if you want to return to the original state.

Specific application understanding of the code:

    protected void onDraw(Canvas canvas) {
    
    
        super.onDraw(canvas);
        Paint paint = new Paint();
        //第一个基于原点坐标绘制的离左边距离10
        paint.setColor(Color.RED);
        canvas.drawRect(10,10,70,30,paint);
        
        //canvas已经平移了100
        canvas.translate(100,100);
        paint.setColor(Color.YELLOW);
        
        //这时候绘制的坐标是0,但是因为平移了,所以间隔原点其实是100
        canvas.drawRect(0,10,60,30,paint);

        paint.setColor(Color.BLACK);
        
        //这时候绘制的坐标是200,但是因为平移了,所以间隔原点其实是200+100
        canvas.drawRect(200,10,320,30,paint);


    }

Insert image description here

But what if the third black block doesn’t want to follow the translational influence of the second yellow block when it is drawn? ? code show as below:

    protected void onDraw(Canvas canvas) {
    
    
        super.onDraw(canvas);
        Paint paint = new Paint();
        //第一个基于原点坐标绘制的离左边距离10
        paint.setColor(Color.RED);
        canvas.drawRect(10,10,70,30,paint);
        //平移前对canvas进行save
        canvas.save();
        
        //canvas已经平移了100
        canvas.translate(100,100);
        paint.setColor(Color.YELLOW);
        
        //这时候绘制的坐标是0,但是因为平移了,所以间隔原点其实是100
        canvas.drawRect(0,10,60,30,paint);
 				//第二个绘制完成后进行restore
        canvas.restore();
       
        paint.setColor(Color.BLACK);
        
        //这时候绘制的坐标是200,那么就是200
        canvas.drawRect(200,10,320,30,paint);


    }

The execution results are as follows:
Insert image description here

Black returns to the original coordinate system, unaffected by the second translation.

For more exciting content, step-by-step videos or follow the public account "Qianlima Learning Framework" below:
https://www.bilibili.com/video/BV1TK4y1c7Ku/

Guess you like

Origin blog.csdn.net/learnframework/article/details/133344869