android Region类介绍

来源:互联网 发布:蝙蝠侠阿甘骑士知乎 编辑:程序博客网 时间:2024/05/22 17:24

好久没写博客了,最近终于心静下来了,踏实学习干活了.

Region意思是区域,范围.先了解有啥api给我们使用,然后每个api啥意思,我们就可以根据这个做出我们想要的效果出来,自定义view学习一般是这样的吧,至少个人是这么认为的.

构造函数:

public Region() {    this(nativeConstructor());}/** Return a copy of the specified region*/public Region(Region region) {    this(nativeConstructor());    nativeSetRegion(mNativeRegion, region.mNativeRegion);}/** Return a region set to the specified rectangle*/public Region(Rect r) {    mNativeRegion = nativeConstructor();    nativeSetRect(mNativeRegion, r.left, r.top, r.right, r.bottom);}/** Return a region set to the specified rectangle*/public Region(int left, int top, int right, int bottom) {    mNativeRegion = nativeConstructor();    nativeSetRect(mNativeRegion, left, top, right, bottom);}
我们发现有四个构造函数,先每个函数试试什么意思,
package com.simple;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.graphics.Region;import android.graphics.RegionIterator;import android.util.AttributeSet;import android.view.View;/** * Created by admin on 2017/7/11. */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);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        Region region = new Region();        drawRegion(canvas,region,mPaint);    }    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);        }    }}
上面是使用空的构造函数创建Region对象,如图:


用崔健的一首歌来形容是一无所有啊,对,没错,确实是什么都没有,因为空的构造函数是没指定区域的,哪它就相当于是(0,0)坐标位置了.

现在构造函数改变一下:

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    Region region = new Region(0,0,100,100);    drawRegion(canvas,region,mPaint);}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);    }}
效果图:


这是使用一个矩形构造了一个区域,这和 public Region(Rect r)构造函数是一样的,Rect只是把四个变量封装了一下而已,

现在就剩下最后一个构造函数没说了:

public Region(Region region) {    this(nativeConstructor());    nativeSetRegion(mNativeRegion, region.mNativeRegion);}
关于一个构造函数中传递的是它自己本身的话,一般是copy里面值,比如Rect构造函数中传递一个Rect,无法是把构造函数中的Rect中的left,top,right,bottom赋值给当前要构造的对象Rect而已.
@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    Region region1 = new Region(0,0,100,100);    Region region = new Region(region1);    drawRegion(canvas,region,mPaint);}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);    }}
效果图:


这个和构造一个矩形那个构造函数是一样的,构造函数说完了,看看有啥方法给我们使用;看截图:


我去,不少啊,一个个函数先看下,没办法.

 public void setEmpty() {}把之前区域置为空.

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    Region region = new Region(0,0,100,100);    //region.setEmpty();    drawRegion(canvas,region,mPaint);}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);    }}
图:


现在region调用setEmpty()


你会发现啥也没有了,其实setEmpty()就是把Region中的矩形设置为(0,0),(0,0)设置了这二个点,所以导致啥东西也没有了,

public boolean set(Region region) 
利用新的区域值来覆盖原来的区域

例子:

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    Region region = new Region(0,0,100,100);    region.setEmpty();    Region region1 = new Region(0,0,100,100);    region.set(region1);    drawRegion(canvas,region,mPaint);}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);    }}
我显示给Region设置了一个矩形,然后又置为空了,然后又给它设置了一个矩形,相当于是在原来空的区域地方设置了一个矩形。

图:


 public boolean set(Rect r)把原来的区域用矩形来代替

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    Region region = new Region(0,0,100,100);    region.setEmpty();    region.set(new Rect(100,100,400,400));    drawRegion(canvas,region,mPaint);}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);    }}
这是先给了一个矩形(0,0),(100,100)然后设置为空了,再然后给他设置了一个矩形(100,100),(400,400).

图:


这个方法public boolean set(int left, int top, int right, int bottom)和上面的是同一个意思.不多讲

public native boolean isEmpty()判断这个区域是否是空的.

public native boolean isRect()判断这个区域是否是矩形

/**
     * Return true if the region contains more than one rectangle
     */
    public native boolean isComplex(); 这个注释很清楚,判断是否是多个矩形,意思是这个区域是否是多个矩形构建而成的

public void translate(int dx, int dy) 平移的方法

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    Region region = new Region(0,0,100,100);    region.setEmpty();    region.set(new Rect(100,100,400,400));    mPaint.setColor(Color.GREEN);    canvas.drawPoint(100,100,mPaint);    canvas.drawPoint(400,400,mPaint);    region.translate(0,50);//对区域平移y50px    drawRegion(canvas,region,mPaint);    mPaint.setColor(Color.RED);    canvas.drawPoint(100,100,mPaint);    canvas.drawPoint(400,400,mPaint);    mPaint.setColor(Color.BLUE);    canvas.drawPoint(400,450,mPaint);}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);    }}

图;


 public native boolean contains(int x, int y) 判断这个点是否在这区域内

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    region = new Region(0,0,100,100);    region.setEmpty();    region.set(new Rect(100,100,400,400));    mPaint.setColor(Color.GREEN);    region.translate(0,50,region);    drawRegion(canvas,region,mPaint);}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);    }}@Overridepublic boolean onTouchEvent(MotionEvent event) {    int downX = (int)event.getX();    int downY = (int)event.getY();    boolean isContain =  region.contains(downX,downY);    if(isContain){        Toast.makeText(getContext(),"这个点在这个区域内",Toast.LENGTH_LONG).show();    }else{        Toast.makeText(getContext(),"这个点不在这个区域内",Toast.LENGTH_LONG).show();    }    return true;}
效果图:


public Rect getBounds()  返回的这个区域的矩形

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    region = new Region(0,0,100,100);    drawRegion(canvas,region,mPaint);    Rect rect =  region.getBounds();    Log.e(TAG,"left="+rect.left);    Log.e(TAG,"top="+rect.top);    Log.e(TAG,"right="+rect.right);    Log.e(TAG,"bottom="+rect.bottom);}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);    }}
log:

07-11 03:47:13.188 6873-6873/com.simple E/RegionView: left=0
07-11 03:47:13.188 6873-6873/com.simple E/RegionView: top=0
07-11 03:47:13.188 6873-6873/com.simple E/RegionView: right=100
07-11 03:47:13.188 6873-6873/com.simple E/RegionView: bottom=100

 public boolean getBounds(Rect r)是把Region区域赋值给这个r,

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    region = new Region(0,0,10,10);    Rect rect = new Rect(200,200,240,240);    drawRegion(canvas,region,mPaint);    boolean  a=  region.getBounds(rect);    Log.e(TAG,"a="+a);    Log.e(TAG, ""+rect);}
log:

07-11 04:11:55.014 30301-30301/com.simple E/RegionView: a=true
07-11 04:11:55.014 30301-30301/com.simple E/RegionView: Rect(0, 0 - 10, 10)

从log发现rect原来是(200,200),(240,240)现在变成了(0,0),(10,10),倒推就是region的区域赋值给了rect,相等于rect = region.getRect(),

public boolean quickContains(Rect r)这个方法是判断r这个矩形是否在区域内

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    region = new Region(0,0,100,100);    Rect rect = new Rect(0,0,101,101);    drawRegion(canvas,region,mPaint);    boolean b = region.quickContains(rect);    Log.e(TAG,"b="+b);    rect = new Rect(0,0,100,100);    boolean c = region.quickContains(rect);    Log.e(TAG,"c="+c);}
log:

07-11 05:10:07.150 19374-19374/com.simple E/RegionView: b=false
07-11 05:10:07.150 19374-19374/com.simple E/RegionView: c=true

public native boolean quickReject(int left, int top, int right, int bottom)这个方法同理上面的

public boolean quickReject(Rect r) 这个看官方注释:

/** * Return true if the region is empty, or if the specified rectangle does * not intersect the region. Returning false is not a guarantee that they * intersect, but returning true is a guarantee that they do not. */
大概就能明白,还不明白,给你翻译:

返回true,如果区域是空的,或者指定的矩形不相交的区域。返回false并不保证他们相交,但是是一个保证他们不返回true

测试:

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    region = new Region(0,0,100,100);    Rect rect = new Rect(0,0,101,101);    drawRegion(canvas,region,mPaint);    boolean b = region.quickReject(rect);    Log.e(TAG,"b="+b);    rect = new Rect(0,0,0,0);    boolean c = region.quickReject(rect);    Log.e(TAG,"c="+c);}
log:

07-11 05:15:06.741 24043-24043/com.simple E/RegionView: b=false
07-11 05:15:06.741 24043-24043/com.simple E/RegionView: c=true

public native boolean quickReject(int left, int top, int right, int bottom)同理上面的方法


还剩下几个重要的方法,就是区域之间的交并集方法:

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)  

先来讲第一个方法:

public final boolean union(Rect r) 

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    region = new Region(0,0,100,100);    Rect rect = new Rect(200,200,300,300);    drawRegion(canvas,region,mPaint);    region.union(rect);    mPaint.setColor(Color.GRAY);    drawRegion(canvas,region,mPaint);}
效果图:


就是把二个区域合并,就是高中学的二个集合的并集

public boolean op(Rect r, Op op) 

第一个参数是Rect

第二个参数是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;}
这是什么鬼:有道翻译出手



写例子去证明每个啥意思:

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    Rect rect1 = new Rect(200,200,500,500);    Rect rect2 = new Rect(300,300,600,600);    Paint paint = new Paint();    paint.setColor(Color.RED);    paint.setStyle(Paint.Style.STROKE);    paint.setStrokeWidth(2);    //绘制二个矩形    canvas.drawRect(rect1, paint);    canvas.drawRect(rect2, paint);    //构造两个Region    Region region1 = new Region(rect1);    Region region2= new Region(rect2);    region1.op(region2, Region.Op.DIFFERENCE);    paint.setColor(Color.GREEN);    paint.setStyle(Paint.Style.FILL);    drawRegion(canvas, region1, 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);    }}
DIFFERENCE:


INTERSECT:


UNION:


XOR:


REVERSE_DIFFERENCE:


REPLACE:


综合上面的演示总结:

DIFFERENCE就是region1-(region1和region2的交集) 补集

INTERSECT就是region1和region2的交集

UNION就是region1和region2的并集

XOR就是region1和region2的并集并减去region1和region2的交集    异并集

REVERSE_DIFFERENCE就是region2减去region2和region1的交集   反转补集

REPLACE:就是显示region2的区域 替换

他有什么实际的作用,好像我没用到.就看到判断一个点是否在该区域内.用到地方再说吧

原创粉丝点击