Region,中文意思即区域的意思,它表示的是canvas图层上的某一块封闭的区域。
Region 常用Api
1、基本构造函数
构造函数只能传入矩形 或者region
public Region() //创建一个空的区域
public Region(Region region) //拷贝一个region的范围
public Region(Rect r) //创建一个矩形的区域
public Region(int left, int top, int right, int bottom) //创建一个矩形的区域
2、间接构造
只能为region 设置矩形或者其他的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)//后面单独讲
这是Region所具有的一系列Set方法,我这里全部列了出来,下面一一对其讲解:
注意:无论调用Set系列函数的Region是不是有区域值,当调用Set系列函数后,原来的区域值就会被替换成Set函数里的区域。
- SetEmpty():从某种意义上讲置空也是一个构造函数,即将原来的一个区域变量变成了一个空变量,要再利用其它的Set方法重新构造区域。
- set(Region region):利用新的区域值来替换原来的区域
- set(Rect r):利用矩形所代表的区域替换原来的区域
- set(int left, int top, int right, int bottom):同样,根据矩形的两个点构造出矩形区域来替换原来的区域值
- setPath(Path path, Region clip):根据路径的区域与某区域的交集,构造出新区域,这个后面具体讲解
3、矩形集枚举区域——RegionIterator类
对于特定的区域,我们都可以使用多个矩形来表示其大致形状。事实上,如果矩形足够小,一定数量的矩形就能够精确表示区域的形状,也就是说,一定数量的矩形所合成的形状,也可以代表区域的形状。RegionIterator类,实现了获取组成区域的矩形集的功能,其实RegionIterator类非常简单,总共就两个函数,一个构造函数和一个获取下一个矩形的函数;
RegionIterator(Region region) //根据区域构建对应的矩形集
boolean next(Rect r) //获取下一个矩形,结果保存在参数Rect r 中
由于在Canvas中没有直接绘制Region的函数,我们想要绘制一个区域,就只能通过利用RegionIterator构造矩形集来逼近的显示区域。用法如下:
// 用矩形画椭圆
public void drawOvalUseRect(Canvas canvas){
// 2.0 区域由很多矩形构成
//初始化Paint
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
//构造一个椭圆路径
Path ovalPath = new Path();
RectF rect = new RectF(50, 50, 200, 500);
ovalPath.addOval(rect, Path.Direction.CCW);
//SetPath时,传入一个比椭圆区域小的矩形区域,让其取交集
Region rgn = new Region();
rgn.setPath(ovalPath,new Region(50, 50, 200, 500));
//画出路径
drawRegion(canvas, rgn, paint);
}
private void drawRegion(Canvas canvas,Region rgn,Paint paint)
{
RegionIterator iter = new RegionIterator(rgn);
Rect r = new Rect();
while (iter.next(r)) {
canvas.drawRect(r, paint);
}
}
上面我们也都看到了它的用法,首先,根据区域构建一个矩形集,然后利用next(Rect r)来逐个获取所有矩形,绘制出来,最终得到的就是整个区域,如果我们将上面的画笔Style从FILL改为STROKE,重新绘制椭圆路径,会看得更清楚。
4、使用SetPath()构造不规则区域
boolean setPath (Path path, Region clip)
参数说明:Path path:用来构造的区域的路径
Region clip:与前面的path所构成的路径取交集,并将两交集设置为最终的区域
由于路径有很多种构造方法,而且可以轻意构造出非矩形的路径,这就摆脱了前面的构造函数只能构造矩形区域的限制。但这里有个问题是要指定另一个区域来取共同的交集,当然如果想显示路径构造的区域,Region clip参数可以传一个比Path范围大的多的区域,取完交集之后,当然是Path参数所对应的区域喽。机智的孩子。
下面,先构造一个椭圆路径,然后在SetPath时,传进去一个比Path小的矩形区域,让它们两个取交集
public class MyRegionView extends View {
public MyRegionView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
//初始化Paint
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStyle(Style.FILL);
paint.setStrokeWidth(2);
//构造一个椭圆路径
Path ovalPath = new Path();
RectF rect = new RectF(50, 50, 200, 500);
ovalPath.addOval(rect, Direction.CCW);
//SetPath时,传入一个比椭圆区域小的矩形区域,让其取交集
Region rgn = new Region();
rgn.setPath(ovalPath,new Region(50, 50, 200, 200));
//画出路径
drawRegion(canvas, rgn, paint);
}
//把图形分成矩形,逐个显示
private void drawRegion(Canvas canvas,Region rgn,Paint paint)
{
RegionIterator iter = new RegionIterator(rgn);
Rect r = new Rect();
while (iter.next(r)) {
canvas.drawRect(r, paint);
}
}
}
5、区域的合并、交叉等操作
无论是区域还是矩形,都会涉及到与另一个区域的一些操作,比如取交集、取并集等,涉及到的函数有:
- 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(Rect r)是指定合并操作以外,其它四个op()构造函数,都是指定与另一个区域的操作。其中最重要的指定Op的参数,Op的参数有下面四个:
假设用region1 去组合region2
public enum Op {
DIFFERENCE(0), //最终区域为region1 与 region2不同的区域
INTERSECT(1), // 最终区域为region1 与 region2相交的区域
UNION(2), //最终区域为region1 与 region2组合一起的区域
XOR(3), //最终区域为region1 与 region2相交之外的区域
REVERSE_DIFFERENCE(4), //最终区域为region2 与 region1不同的区域
REPLACE(5); //最终区域为为region2的区域
}
两个Region 的组合
@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);
//构造一个画笔,画出矩形轮廓
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(2);
canvas.drawRect(rect1, paint);
canvas.drawRect(rect2, paint);
//构造两个Region
Region region = new Region(rect1);
Region region2= new Region(rect2);
//取两个区域的交集
region.op(region2, Op.INTERSECT);
//再构造一个画笔,填充Region操作结果
Paint paint_fill = new Paint();
paint_fill.setColor(Color.GREEN);
paint_fill.setStyle(Style.FILL);
drawRegion(canvas, region, paint_fill);
}
private void drawRegion(Canvas canvas,Region rgn,Paint paint)
{
RegionIterator iter = new RegionIterator(rgn);
Rect r = new Rect();
while (iter.next(r)) {
canvas.drawRect(r, paint);
}
}
6、常用方法
/**几个判断方法*/
public native boolean isEmpty();//判断该区域是否为空
public native boolean isRect(); //是否是一个矩阵
public native boolean isComplex();//是否是多个矩阵组合
/**一系列的getBound方法,返回一个Region的边界*/
public Rect getBounds()
public boolean getBounds(Rect r)
public Path getBoundaryPath()
public boolean getBoundaryPath(Path path)
/**一系列的判断是否包含某点 和是否相交*/
public native boolean contains(int x, int y);//是否包含某点
public boolean quickContains(Rect r) //是否包含某矩形
public native boolean quickContains(int left, int top, int right,
int bottom) //是否没有包含某矩阵形
public boolean quickReject(Rect r) //是否没和该矩形相交
public native boolean quickReject(int left, int top, int right, int bottom); //是否没和该矩形相交
public native boolean quickReject(Region rgn); //是否没和该矩形相交
/**几个平移变换的方法*/
public void translate(int dx, int dy)
public native void translate(int dx, int dy, Region dst);
public void scale(float scale) //hide
public native void scale(float scale, Region dst);//hide