1:画圆
canvas.drawCircle(width / 2, height / 2, radius, mPaint);//绘制圆形,第一个参数是圆心的x坐标,第二个参数是圆心的y坐标,第三个参数是半径,单位都是像素
2:画矩形canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),paint);//这里绘制出来的矩形是实心的矩形,而不是空心的矩形线条,因为paint设置的style是Paint.Style.FILL,前四个参数的具体含义请看下图
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);
以上两句代码画出的形状是
5,画笔的一些方法
1:用paint的时候有三种Style,分别是
Paint.Style.STROKE 只绘制图形轮廓(描边)
Paint.Style.FILL 只绘制图形内容 ,默认是Paint.Style.FILL
Paint.Style.FILL_AND_STROKE 既绘制轮廓也绘制内容
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);
来个图片,通俗易懂
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();
图如下所示:
3:PorterDuffXfermode(参考文章:https://www.jianshu.com/p/0f64daf202f2)
示例代码如下:
...
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();//合并图层
...
效果如下:
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);
结果如下所示:
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);
结果如下所示:
小技巧: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);
效果图如下:
5.2:DashPathEffect,这个效果可以用来绘制虚线,用一个数组来设置各个点之间的间隔,此后绘制虚线时就重复这样的间隔进行绘制,另一个参数则用来控制绘制时数组的一个偏移量,通常可以通过设置值来实现路径的动态效果。
paint.setPathEffect(new DashPathEffect(new float[]{20,10,5,10},0));
效果图如下:
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));
效果图如下:
5.4:CornerPathEffect,就是将拐角处变得圆滑,具体圆滑的程度,则由参数决定。
paint.setPathEffect(new CornerPathEffect(30));
效果图如下:
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));
效果图如下:
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));
效果图如下: