2018-05-16—自定义控件之Paint,Canvas,Path使用

在我们之前做项目的时候,肯定是用到过很多控件的,那些都是系统或者别人设计出来的。看到那些炫酷美观的界面,你有没有想过设计一款属于自己的View控件呢?从今开始我们将学习一下如何设计自定义View。

首先自定义View分为三种类型:自定义View(继承View),自定义ViewGroup(继承ViewGroup)和,在原有的控件基础进行功能拓展(继承其他控件)。

我们先从自定义View开始看。今天我们主要说在里面一个比较重要的方法,onDraw方法:

2018-05-16—自定义控件之Paint,Canvas,Path使用
onDraw

我们去看一下官方给他的注释,很简单的一句话

2018-05-16—自定义控件之Paint,Canvas,Path使用
onDraw注释

解释一下,用这个画你的画。我们现在不需要了解太多,只要知道我们view长什么样子,是靠他完成的就行了。

关于这个方法,我们要使用三个很重要的对象:Canvas,Paint,和Path,我们绘制主要就是用这三个类完成的。


一、Paint类

Paint中文是油漆的意思,其实就是画笔的意思,我们来看一下Paint的主要方法:

2018-05-16—自定义控件之Paint,Canvas,Path使用
paint类主要方法

我们通过上述一系列方法,更改我们画笔的属性,然后画出来不一样的效果。

有笔还得有纸,接下来我们看一下起到纸作用的类:Canvas类。


二、Canvas类

Canvas帆布的意思。他的方法就不全列举了,我们一边讲解,一遍使用。

在此之前,先说一下Canvas的坐标:

2018-05-16—自定义控件之Paint,Canvas,Path使用

同我们平时数学书中见到的坐标系不一样,Canvas中的y正半轴向下。我们的画布就从原点开始向x、y轴扩散。

画线:

2018-05-16—自定义控件之Paint,Canvas,Path使用

我们来说一下这几个参数,前两个是起始点的坐标,随后两个是结束点的坐标,最后一个是画笔对象,看到这几个参数大家应该就能看懂,我们设置起始点和结束点,然后在这两个点之间画一条线段,然后线段的粗细颜色都由我们自己通过paint来改变。

2018-05-16—自定义控件之Paint,Canvas,Path使用
效果1

画一个矩形:

2018-05-16—自定义控件之Paint,Canvas,Path使用

我们通过drawRect方法来实现画矩形,他有三个构造方法,前两个很像,只是第一个参数一个传入RectF对象,一个传入Rect对象,这两个对象都是创建一个矩形,只是一个参数是float类型,一个是int类型,所以前两个方法就不用多说了吧。

最后一个我们分别指定左、上、右、下四条边和x,y轴的偏移量。

2018-05-16—自定义控件之Paint,Canvas,Path使用

这里大家能看懂吧。

画一个圆或椭圆:

2018-05-16—自定义控件之Paint,Canvas,Path使用
2018-05-16—自定义控件之Paint,Canvas,Path使用

有了上面的了解,大家应该知道这些参数的意义了吧。画圆这里我们不说了,我们看一下椭圆。

其实椭圆也能画成圆,这要看我们指定的矩形是长方形还是正方形。

这里不展示了。

画弧:

2018-05-16—自定义控件之Paint,Canvas,Path使用

前几个参数不说了,看的都吐了。我们看一下后面几个参数:

startAngle:起始角度,0是水平最右边。

sweepAngle:顺时针划过的角度。

useCenter:起始和结束位置是否和圆心连接。

2018-05-16—自定义控件之Paint,Canvas,Path使用

对应代码和效果如上所示。我画了一个半圆,起始位置为0,所以从右水平顺时针划过180度,然后规定连接圆心。

裁剪:

2018-05-16—自定义控件之Paint,Canvas,Path使用

关于裁剪的方法实在是太多了,我们举两个例子就好。

2018-05-16—自定义控件之Paint,Canvas,Path使用

这是官方给出的clipRect方法的介绍:让当前的裁剪和我们指定的矩形相交。

关于裁剪方法的官方文档说的话非常绕,我们这么理解:

我们从canvas上面裁下来一块图形,这个图形是我们自己选择的(Rect或者Path画出来),然后我们画的范围就只是在这个裁剪的矩形之内了。

