区域Region详解
Region类图形游戏开发中比较常用,判断点是否在指定区域内碰撞。还能在自定义View中指定区域为可点击就是使用Region完成的。首先需要明白Region表示的是Canvas图层上的某一块封闭的区域。
1、构造Region
Region有几个构造函数,或者通过方法为空的Region对象设置区域。
1.1、构造
①Region():创建一个空白区域,结合后面的方法设置该区域
②Region(Region region):从另一个region区域中复制一块相同的区域
③Region(Rect r):创建一块Rect矩形区域
④Region(int left, int top, int right, int bottom)
1.2、set方法
构造的空Region可以通过一系列的set方法设置指定区域,不过需要注意每次set都会替换掉之前Region中的区域范围。
①set(Region region):将区域设置为指定区域
②set(Rect r):将区域设置为指定的矩形
③set(int left, int top, int right, int bottom):将区域设置为指定的矩形
④setEmpty():将区域设置为空区域
⑤setPath(Path path,Region clip):将path形成的路径和clip形成的区域取交集,获得一个交集区域
/**
* 将区域设置为路径和剪辑所描述的区域。
* 如果结果区域为非空,则返回true。
* 这将产生与该路径将绘制的像素相同的区域(不带抗锯齿)。
*
* @param path 用来构造区域的路径
* @param clip 第一个参数path所构成的路径取交集,并将该交集设为最终区域。
*/
public boolean setPath(@NonNull Path path, @NonNull Region clip) {
return nativeSetPath(mNativeRegion, path.readOnlyNI(), clip.mNativeRegion);
}
2、Region方法
介绍Region类的常用方法。包括Region之间的相互op操作、获取
2.1、union/op运算
①op(Region region, Op op):在此区域和指定区域region上执行指定的Op
②op(Rect r, Op op):在此区域和指定区域Rect执行指定的Op
③op(int left, int top, int right, int bottom, Op op)
④op(Rect rect, Region region, Op op)
⑤op(Region region1, Region region2,Op op)
⑥union(Rect r):当前区域和指定矩形取并集,将Rect区域加入到当前区域中。
2.2、getBound
获取区域Region的矩形位置,有多个重载方法,除了参数有区别,返回值也有区别。
①Rect getBounds():返回一个新的Rect集到区域的边界。 如果该区域为空,则Rect将设置为[0,0,0,0]
②boolean getBounds(Rect r):将矩形r设置为该区域的边界。 如果该区域为空,则剩余部分将设置为[0,0,0,0]
③Path getBoundaryPath():将区域的边界作为新路径返回。 如果该区域为空,则路径也将为空。
④boolean getBoundaryPath(@NonNull Path path):将路径path设置为区域的边界。 如果该区域为empty,则路径也将为empty。
2.3、contains
①contains(int x, int y):判断一个点(x,y)是否在某个区域内
②quickContains(Rect r):如果区域是单个矩形(不复杂)并且包含指定的矩形,则返回true。 返回false不能保证该区域不包含该矩形的部分,但是返回true可以保证该区域包含该矩形。
③quickContains(int left, int top, int right,int bottom)
2.4、is方法
Region类中还有三个is判断方法,这三个方法都是Native方法。
①isComplex():如果区域包含多个矩形,则返回true
②isRect():如果区域包含单个矩形,则返回true
③isEmpty():如果该区域为空,则返回true
3、Op操作
前面介绍的方法中有提到Region.Op类型,这个是定义在Region类中的枚举,定义了各种运算逻辑,现在来结合实例了解其中的实际含义。
3.1、Op枚举
操作符定义在Region类内部的枚举Op
// the native values for these must match up with the enum in SkRegion.h
public enum Op {
DIFFERENCE(0), //补集
INTERSECT(1), //交集
UNION(2), //并集
XOR(3), //异并集
REVERSE_DIFFERENCE(4),//反转补集
REPLACE(5); //替换
}
3.2、示例
①DIFFERENCE 补集

②INTERSECT 交集

③UNION 并集

④XOR 异并集

⑤REVERSE_DIFFERENCE 反转补集

⑥REPLACE 替换

例:
//构造两个矩形Rect
Rect rect1 = new Rect(100, 100, 400, 200);
Rect rect2 = new Rect(200, 0, 300, 300);
//利用矩形构造两块区域
Region region1 = new Region(rect1);
Region region2 = new Region(rect2);
onDraw(Canvas )方法中先绘制出矩形区域对照,再对两个区域进行Op操作
@Override
protected void onDraw(final Canvas canvas) {
super.onDraw(canvas);
//先绘制出矩形区域对照
canvas.drawRect(rect1, mPaint);
canvas.drawRect(rect2, mPaint);
//对两个区域进行Op操作
region1.op(region2, Region.Op.REPLACE );
//画笔设置不同的颜色,和FILL填充模式,绘制操作后的Region区域
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(Color.GREEN);
drawRegion(canvas, region1, mPaint);
}
绘制Region区域,View中没有单独绘制Region的方法,需要手动实现一个drawRegion()方法
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);
}
}
参考资料:
Android Developers > Docs > Reference > Region
Android Region 类介绍
Region使用全解
Android Region碰撞
Android View之Region