自定义View ——Canvas之绘制基本形状

自定义View ——Canvas之绘制基本形状##

转载出处:http://www.gcssloop.com/customview/Canvas_Convert/

一.Canvas简介###

Canvas 称之为画布,是安卓平台2D图形绘制的基础,非常强大。

一般来说,比较基础的东西有两大特点:

1.可操作性强:由于这些是构成上层的基础,所以可操作性必然十分强大。

2.比较难用:各种方法太过基础,想要完美的将这些操作组合起来有一定难度。

本系列文章不仅会介绍到Canvas的操作方法,还会简单介绍一些设计思路和技巧。

二.Canvas的常用操作速查表##

列表:

操作类型 相关API 备注
绘制颜色 drawColor,drawRGB,drawARGB 使用单一颜色填充整个画布
绘制基本形状 drawPoint,drawPoints,drawLine,drawLines,drawRect,drawRountRect,drawOval,drawCircle,drawArc 依次为点、线、矩形、圆角矩形、椭圆、圆、圆弧
绘制图片 drawBitmap,drawPicture 绘制位图和图片
绘制文本 drawText,drawPosText,drawTextOnPath 依次为 绘制文字、绘制文字时指定每个文字位置、根据路径绘制文字
顶点操作 drawVertices,drawBitmapMesh 通过对顶点操作可以使图像形变,drawVertices直接对画布作用、drawBitmapMesh只对绘制的Bitmap作用
绘制路径 drawPath 绘制路径,绘制贝塞尔曲线时也需要用该函数
画布剪裁 clipPath,clipRect 设置画布的显示区域
画布快照 save,restore,saveLayerXxx,restoreToCount,getSaveCount 依次为保存当前状态、回滚到上一次保存的状态、保存图层状态、回滚到指定状态、获取保存次数
画布变换 translate,scale,rotate,skew 依次为位移、缩放、旋转、错切
Matrix矩阵 getMatrix、setMatrix、concat 实际画布的位移,缩放等操作的都是图像矩阵Matrix,只不过Matrix比较难以理解和使用,故封装了一些常用的方法。

三、Canvas详解###

本篇内容主要讲解如何利用Canvas绘制基本图形。

绘制颜色:

绘制颜色是填充整个画布,常用于绘制底色。

代码:

canvas.drawColor(Color.BLUE);//绘制蓝色

如图:

自定义View ——Canvas之绘制基本形状_第1张图片

创建画笔:

想绘制内容,首先需要先创建一个画笔,如下:
//创建一个画笔
private Paint mPaint=new Paint();
//初始化画笔
private void initPaint(){
mPaint.setColor(Color.BLACK); //设置画笔颜色
mPaint.setStyle(Paint.Style.FILL); //设置画笔模式为填充
mPaint.setStrokeWidth(10f); //设置画笔宽度为10px
}
//在构造函数中初始化
public SloopView(Context context,AttributeSet attrs){
super(context,attrs);
initPaint();
}

在创建完画笔之后,就可以在Canvas中绘制各种内容了。


绘制点:###

可以绘制一个点,也可以绘制一组点,如下:

canvas.drawPoint(200,200,mPaint);
canvas.drawPoints(new float[]{
    500,500,
    500,600,
    500,700
},mPaint);

关于坐标原点默认在左上角,水平向右为x轴增大方向,竖直向下为y轴增大方向。

自定义View ——Canvas之绘制基本形状_第2张图片

绘制直线:###

绘制直线只需要两个点,初始点和结束点,同样绘制直线也可以绘制一条或者绘制一组:

canvas.drawLine(300,300,500,500,mPaint);//在坐标(300,300)(500,600)之间绘制一条直线
canvas.drawLines(new float[]{            //绘制一组线  每四位数字(两个点的坐标)确定一条线
100,200,200,200,
100,300,200,200
},mpaint);
自定义View ——Canvas之绘制基本形状_第3张图片

绘制矩形:###

确定确定一个矩形最少需要四个数据,就是对角线的两个点的坐标值,这里一般采用左上角和右下角的两个点的坐标。

关于绘制矩形,Canvas提供了三种重载方法,第一种就是提供四个数值(矩形左上角和右下角两个点的坐标)来确定一个矩形进行绘制。其余两种是先将矩形封装为Rect或者RectF(实际上仍然是用两个坐标点来确定的矩形),然后传递给Canvas绘制,如下:
//第一种
canvas.drawRect(100,100,800,400,mPaint);
//第二种
Rect mRect=new Rect(100,100,800,400);
canvas.drawRect(mRect,mPaint);
//第三种
RectF mRectF=new RectF(100,100,800,400);
canvas.drawRect(mRectF,mPaint);

三种绘制的结果是完全一样的。


自定义View ——Canvas之绘制基本形状_第4张图片

绘制圆角矩形###

绘制圆角矩形也提供了两种重载方式,如下:
//第一种
RectF mRectF=new RectF(100,100,800,400);
canvas.drawRoundRect(mRectF,30,30,mPaint);
//第二种
canvas.drawRoundRect(100,100,800,400,30,30,mPaint);

第二种方法在API21的时候才添加上,所以我们一般使用的都是第一种。


自定义View ——Canvas之绘制基本形状_第5张图片

与矩形相比,圆角矩形多出来了两个参数rx和ry,这里圆角矩形的角实际上不是一个正圆的圆弧,而是椭圆的圆弧,这里的两个参数实际上是椭圆的两个半径,他们看起来如下图:


自定义View ——Canvas之绘制基本形状_第6张图片