2018-05-16—自定义控件之Paint,Canvas,Path使用

过时的方法我们不说了(这几个过时的方法是真的恶心,就是因为最后那个参数-。+)。

2018-05-16—自定义控件之Paint,Canvas,Path使用

我们可以看到从(0,0)点到(550,850)的一条线段只是显示了一部分,这一部分就是我们裁剪了之后的那个部分。

绘制文字:

我们还可以在canvas上绘制文字。

2018-05-16—自定义控件之Paint,Canvas,Path使用

他有四个构造方法,我们看一下最简单的第二个-。+;

x:被绘制文本所在矩形的原点横坐标

y:被绘制文本所在矩形的原点纵坐标(基线坐标)

2018-05-16—自定义控件之Paint,Canvas,Path使用

这张图表示的应该很清楚了吧,蓝色框是文本的相关矩形,左下角的黑色点是他的原点坐标。

这里我们要返回去看我们Paint中的一个方法:setTextAlign(enum);这个方法指定了我们的文本显示在原点左侧还是右侧,还是居中。

2018-05-16—自定义控件之Paint,Canvas,Path使用

我们看到他是从100,500这个点往右显示的,所以我们如果不指定setTextAlign的话,他默认是LEFT。

我上面还有两个方法, save和restore。我们注意到了,上面我们已经指定了画布范围为裁剪之后的矩形,而现在居然又显示出来了。这就是save和restore方法的作用。

save方法让我们将当前的画布压入一个临时的栈中,而restore方法会让我们将从这个栈中取出栈顶的canvas。所以我们上得到了没有裁剪的canvas。

2018-05-16—自定义控件之Paint,Canvas,Path使用

以上是根据官方文档和自己的理解综合的一段画,我们综合上面的例子来看一下:

首先一开始我们就调用save方法,在此之前我们除了drawLine方法没有进行过上面四种任意变换,所以没什么变化。我们把这个状态存入栈中。

然后我们就裁剪了一个矩形。在上面画线,因为现在已经只是显示当前这裁剪的矩形了,所以我们的线段只是显示了一个部分。

然后我们调用了restore方法,我们栈中唯一存储的状态取出来。这时候显示之前裁剪的效果已经消失,但是之前画的那一条线段还在。

最后我们写了一行字:屙屎那沙壁!!。。。。。

现在Canvas常用的方法已经说完了。我们在上面使用的时候间接地提到了Path这个类,那最后我们来看一下这个Path类:


Path类

path为路径的意思,其实这个类的效果和绘制差不多,只不过它并不是局限于上述几种图形,因为我们是一个一个点的移动,让他点动成线,从而形成图像。

就和我们走路走出来一个个脚印,然后连起来就是一个图像了。

2018-05-16—自定义控件之Paint,Canvas,Path使用

其实path他的方法和canvas特别像,他也可以画上面说的那些图像(圆,弧,椭圆,矩形,线段)。只是他每个构造方法(除了lineTo和moveTo)最后都偶一个Direction参数,我们来说一下这个参数的作用:

Direction为一个枚举类型,他有两个量,CW表示顺时针CCW表示逆时针。

2018-05-16—自定义控件之Paint,Canvas,Path使用

因为Path是点动成线图,所以我们是有顺序的,要制定顺时针还是逆时针。

最后说一下path的close方法。

2018-05-16—自定义控件之Paint,Canvas,Path使用

我先把画笔移动到(100,600)这个点,然后先竖后横画了两条线。最后我们调用了close方法。

我们发现没画斜线啊他怎么连起来了,这就是我们close方法的作用:

2018-05-16—自定义控件之Paint,Canvas,Path使用

这是close方法注解:关闭当前的轮廓,如果发现当前的点和起始点的点不在一个等高线,就添加从起始点到最后点。

说到这里大家应该明白为什么会有一条斜着的线段了。



好了,这是我们绘制过程中三个主要的类的基本用法。在这个上面坑时特别多的,笔者关于这些东西已经捣鼓了整整两天了。但是无论多么复杂的效果和代码,我们首先要知道他的基本效果和作用,那么在复杂的分析也不会乱啦。