自定义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基础入门学习资料。
在这里插入图片描述

参考资料:
https://blog.csdn.net/cquwentao/article/details/51365099

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值