自定义控件——基础图形绘制

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_43847987/article/details/100323922

android中的paint类就是画笔,canvas类就是纸,也就是画布。

画笔的基本属性如下:

Paint paint = new Paint();
paint.setColor(Color.RED);//设置画笔基本属性
paint.setStyle(Paint.Style.STROKE);//设置填充样式 
paint.setStrokeWidth(50);//设置画笔宽度

如何实现画一个圆呢?很简单

canvas.drawCircle(100,200,100,paint)

这里的画圆会调用专门的drawCircle方法,前两个参数是圆心的坐标,第三个参数是元的半径,第四个参数就是我们所设置的画笔了。

画笔的基本设置:
1.setColor()
设置颜色,颜色由三种原色组成(红,绿,蓝),所以void setColor(int color)中 color只能8位的0xAARRGGBB样式颜色值。A代表透明度,RGB对应红绿蓝。通过数值来设置我们需要的颜色。
2.setStyle
设置填充样式,对于文字和几何图形都有效,三种取值方式:
Paint .Style.FILL:仅填充内部
Paint.Style.FILL_AND_STROKE:填充内部和描边
Paint.Style.STROKE:仅描边

效果如下:
在这里插入图片描述
3.setStrokeWidth
设置描边宽度

Canvas使用基础
1.画布背景设置
三种方法实现:

void drawColor(int color);
void drawColor(int a,int r,int g,int b);
void drawColor(int r,int g,int b);

2.画直线
drawLine(float startX,float startY,float stopX,float stopY,Paint paint)
startX,startY起始点坐标
stopX,stopY结束点坐标

3.点
void drawPoint(float x,float y,Paint paint)//点坐标

4.矩形工具类RectF,Rect
RectF的构造方法

RectF()
RectF(float left,float top,float right,float bottom);
RectF(RectF r);
RectF(Rect r);

Rect的构造方法

Rect()
Rect(float left,float top,float right,float bottom);
Rect(Rect r);

构造一个矩形结构如下:

//方法一
Rect rect = new Rect(10,10,100,100);
//方法二
Rect rect = new Rect();
rect.set(10,10,100,100);

5.矩形

void drawRect(float left,float top,float right,float bottom,Paint paint);
void drawRect(RectF r,Paint paint);
void drawRect(Rect r,Paint paint);

路径
在android中Path类就代表路径
路径的绘制方法:

void drawPath(Path path,Paint paint);

直线路径
画一条直线路径涉及到三个函数
void moveTo(float x1,float y1);

void moveTo(float x1,float y1);//对应直线的起始点
void lineTo(float x1,float y1);//对应直线的终点
void close();//如果所画的几条线没有形成闭环,close函数会将路径首尾点连接起来。	

实现如下:

Path path = new Path();
path.moveTo(10,10);//直线的起点
path.lineTo(10,100);//第一条直线的终点,也是第二条直线的起点
path.lineTo(200,100);//第二条直线
path.close();//闭环

弧线路径
void arcTo(RectF oval,float startAngle,float sweepAngle)

void arcTo(RectF oval,float startAngle,float sweepAngle) ;
void arcTo(RectF oval,float startAngle,float sweepAngle,boolean forceMoveTo) ;
void arcTo(float left,float top,float right,float bottom,
float startAngle,float sweepAngle,boolean forceMoveTo) ;

oval 生成椭圆的矩形
startAngle 弧开始的角度,以x轴正方向为0°
sweepAngle 弧持续的角度
forceMoveTo 表示是否将弧的起始点作为绘制起始位置

Region区域
直接构造

public  Region(Region region);//复制一个Region的范围
public  Region(RectF r);//创建一个矩形
public  Region(int left,int top,int right,int bottom);//创建一个矩形区域

示例

 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        Paint paint=new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.RED);

        Region region=new Region(new Rect(50,50,100,100));
        drawRegion(canvas,region,paint);
    }
//自定义drawRegion方法
	 private void drawRegion(Canvas canvas, Region region, Paint paint) {
	        RegionIterator iterator=new RegionIterator(region);
	        Rect r=new Rect();
	        while(iterator.next(r)){
	            canvas.drawRect(r,paint);
	        }
	    }

示例中构造了一个Region对象,但是在canvas中并没有用来画Region的方法,所以我们需要自己来定义这么一个方法drawRegion()。
上在这里插入图片描述
这就是上面代码所画的图,从代码中我们就可以看出是一个矩形区域。
从canvas并没有提供Region的画图方法,可以知道Region并不是用来绘图的。

2.Region的间接构造
set系列函数

public void setEmpty();//置空函数,即将原来的函数变成空变量
public boolean set(Region region);//用新区域代替原来的区域
public boolean set(Rect r);//用矩形区域代替原来的区域
public boolean set(int l,int t,int r,int b );//用矩形区域代替原来的区域
public boolean setPath(Path path, Region r);//根据路径区域与某区域的交集构造新的区域

区域相交
union函数
用于指定矩形取并集,将Rect所指定的矩形加入当前区域中。 、

区域操作
三种方法:

boolean op(Rect r,Op op);
boolean op(int l,int t,int r,int b,Op op);
boolean op(Region r,Op op);

如下为op对应的6中参数值
在这里插入图片描述
下图是者六种对应的图形表示
在这里插入图片描述

Canvas画布
1.画布的平移
在Canvas种有一个函数translate()是用来实现化的平移的

void translate(float dx,float dy);//对应的X,Y分别表示在下水平和竖直方向上的平移距离。

当我们平移了画布时,使用同样的画图坐标比如:
new Rect(50,50,100,100);在画布平移前后会得到不同的结果,相信这个还是很好理解的,毕竟坐标系都发生了改变。

2.屏幕显示和Canvas的关系
我一直以为显示所绘图形的屏幕就是canvas,起始这是一种错误的理解,看下面这段代码:

  @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        Paint paintG=generatePaint(Color.GREEN, Paint.Style.STROKE,3);
        Paint paintR=generatePaint(Color.RED,Paint.Style.STROKE,3);

        Rect r=new Rect(0,0,400,220);

        canvas.drawRect(r,paintG);

        canvas.translate(100,100);

        canvas.drawRect(r,paintR);

    }

    private Paint generatePaint(int color, Paint.Style style, int width) {
        Paint p=new Paint();
        p.setColor(color);
        p.setStyle(style);
        p.setStrokeWidth(width);
        return p;
    }

实际结果如图:
在这里插入图片描述
为什么绿色框会没有移动呢?
这是因为屏幕显示与Canvas根本不是一个概念,Canvas是一个很虚幻的概念,相当于一个透明图层,每次在canvas上画图时,都会产生一个透明图层,然后再再这个图层上面绘图,这上面的绿色框没有移动就是因为它处于没有移动时的那个图层。所以会有这样的现象。所以一定要记住屏幕显示和我们的Canvas是不一样的哦。

3.裁剪画布(clip系列函数)
裁剪画布是指clip系列函数与Rect,Path等取交并等集合运算来获得的最新的画布形状。除调用save(),restore()函数外,这个操作是不可逆的,一旦Canvas被裁剪,就不可恢复。

 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.RED);
        canvas.clipRect(new Rect(100,100,200,200));
        canvas.drawColor(Color.GREEN);
    }

裁剪结果如下:
在这里插入图片描述
画布的保存与恢复
save和restore函数
save每次调用时都会先保存当前画布的状态,然后将其放入特定的栈中。
restore每次调用时都会把栈中顶层的画布状态取出来,并按照这个状态恢复当前的画布,然后在这个画布上作画

猜你喜欢

转载自blog.csdn.net/weixin_43847987/article/details/100323922