Android 开发之自定义控件开发-03之Region

本文详细解析了Android中Region类的使用方法,包括直接和间接构造方式,如何利用RegionIterator进行图形绘制,以及如何进行区域相交、并集等复杂操作。通过实例展示了如何使用setPath构造不规则区域,以及union()和其他操作函数的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Region 翻译为“区域”,区域是一块任意形状的封闭图形
Region 构造:
1.直接构造

public Region(Region region) // 复制一个Region 的范围
public Region(Rect r)            //创建一个矩形区域
public Region(int left,int top,int right,int bottom) //创建一个矩形区域

第一个构造函数通过其他Region复制一个一样的Region变量
第二、三个构造函数是我们常用的,根据一个矩形或矩形的左上角和右下角点构造出一个矩形区域


    void initView(){
        paint=new Paint();
        paint.setColor(Color.RED);
        paint.setStyle(Paint.Style.FILL);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Region region = new Region(new Rect(50,50,200,100));
        drawRegion(canvas,region,paint);
    }

上面的例子中我们构造出一个矩形Region 对象,Canvas中是没有直接画Region 的方法的,所以我们先要画出来Region 就要通过RegionIterator类来实现绘制,RegionIterator类看名字能看出来,是一个迭代器,它的作用主要是从指定的Region中获取rect,也就是矩形。
意思是:任意指定Region的图形,都可以由若干个细分的矩形组成

/**
     * 通过迭代器来绘制
     * @param canvas
     * @param region
     * @param paint
     */
    private  void drawRegion(Canvas canvas,Region region,Paint paint){
        RegionIterator iterator = new RegionIterator(region);
        Rect rect = new Rect();
        while (iterator.next(rect)) {
            canvas.drawRect(rect, paint);
        }
    }

新歌

从上面可以看出Canvas 并没有提供针对 Region的绘制方法,也就是说明Region并不是用来绘图的,上面的矩形填充,我们可以使用Rect代替

 canvas.drawRect(new Rect(50,50,200,100), paint);

效果是一样的。

2.间接构造
间接构造主要是通过public Region ()空构造函数与set系列函数相结合来实现的
Region 空构造函数

public Region  ()

set函数

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   region)

当我们调用set系列函数的Region 是不是区域值,当调用set系列的函数后,原来的区域值都会被替换成set系列函数里的区域值。

set系列函数的含义:

setEmpty() //某种意义上讲,置空也是一个构造函数,将原来一个区域的变量变成空变量,再利用其它的函数重新构造。
set(Region region) //利用新的区域替换原来的区域。
set(Rect   r) //利用矩形的区域替换原来的区域。
set(int left,int top,int right,int bottom) // 根据矩形的两个角点构造出矩形来替换原来的区域。
setPath(Path path,Region region)  // 根据路径的区域与某个区域的交集构造出新的区域。

下面讲解一下利用setPath构造不规则区域的方法,其他的没有什么难度不做详细的讲解了
setPath参数:

  • Path path 用来构造区域的路径
  • Region region 与前面的path所构成的路径取交集,并将该交集设置为最终的区域。
@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
       //构造一个椭圆路径
        Path ellipsePath = new Path();
        RectF rect = new RectF(50, 50, 200, 500);
        ellipsePath.addOval(rect,Path.Direction.CCW);
        Region region = new Region();
        region.setPath(ellipsePath,new Region(50,50,200,200));
        drawRegion(canvas,region,paint);
    }

    /**
     * 通过迭代器来绘制
     * @param canvas
     * @param region
     * @param paint
     */
    private  void drawRegion(Canvas canvas,Region region,Paint paint){
        RegionIterator iterator = new RegionIterator(region);
        Rect rect = new Rect();
        while (iterator.next(rect)) {
            canvas.drawRect(rect, paint);
        }
    }

上面我们绘制除了一个椭圆和一个矩形相交,我们去相交的部分:
在这里插入图片描述

