Canvas: canvas.clipRect()方法的作用


該方法用於裁剪畫布,也就是設置畫布的顯示區域
調用clipRect()方法后,只會顯示被裁剪的區域,之外的區域將不會顯示
該方法最后有一個參數Region.Op,表示與之前區域的區域間運算種類,如果沒有這個參數,則默認為Region.Op.INTERSECT
這幾個參數的意義為:

  • DIFFERENCE 是第一次不同於第二次的部分顯示出來
  • REPLACE  是顯示第二次的
  • REVERSE_DIFFERENCE 是第二次不同於第一次的部分顯示
  • INTERSECT  交集顯示
  • UNION 全部顯示
  • XOR補集 就是全集的減去交集生育部分顯示

下面以一個例子說明:

Layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".CanvasSaveAndRestore">

  
    <com.yongdaimi.android.androidapitest.view.CanvasClipView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

</LinearLayout>

自定義View:

package com.yongdaimi.android.androidapitest.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Region;
import android.util.AttributeSet;

import androidx.annotation.Nullable;

public class CanvasClipView extends android.view.View {


    public CanvasClipView(Context context) {
        this(context, null);
    }

    public CanvasClipView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CanvasClipView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private Paint mPaint;

    private void init() {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(Color.BLACK);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.drawColor(Color.GRAY); canvas.drawRect(400, 400, 600, 600, mPaint);

        canvas.drawRect(400, 700, 600, 900, mPaint);


        canvas.clipRect(100, 100, 350, 600, Region.Op.INTERSECT);
        canvas.drawColor(Color.RED);

        canvas.drawCircle(100, 100, 100, mPaint);

    }

}

上面先將畫布顏色設置成灰色,然后分別在(400, 400, 600, 600) 和 (400, 700, 600, 900)的位置繪制了兩個矩形,緊接着對畫布進行裁剪,裁剪區域為(100, 100, 350, 600), 裁剪完畢后重新設置畫布顏色為紅色,最后繪制了一個圓形,圓心坐標是(100, 100), 半徑是100,最終效果如下:

我們在布局文件里面設置的View的尺寸是鋪滿全屏,可以看到雖然對畫布進行裁剪,但是之前繪制的形狀依舊可以顯示;畫布裁剪完畢后,再去繪制圓,但圓心的坐標卻仍然以最開始的坐標為准。

下面對繪制的Code進行修改:

package com.yongdaimi.android.androidapitest.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Region;
import android.util.AttributeSet;

import androidx.annotation.Nullable;

public class CanvasClipView extends android.view.View {


    public CanvasClipView(Context context) {
        this(context, null);
    }

    public CanvasClipView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CanvasClipView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private Paint mPaint;

    private void init() {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(Color.BLACK);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.drawColor(Color.GRAY);

        canvas.drawRect(400, 400, 600, 600, mPaint);

        // 注釋掉此段code
        // canvas.drawRect(400, 700, 600, 900, mPaint);

        canvas.clipRect(100, 100, 350, 600, Region.Op.INTERSECT);
        canvas.drawColor(Color.RED);

        canvas.drawCircle(100, 100, 100, mPaint);

        // 將繪制第二個矩形的code移動到此處
        canvas.drawRect(400, 700, 600, 900, mPaint);
    }

}

再次運行:

發現最后繪制的那個矩形看不到了,說明調用clipRect()方法后,顯示區域已經被修改成(100, 100, 350, 600)了,在這個區域其它位置繪制的形狀就再也看不到了。

綜上:

1. 調用clipRect()方法后,畫布只會顯示傳入的矩形參數所在的區域,在此之后繪制的其它形狀如果不在這個區域內,將不會顯示。

2. clipRect() 只會影響在調用此方法之后繪制的形狀,先前繪制的形狀不會受到影響。

 

參考鏈接:

https://blog.csdn.net/lovexieyuan520/article/details/50698320

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM