canvas的使用

1:画圆
canvas.drawCircle(width / 2, height / 2, radius, mPaint);//绘制圆形,第一个参数是圆心的x坐标,第二个参数是圆心的y坐标,第三个参数是半径,单位都是像素
2:画矩形canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),paint);//这里绘制出来的矩形是实心的矩形,而不是空心的矩形线条,因为paint设置的style是Paint.Style.FILL,前四个参数的具体含义请看下图
canvas的使用_第1张图片
image.png
3:canvas.save()和canvas.restore()的区别
@Override
    protected void onDraw(Canvas canvas) {
        canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),paint);
        canvas.drawRect(10,10,getMeasuredWidth()-10,getMeasuredHeight()-10,paint1);
        canvas.save();
        canvas.translate(10,0);
        canvas.restore();
        super.onDraw(canvas);
    }
区别是:当调用save方法后,就将canvas的位置和角度记录下来了,然后接下来就可以进行画布的平移,旋转之类的位置变化操作,也可以进行画图操作,不过此时所画的图是在进行了位置变化操作之后的canvas上进行的,如果要还原上一次保存的canvas的位置的话,就调用restore方法,这时canvas的位置就回到了上一次save时的状态了。
4,画圆弧:drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)

oval :指定圆弧的外轮廓矩形区域。
startAngle: 圆弧起始角度(x轴的正右的方向,是0度的位置),单位为度。
sweepAngle: 圆弧扫过的角度,顺时针方向为正角度,单位为度
useCenter: 如果为True时,用来绘制扇形,如果为false时,用来绘制弧形。
paint: 绘制圆弧的画板属性,如颜色,是否填充等。

paint.setStyle(Paint.Style.FILL);
canvas.drawArc(200,100,800,500,180,60,false,paint);
以上两句代码画出的形状是
canvas的使用_第2张图片
5,画笔的一些方法

1:用paint的时候有三种Style,分别是
Paint.Style.STROKE 只绘制图形轮廓(描边)
Paint.Style.FILL 只绘制图形内容 ,默认是Paint.Style.FILL
Paint.Style.FILL_AND_STROKE 既绘制轮廓也绘制内容


canvas的使用_第3张图片
image.png

2:mPaint.setStrokeWidth(40);//用来设置画笔的宽度

6,设置画布的颜色,这类颜色填充方法一般用于在绘制之前设置底色,或者在绘制之后为界面设置半透明蒙版。
        canvas.drawColor(Color.RED);
        canvas.drawARGB(100,100,100,100);
        canvas.drawRGB(100,100,100);
7,设置线条的宽度,在STROKE和FILL_AND_STROKE下使用
paint.setStrokeWidth(10);//设置线条宽度为10像素
8,在绘制的时候,往往需要开启抗锯齿来让图形和文字的边缘更加平滑
        paint=new Paint(Paint.ANTI_ALIAS_FLAG);//静态开启抗锯齿
        paint.setAntiAlias(true);//动态开启抗锯齿
9,绘制一个点,前两个参数是x,y坐标,点的大小可以通过paint.setStrokeWidth来设置,点的形状可以通过paint.setStrokeCap来设置,其中,SQUARE或BUTT画出来是方形的点,ROUND画出来是圆形的点。
canvas.drawPoint(100,100,paint);
10,画椭圆
canvas.drawOval(100,100,200,500,paint);
11,画线,由于直线不是封闭图形,所以paint.setStyle对直线没有影响,canvas.drawLine是画一条线,可以用canvas.drawLines批量画线
canvas.drawLine(200,200,400,400,paint);
12,画圆角矩形,第五个和第六个参数是矩形的每个圆角的横向半径和纵向半径
canvas.drawRoundRect(200,300,400,500,80,80,paint);
13,根据path画图形
canvas.drawPath(path, paint);

其中,Path对象有如下

第一组,add...方法(添加完整封闭图形,除了addPath())

        path.addCircle(300,300,200, Path.Direction.CW);//添加圆
        //path.addOval();//添加椭圆
        //path.addRect();//添加矩形
        //path.addRoundRect();添加圆角矩形
        //path.addPath();添加path

第二组,...To方法(画直线或者曲线)

        //lineTo和rLineTo画直线
        paint.setStyle(Paint.Style.STROKE);//如果参数是Paint.Style.FILL,那么画出来的是个三角形,和上面的那个画圆弧的一样,将画笔style设置为FILL
        path.lineTo(100,100);//参数是绝对坐标,由当前位置(0,0)向(100,100)画一条直线
        path.rLineTo(100,0);//参数是相对坐标,由当前位置(100,100)向正右方100像素的位置画一条直线
        canvas.drawPath(path, paint);

        //moveTo移动原点位置
        paint.setStyle(Paint.Style.STROKE);
        path.lineTo(100,100);//相对于原点(0,0)画直线到点(100,100)
        path.moveTo(200,100);//此时原点坐标为(200,100)
        path.lineTo(200,0);//相对于原点(200,100)画直线到点(200,0),注意这个(200,0)点还是以(0,0)为原点的(200,0)点,因为用的是lineTo,如果是rLineTo()则原点为(200,100)
        canvas.drawPath(path, paint);

        //arcTo画弧线
        paint.setStyle(Paint.Style.STROKE);
        path.lineTo(100,100);
        path.arcTo(100,100,300,300,-90,90,false);//第七个参数为直线连线连到弧形起点,true为无痕迹,false为有痕迹,如果没有path.lineTo(100,100);这句
        //代码的话,true和false的效果是一样的
        canvas.drawPath(path, paint);

        //addArc画弧线
        paint.setStyle(Paint.Style.STROKE);
        path.lineTo(100,100);
        path.addArc(100,100,300,300,-90,90);//path.addArc(100,100,300,300,-90,90)相当于path.arcTo(100,100,300,300,-90,90,true),addArc()相当于arcTo()的第七个参数为true的简化版
        canvas.drawPath(path, paint);

第三,Path的close方法,不是所有的子图形都需要使用path的close()来封闭的,当paint的style是FILL或者是FILL_AND_STROKE时,Path会自动封闭子图形,这就是上面画弧和画两条线,如果设置为FILL,画出来的是填充的弧和三角形的原因。

        paint.setStyle(Paint.Style.FILL);
        path.moveTo(100,100);
        path.lineTo(200,100);
        path.lineTo(150,150);
        canvas.drawPath(path, paint);//这里只绘制了两条边,但由于style是FILL,所以绘制时会自动封口

第四,Path的setFillType方法,对于添加子图形类方法(如path.addCircle(),path.addRect())的方向,由方法的dir参数来控制,而对于画线类的方法(如path.lineTo(),path.arcTo())的方向就是图形的方向

        paint.setStyle(Paint.Style.FILL);
        path.addCircle(300,300,200, Path.Direction.CCW);//CW顺时针,CCW逆时针
        path.addCircle(300,300,100, Path.Direction.CW);
        path.setFillType(Path.FillType.INVERSE_WINDING);//EVEN_ODD是如果是奇数就绘制,也就是说如果两个图形有部分重合,那么重合的那部分就不绘制,绘制剩下的
        //WINDING是按方向进行相加的,顺时针方向+1,逆时针方向-1,最后为0的那部分不绘制,绘制剩下的
        //INVERSE_EVEN_ODD就是将EVEN_ODD反过来
        //INVERSE_WINDING就是将WINDING反过来
        canvas.drawPath(path,paint);
来个图片,通俗易懂
canvas的使用_第4张图片
14,画Bitmap
Bitmap bitmap=BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher);
...
canvas.drawBitmap(bitmap,100,100,paint);
15,绘制文字
        paint.setTextSize(100);//设置文字的大小
        canvas.drawText("你好啊",200,200,paint);

