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(); //创建一个 Region 对象
drawRegion(canvas,region,mPaint); //自定义方法 绘制 Region
}
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)坐标位置了.
现在构造函数改变一下:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Region region = new Region(0,0,100,100); //创建一个 有区域参数的 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 对象来赋值传递
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Region region1 = new Region(0,0,100,100); //创建一个 region 对象
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);
}
}
就是把之前的区域给置空
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Region region = new Region(0,0,100,100);
//region.setEmpty(); //打开函数 将什么也看不到
drawRegion(canvas,regi on,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);
}
}
用新的区域覆盖原来的区域
例子:
@Override
protected 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)把原来的区域用矩形来代替
@Override
protected 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 contains(int x, int y) 判断这个点是否在这区域内
@Override
protected 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);
}
}
@Override
public 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;
}
效果图:
返回的是 区域的矩形位置
@Override
protected 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
getBounds(Rect r) 是把Region区域赋值给这个r,
@Override
protected 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(),
quickContains(Rect r)这个方法是判断r这个矩形是否在区域内
@Override
protected 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 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;
}
写例子去证明每个啥意思:
@Override
protected 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); //设置两个 区域操作为 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
DIFFERENCE就是region1-(region1和region2的交集) 补集
INTERSECT
INTERSECT就是region1和region2的交集
UNION
UNION就是region1和region2的并集
XOR
XOR就是region1和region2的并集并减去region1和region2的交集 异并集
REVERSE_DIFFERENCE
REVERSE_DIFFERENCE就是region2减去region2和region1的交集 反转补集