Android自定义View之——Region区域(一)

1,138 阅读2分钟

Region 译为“区域”,是一块任意形状的封闭图形。很多时候用来构造图形。

1. 构造函数

  // 复制
  public Region(@NonNull Region region)
  // 创建一个矩形区域
  public Region(@NonNull Rect r)
  // 通过上下左右创建矩形区域
  public Region(int left, int top, int right, int bottom)

第二个和第三个构造函数最常用。

2. 函数

  // 置空
  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)

主要说一下最后一个setPath函数:

  • Path path:用来构造区域的路径
  • Region clip:与前面的path所构成的路径取交集,并将该交集设置为最终的区域。

3. 区域相交

1. union函数

boolean union(Rect r)

该函数用于指定矩形取并集,即将Rect所指定的矩形加入到当前区域中。

如:

override fun onDraw(canvas: Canvas?) {
  super.onDraw(canvas)
  // 画笔
  val paint = Paint()
  // 灰色
  paint.color = Color.GRAY
  paint.style = Paint.Style.FILL
  // 区域
  val region = Region(10, 10, 200, 100)
  // 和另一个矩形取并集
  region.union(Rect(10, 10, 50, 200))
  drawRegion(canvas, region, paint)
}

注:其中drawRegion为绘制区域的方法,代码如下:

private fun drawRegion(canvas: Canvas?, region: Region, paint: Paint) {
  val regionIterator = RegionIterator(region)
  val rect = Rect()
  // 循环绘制
  while (regionIterator.next(rect)) {
    canvas?.drawRect(rect, paint)
  }
}

最后的效果如下:

union

2. 区域操作

除通过union函数取并集指定的矩形外,Region还提供了如下几个灵活的操作函数。前三个函数的作用相同,和指定的Rect矩形相交,并赋值给当前Region,后两个函数允许我们传入两个区域进行操纵,成功返回true

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

Op为指定操作的枚举参数,共有6种操作:

public enum Op {
  DIFFERENCE(0),  // 补集
  INTERSECT(1),   // 交集
  UNION(2),     // 并集
  XOR(3), // 异并集
  REVERSE_DIFFERENCE(4),  // 反转补集
  REPLACE(5); // 替换
}

感兴趣可以自己去尝试一下,代码和效果如下:

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
​
        val rect1 = Rect(100, 100, 400, 200)
        val rect2 = Rect(200, 0, 300, 300)
​
        val paint = Paint()
        paint.color = Color.RED
        paint.style = Paint.Style.STROKE
        paint.strokeWidth = 2f
​
        canvas?.drawRect(rect1, paint)
        canvas?.drawRect(rect2, paint)
​
        val region1 = Region(rect1)
        val region2 = Region(rect2)
​
        region1.op(region2, Region.Op.DIFFERENCE)
//        region1.op(region2, Region.Op.INTERSECT)
//        region1.op(region2, Region.Op.UNION)
//        region1.op(region2, Region.Op.XOR)
//        region1.op(region2, Region.Op.REVERSE_DIFFERENCE)
//        region1.op(region2, Region.Op.REPLACE)
​
        // 最后构造一个填充画笔,将所选区域用绿色填充
        val paint1 = Paint()
        paint1.color = Color.GREEN
        paint1.style = Paint.Style.FILL
        drawRegion(canvas, region1, paint1)
    }
​
    private fun drawRegion(canvas: Canvas?, region: Region, paint: Paint) {
        val regionIterator = RegionIterator(region)
        val rect = Rect()
        while (regionIterator.next(rect)) {
​
            canvas?.drawRect(rect, paint)
​
        }
    }

补集

交集

并集

异并集

反转补集

image-20220120230716997

\