区域相交
既然Region 不是用来绘图的,Region 作重要的功能在区域相交操作
1.union() 函数
用于与指定函数取交集

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
       //构造一个椭圆路径
        
        Region region = new Region(10,10,200,100);
        region.union(new Rect(10,10,50,300));
        drawRegion(canvas,region,paint);
    }

    /**
     * 通过迭代器来绘制
     * @param canvas
     * @param region
     * @param paint
     */
    private  void drawRegion(Canvas canvas,Region region,Paint paint){
        RegionIterator iterator = new RegionIterator(region);
        Rect rect = new Rect();
        while (iterator.next(rect)) {
            canvas.drawRect(rect, paint);
        }
    }

我们先横向、竖向分别画两个矩形区域,然后利用union()函数将两个矩形区域合并:
在这里插入图片描述

2.区域操作
除了union()函数 Region 还提供了几个更加灵活的操作函数:

boolean op(Rect r,Op op)
boolean op(int left,int top,int rigth,int bottom,Op op)
boolean op(Region  region ,Op op)

上面的函数用当前的Region 对象与指定的一个Rect对象或Region 对象执行相交操作,并将结果赋值给当前的Region 对象,计算成功返回true否则返回false。
其中最重要的是指操作类型的Op参数,Op参数值有如下6个:

public enum Op{
		DIFFERENCE(0),   // 最终区域为region1与region2 不同的区域    
		INTERSECT(1),     // 最终区域为region1与region2 相交的区域
		UNION(2),             //  最终区域为region1与region2 组合在一起的区域
		XOR(3),                 // 最终区域为region1与region2 相交之外的区域
		REVERSE_DIFFERENCE(4),   // 最终区域为region1与region2 不同的区域
		REPLACE(5);    //  // 最终区域为region2 的区域
}

下面做一些栗子:

 void initView(){
        //构造一个画笔
        paint=new Paint();
        paint.setColor(Color.RED);
        paint.setStyle(Paint.Style.FILL);
        paint.setStrokeWidth(2);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
       //构造构造两个矩形
        Rect rect1 = new Rect(100, 100, 400, 200);
        Rect rect2 = new Rect(200, 0, 300, 300);
        canvas.drawRect(rect1,paint);
        canvas.drawRect(rect2,paint);
    }

在这里插入图片描述
然后利用上面的rect1 和rect2来构造Region 并在rect1 的基础上取与rect2 的交集。.

   Region region1 = new Region(rect1);
        Region region2 = new Region(rect2);
        //取两个区域的交集
        region1.op(region2, Region.Op.INTERSECT);

构造另外一个填充的画笔

  paint2=new Paint();
        paint2.setColor(Color.YELLOW);
        paint2.setStyle(Paint.Style.FILL);
        paint2.setStrokeWidth(2);
          //交集的地方设置为黄色
        drawRegion(canvas,region1,paint2);

在这里插入图片描述

        //取两个区域的补集
        region1.op(region2, Region.Op.DIFFERENCE);

在这里插入图片描述

        //取两个区域的替换
        region1.op(region2, Region.Op.REPLACE);

在这里插入图片描述

        //取两个区域的反转补集
        region1.op(region2, Region.Op.REVERSE_DIFFERENCE);

在这里插入图片描述

          //取两个区域的反转并集
        region1.op(region2, Region.Op.UNION);

在这里插入图片描述

         //取两个区域的并集
        region1.op(region2, Region.Op.XOR);

在这里插入图片描述

还有两个方法:

boolean op(Rect rect,Region region, Op op  )
boolean op(Region region1,Region region2, Op op  )

这两个函数允许我们传入两个Region 对象进行区域操作,并将操作结果赋值给当前的Region 对象。同样当操作成功返回true,否则返回false。

 Region region01 = new Region(100,100,400,200);
        Region region02 = new Region(200,0,300,300);
        Region region = new Region();
        region.op(region01,region02, Region.Op.INTERSECT);

这里是将region01、region02相交的结果赋值给 Region 对象。

Region 的介绍就到这里了。


明天就过元旦的假期了,祝大家节日快乐,心想事成,有缘人找到有情人,陪你的另一半一起跨年。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值