红线标注的rx与ry就是两个半径,也就是相比绘制矩形多出来的那两个参数。

我们了解到原理后,就可以为所欲为了,通过计算可知我们上次绘制的矩形宽度为700,高度为300,当你让rx大于350(宽度的一半),ry大于150(高度的一半)时奇迹就出现了,你会发现圆角矩形变成了一个椭圆,他们画出来是这样的(为了方便确认我更改了画笔颜色,同时绘制出了矩形和圆角矩形):

//矩形
RectF  mRectF=new RectF(100,100,800,400);
//绘制背景矩形
mPaint.setColor(Color.GRAY);
canvas.drawRect(mRectF,mPaint);
//绘制圆角矩形
mPaint.setColor(Color.BLUE);
canvas.drawRoundRect(mRectF,700,400,mPaint);
自定义View ——Canvas之绘制基本形状_第7张图片

其中灰色部分是我们所选定的矩形,而里面的圆角矩形则变成了一个椭圆,实际上rx为宽度的一半,ry为高度的一半时,刚好是一个椭圆,通过上面我们分析的原理推算一下就能得到,而当rx大于宽度的一半,ry大于高度的一半时,实际上是无法计算出圆弧的,所以drawRoundRect对大于该数值的参数进行了限制,凡是大于一半的参数均按照一半来处理。

绘制椭圆:###

相对于绘制圆角矩形,绘制椭圆就简单的多了,因为他只需要一个矩形作为参数:

//第一种
RectF  rectF=new RectF(100,100,800,400);
canvas.drawOval(rectF,mPaint);
//第二种
canvas.drawOval(100,100,800,400,mPaint);

以上两种方法效果完全一样,但一般使用第一种。


自定义View ——Canvas之绘制基本形状_第8张图片

绘制椭圆实际上就是绘制一个矩形的内切图形,原理如下:

自定义View ——Canvas之绘制基本形状_第9张图片

绘制圆:###

如下:

canvas.drawCircle(500,500,400,mPaint);//绘制一个圆心坐标在(500,500),半径为400的圆。

绘制圆形有四个参数,前两个是圆心坐标,第三个是半径,最后一个是画笔。


自定义View ——Canvas之绘制基本形状_第10张图片

绘制圆弧:

// 第一种
public void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint){}

// 第二种
public void drawArc(float left, float top, float right, float bottom, float startAngle,
        float sweepAngle, boolean useCenter, @NonNull Paint paint) {}

从上面可以看出,相比于绘制椭圆,绘制圆弧还多了三个参数:

startAngle //开始角度
sweepAngle    //扫过角度
useCenter    //是否使用中心

上代码:

RectF rectF = new RectF(100,100,800,400);
// 绘制背景矩形
mPaint.setColor(Color.GRAY);
canvas.drawRect(rectF,mPaint);

// 绘制圆弧
mPaint.setColor(Color.BLUE);
canvas.drawArc(rectF,0,90,false,mPaint);

//-------------------------------------

RectF rectF2 = new RectF(100,600,800,900);
// 绘制背景矩形
mPaint.setColor(Color.GRAY);
canvas.drawRect(rectF2,mPaint);

// 绘制圆弧
mPaint.setColor(Color.BLUE);
canvas.drawArc(rectF2,0,90,true,mPaint);

上述代码实际上是绘制了一个起始角度为0度,扫过90度的圆弧,两者的区别就是是否使用了中心点,结果如下:

自定义View ——Canvas之绘制基本形状_第11张图片

相比于使用椭圆,我们还是使用正圆比较多的,使用正圆展示一下效果:

RectF  rectF= new RectF(100,100,800,400);
//绘制背景矩形
mPaint.setColor(Color.GRAY);
canvas.drawRect(rectF,mPaint);
//绘制圆弧
mPaint.setColor(Color.BLUE);
canvas.drawArc(rectF,0,90,false,mPaint); 
//-----------------------------------------------------

RectF  rectF2= new RectF(100,600,800,900);
//绘制背景矩形
mPaint.setColor(Color.GRAY);
canvas.drawRect(rectF2,mPaint);
//绘制圆弧
mPaint.setColor(Color.BLUE);
canvas.drawArc(rectF2,0,90,true,mPaint);
自定义View ——Canvas之绘制基本形状_第12张图片

简要介绍Paint###

看了上面这么多,相信有一部分人会产生一个疑问,如果我想绘制一个圆,只要边不要里面的颜色怎么办?

很简单,绘制的基本形状由Canvas确定,但绘制出来的颜色,具体效果则由Paint确定。

    mPaint.setStyle(Paint.Style.FILL);//设置画笔模式为填充

为了展示方便,容易看出效果,之前使用的模式一直为填充模式,实际上画笔有三种模式,如下:
STROKE //描边
FILL //填充
FILL_AND_STROKE //描边加填充

为了区分三者效果我们做如下实验:

    Paint paint = new Paint();
    paint.setColor(Color.BLUE);
    paint.setStrokeWidth(40);

    //描边
    paint.setStyle(Paint.Style.STROKE);
    canvas.drawCircle(200,200,100,paint);

    //填充
    paint.setStyle(Paint.Style.FILL);
    canvas.drawCircle(200,500,100,paint);
    
    //描边加填充
    paint.setStyle(Paint.Style.FILL_AND_STROKE);
    canvas.drawCircle(200,800,100,paint);
自定义View ——Canvas之绘制基本形状_第13张图片

如果想系统学习自定义View,推荐看作者GcsSloop系列文章###

你可能感兴趣的:(自定义View ——Canvas之绘制基本形状)