以前记录过的

        Paint a=new Paint();
        a.setColor(Color.RED);
        //a.setAlpha(100);
        //a.setStyle(Style.FILL_AND_STROKE);//设置画笔的风格
        //a.setStrokeWidth(33);//设置空心线宽
        a.setTextSize(34);//设置画笔字体的大小
        //a.setTypeface(Typeface.DEFAULT_BOLD);//设置字体样式
        //a.setTextScaleX(55);//设置比例因子,以一为标准
        //a.setARGB(40, 45, 88, 66);//设置字体的颜色
        //a.setUnderlineText(true);//设置下划线
        //a.setTextSkewX(3);//设置倾斜因子,以零为标准
        canvas.drawColor(Color.GREEN);//设置背景颜色
        //canvas.drawText("n好啊", 70, 90, a);
        ///canvas.drawCircle(33, 22, 44, a);
        //canvas.drawLine(33, 44, 11, 22, a);
        //canvas.drawPoint(44, 55, a);
        //canvas.drawRoundRect(new RectF(55,277,488,499), 35, 22, a);//绘制圆角矩形
        //canvas.drawOval(new RectF(33,333,222,444), a);//绘制椭圆形
        //Path ab=new Path();
        //ab.moveTo(33, 44);
        //ab.lineTo(77, 88);
        //ab.lineTo(76, 55);
        //canvas.drawPath(ab, a);//绘制任意多边形
        //canvas.drawArc(new RectF(33,44,333,444), 66, 55, true, a);//绘制圆弧
        //Bitmap ac=((BitmapDrawable)getResources().getDrawable(R.drawable.ic_launcher)).getBitmap();
        //canvas.drawBitmap(ac, 444, 44, a);//绘制图像
        
        //canvas.clipRect(44, 66, 222, 330);//裁剪指定的区域
        //canvas.drawColor(Color.BLUE);
        //canvas.drawText("旋转字", 43, 333, a);
        //canvas.save();
        //canvas.rotate(60,43,333);
        //canvas.drawText("旋转字", 43, 333, a);
        //canvas.restore();//关于画布锁定和解锁,旋转的例子

-----------------------------------------------------------------------------------

android群英传中对canvas的介绍

1:Canvas.save(),Canvas.restore(),Canvas.translate(),Canvas.rotate()这四个方法的介绍如下:

Canvas.save()这个方法,从字面上可以理解为保存画布,它的作用就是将之前的所有已绘制图像保存起来,让后续的操作就好像在一个新的图层上操作一样,这一点点与photoshop中的图层理解基本一致。
Canvas.restore()这个方法,则可以理解为photoshop中的合并图层操作,它的作用是将我们在save()之后绘制的所有图像与save()之前的图像进行合并。
translate()和rotate()方法,就是在调用translate(x,y)方法之后,将原点(0,0)移动到(x,y)。之后的所有绘图操作都将以(x,y)为原点执行。同理totate()方法也是一样的,它将坐标系旋转了一定的角度。

2:Layer图层

在android中通过调用saveLayer()方法,saveLayerAlpha()方法创建一个图层,使用restore()方法,restoreToCount()方法合并所有图层。创建图层的时候,后面所有的操作都发生在这个图层上。saveLayerAlpha()的第五个参数的取值如果是0比表示完全透明,127表示半透明,255表示完全不透明。示例代码如下:

        canvas.drawCircle(300,300,200,paint);
        canvas.saveLayerAlpha(0,0,600,600,127);
        paint.setColor(Color.GREEN);
        canvas.drawCircle(300,300,300,paint);
        canvas.restore();

图如下所示:


canvas的使用_第5张图片

