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 的介绍就到这里了。