1. 程式人生 > >自定義View畫布save()和restore()

自定義View畫布save()和restore()

遇到這兩個防法正好記錄一下,有一個簡單的例子,畫一個鐘錶的刻度盤,首先畫圓,然後通過旋轉畫布畫刻度,下面主要程式碼:

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        /**
         * 畫圓
         */
        canvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 2, mPaint);
        /**
         * 畫12點位置
         */
        canvas.drawLine(mWidth / 2, mHeight / 2 - mWidth / 2, mWidth / 2, mHeight / 2 - mWidth / 2 + 50, mPaint);
        /**
         * 畫中心點
         */
        canvas.drawPoint(mWidth / 2, mHeight / 2, mPaint);
        /**
         * 旋轉畫布畫畫其他位置的刻度
         */
        for (int i = 0; i < 11; i++) {
            canvas.rotate(30, mWidth / 2, mHeight / 2);
            canvas.drawLine(mWidth / 2, mHeight / 2 - mWidth / 2, mWidth / 2, mHeight / 2 - mWidth / 2 + 50, mPaint);
        }
    }

效果圖:


那麼現在修改程式碼新增兩個放法save,和restore如下程式碼所示:

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        /**
         * 畫圓
         */
        canvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 2, mPaint);
        /**
         * 畫12點位置
         */
        canvas.drawLine(mWidth / 2, mHeight / 2 - mWidth / 2, mWidth / 2, mHeight / 2 - mWidth / 2 + 50, mPaint);
        /**
         * 畫中心點
         */
        canvas.drawPoint(mWidth / 2, mHeight / 2, mPaint);
        /**
         * 旋轉畫布畫畫其他位置的刻度
         */
        for (int i = 0; i < 11; i++) {
            canvas.save();
            canvas.rotate(30, mWidth / 2, mHeight / 2);
            canvas.restore();
            canvas.drawLine(mWidth / 2, mHeight / 2 - mWidth / 2, mWidth / 2, mHeight / 2 - mWidth / 2 + 50, mPaint);
        }
    }
效果圖如下:

總結:好了我們看到了所有的刻度都畫在12點了,為什麼,在一般情況下save放法和restore一般是成對呼叫的,save放法用於儲存當前畫布狀態,而restore放法則是回覆之前儲存的畫布的狀態,在本例中,我再旋轉畫布之前進行儲存畫布狀態,(此時儲存的畫布狀態是沒有經過旋轉的),我在旋轉之後呼叫restore恢復之前儲存的狀態,所以目前的畫布狀態仍然是沒有旋轉過的,所以所有的刻度都畫在12點位置,不知道明白了沒有,在save和restore一般進行畫布的旋轉縮放平移等操作,最後再用箭頭表示一下畫布的狀態。