3:PorterDuffXfermode(参考文章:https://www.jianshu.com/p/0f64daf202f2)

canvas的使用_第6张图片

示例代码如下:

...
        canvas.saveLayer(0,0,canvas.getWidth(),canvas.getHeight(),paint);//必须要新建一个图层才能看到混合后的效果了
        canvas.drawCircle(0,0,bitmap.getWidth()/2,paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap,0,0,paint);
        paint.setXfermode(null);// 还原混合模式
        canvas.restore();//合并图层
...

效果如下:


canvas的使用_第7张图片

4:Shader,着色器,渲染器,Shader包括:BitmapShader(位图Shader),LinearGradient(线性Shader),RadialGradient(光速Shader),SweepGradient(梯度Shader),ComposeShader(混合Shader)

4.1:BitmapShader的使用,填充模式有三种CLAMP(拉伸),REPEAT(重复),MIRROR(镜像),示例代码如下:

 paint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
        canvas.drawCircle(canvas.getWidth() / 2, canvas.getHeight() / 2, canvas.getWidth() / 2 > canvas.getHeight() / 2 ? canvas.getHeight() / 2 : canvas.getWidth() / 2, paint);

结果如下所示:


canvas的使用_第8张图片

4.2:LinearGradient的使用,示例代码如下:

 paint.setShader(new LinearGradient(0,0,canvas.getWidth(),canvas.getHeight(),Color.BLUE,Color.GREEN, Shader.TileMode.CLAMP));
        canvas.drawCircle(canvas.getWidth() / 2, canvas.getHeight() / 2, canvas.getWidth() / 2 > canvas.getHeight() / 2 ? canvas.getHeight() / 2 : canvas.getWidth() / 2, paint);

结果如下所示:


canvas的使用_第9张图片
小技巧:Marix.setScale(1F,-1F)可以实现图片的垂直翻转。

5:PathEffect

5.1:DiscretePathEffect,使用这个效果之后,线段上就会产生许多杂点

        paint.setPathEffect(new DiscretePathEffect(3f,5f));
        Path path=new Path();
        path.moveTo(0,canvas.getHeight()/2);
        path.lineTo(canvas.getWidth()/3,0);
        path.lineTo(canvas.getWidth()/3*2,canvas.getHeight());
        path.lineTo(canvas.getWidth(),0);
        canvas.drawPath(path,paint);

效果图如下:


canvas的使用_第10张图片

5.2:DashPathEffect,这个效果可以用来绘制虚线,用一个数组来设置各个点之间的间隔,此后绘制虚线时就重复这样的间隔进行绘制,另一个参数则用来控制绘制时数组的一个偏移量,通常可以通过设置值来实现路径的动态效果。

  paint.setPathEffect(new DashPathEffect(new float[]{20,10,5,10},0));

效果图如下:


canvas的使用_第11张图片

5.3:PathDashPathEffect,这个效果和DashPathEffect效果类似,只不过它的功能更加强大,可以设置显示点的图形,即方形点的虚线,圆形点的虚线。

        Path path1=new Path();
        path1.addRect(0,0,8,8,Path.Direction.CCW);
        paint.setPathEffect(new PathDashPathEffect(path1,12f,0,PathDashPathEffect.Style.ROTATE));

效果图如下:


canvas的使用_第12张图片

5.4:CornerPathEffect,就是将拐角处变得圆滑,具体圆滑的程度,则由参数决定。

 paint.setPathEffect(new CornerPathEffect(30));

效果图如下:


canvas的使用_第13张图片

5.5:ComposePathEffect,将任意两种路径特效组合起来形成一个新的效果。

        PathEffect pathEffect=new CornerPathEffect(30);
        PathEffect pathEffect1=new DashPathEffect(new float[]{20,10,5,10},0);
        paint.setPathEffect(new ComposePathEffect(pathEffect,pathEffect1));

效果图如下:


canvas的使用_第14张图片

5.6:SumPathEffect,将任意两种路径特效组合起来形成一个新的效果。

        PathEffect pathEffect=new CornerPathEffect(30);
        PathEffect pathEffect1=new DashPathEffect(new float[]{20,10,5,10},0);
        paint.setPathEffect(new SumPathEffect(pathEffect,pathEffect1));

效果图如下:


canvas的使用_第15张图片

你可能感兴趣的:(canvas的使用)