这里记录一下Canvas 相关API的使用,权当自己作笔记,以后需要好参考
前面有一文Android应用程序窗口View的draw过程讲到View的绘制过程,其中说到,View绘制自己的内容是在它的onDraw()回调里进行的,这个回调带有一个参数,参数类型就是Canvas,View的内容绘制需要用到Canvas。
关于Canvas,官方文档:https://developer.android.com/reference/android/graphics/Canvas.html
Canvas有许多以draw开头的函数:
如上所示,根据这些函数的名字可以大概知道这些函数的作用。就是绘制各种图形,例如填充色,文本,圆,线....这些丰富的API为支持我们自定义内容丰富的View,因为android提供的控件毕竟有限,在有些情况,还是需要自定义View,自定义View无非就是UI个性化设置,这个时候重载onDraw()函数,然后在这个回调里,利用Canvas的API绘制自己想要的内容。
看看上Canvas的draw相关函数,可以发现,还有一个对象经常作为参数传入,就是Paint,就翻译为画笔,可以这么理解Canvas只是一块布,而在该布上执行绘制的操作(画线,画圆)都是由Paint完成的,所以这个Paint很重要。下面就简单看一下Canvas的相关函数:
首先看一下设置Canvas的填充色:
canvas.drawColor(Color.BLUE);
canvas.drawARGB(255,255,0,0);
下面的draw函数都需要用到Paint,先看一下Paint:
https://developer.android.com/reference/android/graphics/Paint.html
Paint类常用方法:
setARGB(int a, int r, int g, int b) // 设置 Paint对象颜色,参数一为alpha透明值
setAlpha(int a) // 设置alpha不透明度,范围为0~255
setAntiAlias(boolean aa) // 是否抗锯齿
setColor(int color) // 设置颜色,这里Android内部定义的有Color类包含了一些常见颜色定义
setTextScaleX(float scaleX) // 设置文本缩放倍数,1.0f为原始
setTextSize(float textSize) // 设置字体大小
setUnderlineText(booleanunderlineText) // 设置下划线
demo的布局文件:
package cj.com.canvasdemo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/**
*
*/
public class MyView extends View {
Paint paint;
public MyView(Context context) {
super(context);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint(); //
paint.setColor(Color.RED);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(3);
}
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//...自定义绘制
}
}
这里画笔默认的style是填充的,所以下面效果都是填充的效果。
1。绘制弧形:
先看第一个函数,这个函数API 21 才添加的
canvas.drawArc(20,20,300,300,0,90,true,paint);
效果:
前面四个参数围成的矩形,在矩形内绘制内切弧形,第5,6个参数分别是起始角度,和结束角度,是按顺时针来绘制的,第7个布尔型参数表示是否绘制中心那一块,看一下为false的情况:
差别很明显,最后一个参数就是Paint。
第二函数比第一个函数也就是少了三个参数,其实是把第一个函数的前面的四个参数,封装到RectF这个对象了,这个对象代表就是矩形:
RectF rectF = new RectF(20,20,300,300);
canvas.drawArc(rectF,0,90,false,paint);
2.绘制圆:
canvas.drawCircle(200,200,100,paint);
这个函数比较好理解,第1,2个参数就是圆心位置的x,y坐标。第3个圆的半径,第四个paint
3.绘制线:
首先看第一个函数
canvas.drawLine(50,60,120,140,paint);
这个函数也比较好理解,绘制直线肯定需要两个端点,前面四个参数就是两个端点x,y坐标
看第二个函数,稍微复杂点:
float[] ps = {20,30,150,180,50,40,90,100,50,60};
canvas.drawLines(ps,0,8,paint);
它的作用绘制很多条直线,这些直线的端点的x,y坐标就通过一个浮点数组来表示,每个四个值代表两个端点。
第一个参数就是数组,第二个参数是偏移位置,就是从数组第几个位置开始取值开始绘制直线,我这里是0,表示20作为第一个端点的x坐标,如果偏移位置是2的话表示舍弃前面的20,30,取150作为第一条直线的第一个端点的x坐标。第三个参数表示取数组中几个值来绘制直线,如果想绘制直线的至少要4个值,当然要是4的倍数才会绘制相应的直线。比如你传3那么就不能绘制一条直线,如果传入4到7之间的值,也只能绘制一条直线。当然你也要根据数组的值的个数来设置,超过数组的大小会报异常的,第4个参数就是paint。
看第三个函数:
float[] ps = {20,30,150,180,180,40,90,100,50,60,70,130};
canvas.drawLines(ps,paint);
这个函数和第二函数相似,都是用来绘制一系列直线,用数组来保存直线端点的x,y坐标值。不过这个函数比较智能,它以数组的大小来判断绘制多少条直线,直接绘制出来。
4.绘制椭圆
绘制椭圆和绘制弧形差不多
首先看第一个函数,这个函数也是API LEVEL 21才添加的
canvas.drawOval(20,80,500,500,paint);
函数的前面四个参数围成矩形,在矩形内绘制内切椭圆
第二个函数,就是将第一个函数的前面四个参数封装成RectF对象。
RectF rectF = new RectF(20,80,500,500);
canvas.drawOval(rectF,paint);
效果一样。
5.绘制path
path可翻译为路径,https://developer.android.com/reference/android/graphics/Path.html
Path类功能很强大,主要用于绘制复杂的图形轮廓,关于Path的简绍该文就不作详说了,大家可以查阅资料。
Path path = new Path(); //定义一条路径
path.moveTo(60, 60); //起始点 坐标60,60
path.lineTo(100, 100);//连接直线
path.lineTo(200,80);
path.lineTo(60, 60);
canvas.drawPath(path,paint);
6,绘制点
绘制点就比较简单了,这三个函数也不难理解,跟绘制直线那三个函数差不多
float[] ps = {20,30,150,180,180,40,90,100,50,60,70,130};
canvas.drawPoints(ps,paint);
这个就不细说了
7.绘制矩形和圆角矩形
这个也比较好理解
//Rect rect = new Rect(20,20,300,300);
RectF rectF = new RectF(20,20,300,300);
canvas.drawRect(rectF,paint);
RectF rectF = new RectF(20,20,300,300);
canvas.drawRoundRect(rectF,50,50,paint);
第2,3个参数表示x,y方向上弧度。
8.绘制文本:
绘制文本的函数较多,但是常用就那么一两个,其他就不分析了
canvas.drawText("Android",60,60,paint);
绘制bitmap的函数也较多,不细说了
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
canvas.drawBitmap(bitmap,70,70,paint);
我们自定义View可能不单单只绘制一种图形,而是多种图形一起绘制。
而且在绘制图形的时候,还要考虑画布位置的变换(translate(float dx, float dy))和画布的保存与恢复(save()、restore())
关于canvas的变换,参考http://blog.csdn.net/harvic880925/article/details/39080931
本文就介绍这么点