自定义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 零零柒」,回复:Android基础,即可获取Android入门资料,公众号主推Android技术,金融经济,认知和知识等文章
参考资料:
https://blog.csdn.net/cquwentao/article/details/51365099