自定義View之Region區域

Region在Android的繪製中是區域的意思,使用Region可以對圖形進行很多操作,比如區域的合併,取交集、或抑或等等。

Region的構造函數有以下四個:

public Region()  //無參構造
public Region(Region region) //傳入指定一個區域
public Region(Rect r)  //傳入一個矩形
public Region(int left, int top, int right, int bottom) //傳入兩個點,其實就是一個矩形

方法二就是傳入一個Region指定區域,方法三四都是一個意思,就是傳入一個矩形。方法一是無參構造,Region是可以後期指定代表區域的,以下是後期指定代表區域的方法:

public void setEmpty()  //清空
public boolean set(Region region)   
public boolean set(Rect r)   
public boolean set(int left, int top, int right, int bottom)   
public boolean setPath(Path path, Region clip)//將path和clip的兩個區域取交集

以上的set方法都是指定新的區域來代替Region對象中原有的區域。

還有以上的方法在繪製圖像過程中,cavas沒有直接繪製Region的方法,要繪製指定的Region需要使用RegionIterator,RegionIterator是一個迭代器,其主要作用是從指定的Region中獲取rect,也就是矩形。

1、SetPath()

public boolean setPath(Path path, Region clip)//將path和clip的兩個區域取交集

如註釋,該方法的作用是將path區域和clip區域取交集。接下來演示一下:

public class RegionView extends View {
    private Paint mPaint;

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

    public RegionView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RegionView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initPaint();
    }

    private void initPaint() {
        mPaint = new Paint();
        mPaint.setColor(Color.GREEN);
        mPaint.setStrokeWidth(3);
        mPaint.setStyle(Paint.Style.STROKE);
    }

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

        //畫一個圓
        Path path = new Path();
        path.addCircle(500, 500, 300, Path.Direction.CW);

        //指定一個區域,然後取與圓的交集
        Region region = new Region();
        region.setPath(path, new Region(0, 0, 1000, 1000));

        //繪製交集區域
        RegionIterator iterator = new RegionIterator(region);
        Rect rect = new Rect();
        while (iterator.next(rect)) {
            canvas.drawRect(rect, mPaint);
        }


    }

}

上面代碼可以看到,ReginIterator類是依次取出構成區域大小不同的矩形,然後由cavas繪製,從而組成一個圖形,下面看結果:
在這裏插入圖片描述

從圖中可以看出,圓形是由若干個矩形組成,依次排列成圓形,因爲代碼中畫筆使用的風格是STROKE(描邊),所以中間一些就是空的。如果使用Fill(填充),那麼組成的就是一個實心圓。

2、區域的操作

public final boolean union(Rect r)   
public boolean op(Rect r, Op op) {  
public boolean op(int left, int top, int right, int bottom, Op op)   
public boolean op(Region region, Op op)   
public boolean op(Rect rect, Region region, Op op) 

區域的操作有很多種,上面第一種union()主要是取並集,後面的op()方法就是operation,操作的意思,具體如何操作?還要看後面的op參數來決定。Op是一個枚舉類,具體取值如下:

  public enum Op {
        DIFFERENCE(0), //取補集
        INTERSECT(1),	//取交集
        UNION(2),	//取並集
        XOR(3),		//取異並集
        REVERSE_DIFFERENCE(4),	//取反轉補集
        REPLACE(5);		//取後者區域代替前者

        Op(int nativeInt) {
            this.nativeInt = nativeInt;
        }

        /**
         * @hide
         */
        public final int nativeInt;
    }

代碼示例如下:

public class RegionView extends View {
    private Paint mPaint;

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

    public RegionView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RegionView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initPaint();
    }

    private void initPaint() {
        mPaint = new Paint();
        mPaint.setColor(Color.GREEN);
        mPaint.setStrokeWidth(3);
        mPaint.setStyle(Paint.Style.STROKE);
    }

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

        Path path1 = new Path();
        Path path2 = new Path();
        path1.addCircle(500, 500, 300, Path.Direction.CW);
        path2.addCircle(500, 800, 300, Path.Direction.CW);

        canvas.drawPath(path1, mPaint);
        canvas.drawPath(path2, mPaint);

        Region region1 = new Region();
        Region region2 = new Region();
        region1.setPath(path1, new Region(0, 0, 1500, 1500));
        region2.setPath(path2, new Region(0, 0, 1500, 1500));

        region1.op(region2, Region.Op.REPLACE);

        mPaint.setColor(Color.GREEN);
        mPaint.setStyle(Paint.Style.FILL);
        RegionIterator iterator = new RegionIterator(region1);
        Rect rect = new Rect();
        while (iterator.next(rect)) {
            canvas.drawRect(rect, mPaint);
        }


    }

}

各結果如下:

在這裏插入圖片描述

關注個人公衆號「Android 零零柒」,回覆:Android基礎,即可獲取Android入門資料,公衆號主推Android技術,金融經濟,認知和知識等文章
在這裏插入圖片描述

參考資料:
https://blog.csdn.net/cquwentao/article/details/51365099

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章