前言
在上一篇文章中,我们学习了自定义View的基本流程和一些相关知识,想必大家对自定义View多少都有了一定的了解。
今天我们就到代码的层次来看下如何实现和使用自定义View吧
在前面的文章中我们已经学习了Flutter中自定义View的简单步骤,今天我们就按照这个步骤来实现下自定义View。
首先,我们新建类继承于CustomPainter并且实现CustomPainter里面的paint()和shouldRepaint方法。
paint方法就是Flutter中负责View绘制的地方,使用传递来的canvas和size即可完成对目标View的绘制。
shouldRepaint是控制自定义View是否需要重绘的,返回fals代表这个View在构建完成后不需要重绘。
canvas中有多个与绘制相关的方法,如drawLine()、drawRect()、drawOval()、drawOval()、等方法。
但是,仅仅使用canvas这个画布还不够,我们还需要一个画笔paint,我们使用如下代码来构建paint
当然,在正常的开发中一般不会使用这么多的属性,大家可以根据需要去具体的了解和使用。
举个简单的例子
正如上面代码看到的,我们设置画笔的颜色为蓝色,打开抗锯齿、设置笔触的类型为圆角并且设置画笔的宽度为5.0像素。
然后在绘制的时候,绘制了一条直线,从左边(20,20)的位置到坐标为(100,100)的位置,好了这样我们便完成了最简单的view绘制。
但是,现在我们并不能去运行这个程序,我们自定义的view从根本也不是一个Widget,所以也没法直接在Widget tree中去构建,所以这个时候就要借助与CustomPaint来给我们自定义的CustomPainter来做渲染。
CustomPaint就是继承于SingleChildRenderObjectWidget的一个Widget,使用时你只需要传入你自定义的CustomPainter即可,当然CustomPaint也可以传入自己的child widget来完成Widget的组合。
下面还是来看下完整的代码:
看下效果:
当然,我们可以随意改变画笔的颜色或者多绘制几条直线?
刚才我们看了下绘制直线,接下来看一下其他绘制相关的方法。
drawPoints(PointMode pointMode, List points, Paint paint)
绘制点也是非常的简单,只需要传入PointMode枚举,坐标list和paint即可
PointMode的枚举类型有三个,points(点),lines(线,隔点连接),polygon(线,相邻连接)
看下面的代码:
为了方便演示,我们在上面定义了7个点,第一个和最后一个点重合。
然后我们设置PointMode为points看下效果。
然后我们把PointMode改为lines
跟大家想象中的一样吗?
PointMode为lines时,两个点相互连接,也就是说第一个和第二个点连接,第三个跟第四个连接,如果最后只有一个点就舍弃不连接了,在我们的例子中有7个点,所以图中只有三条连线。
然后我们把PointMode改为lines
对,你看的没有错跟上面绘制线段的效果是一样的,相邻点互相连接。
canvas.drawCircle(offset, radius, paint)
绘制圆也很简单,仅仅圆心的坐标、半径和paint即可。
来看下用法:
可以看到我们在坐标(100,100)的位置绘制了一个半径为红色的圆。
但是,我们可以看到这个圆都被红色填充了,明明我们在前面定义画笔的宽度为5来着,怎么回填充满呢?
其实是因为,paint的默认绘画风格为填充,我们尝试把style改为PaintingStyle.stroke。
再来看下效果:
drawOval(Rect rect, Paint paint)
绘制椭圆就相对简单很多,只需要传入Rect和paint即可,在前面我们已经讲过了使用Rect便可确认这个矩形的大小和位置。
其实,Rect也有多种构建方式:
fromPoints(Offset a, Offset b) 使用左上和右下角坐标来确定矩形的大小和位置 fromCircle({ Offset center, double radius }) 使用圆的圆心点坐标和半径和确定外切矩形的大小和位置 fromLTRB(double left, double top, double right, double bottom) 使用矩形左边的X坐标、矩形顶部的Y坐标、矩形右边的X坐标、矩形底部的Y坐标来确定矩形的大小和位置 fromLTWH(double left, double top, double width, double height) 使用矩形左边的X坐标、矩形顶部的Y坐标矩形的宽高来确定矩形的大小和位置
所以,这4种方式无论你使用那种都是一样的,都可以确定这个矩形的位置和大小,淡然这个椭圆也是在这个矩形之中内切的。
Rect rect1= Rect.fromPoints(Offset(50.0, 50.0), Offset(130.0, 100.0)); canvas.drawOval(rect1, _paint);
宽度大于高度的椭圆
Rect rect2= Rect.fromPoints(Offset(50.0, 150.0), Offset(130.0, 300.0)); canvas.drawOval(rect2, _paint);
高度大于宽度的椭圆
Rect rect3= Rect.fromPoints(Offset(50.0, 320.0), Offset(130.0, 400.0)); canvas.drawOval(rect3, _paint);
高度等于宽度的,对不起这是圆
drawArc(Rect rect, double startAngle, double sweepAngle, bool useCenter, Paint paint)
绘制圆弧也很简单,首先还是需要Rect来确认圆弧的位置,还需要开始的弧度、结束的弧度、是否使用中心点绘制、以及paint。
弧度
根据定义,一周的弧度数为2πr/r=2π,360°角=2π弧度,因此,1弧度约为57.3°,即57°17’44.806’’,1°为π/180弧度,近似值为0.01745弧度,周角为2π弧度,平角(即180°角)为π弧度,直角为π/2弧度。
一些特殊的弧度:
度 | 弧度 |
---|---|
0° | 0 |
30° | π/6 |
45° | π/4 |
60° | π/3 |
90° | π/2 |
120° | 2π/3 |
180° | π |
270° | 3π/2 |
360° | 2π |
看下例子:
我们定义π为3.1415926,定义开始的角度为0°扫过的角度为PI / 2(90°),设置userCenter为false
看下效果:
看起来好像真的是90°啊,还是打开userCenter看下效果。
嗯,这样看来确实是一个90°的圆弧啊。
drawRRect(RRect rrect, Paint paint)
其实使用起来也是非常的简单,使用RRect确定矩形大小及弧度,使用paint来完成绘制。
RRect构建起来也非常的方便,直接使用fromRectAndRadius即可
RRect.fromRectAndRadius(rect, radius)
rect依然用来表示矩形的位置和大小,radius用来表示圆角的大小。
设置圆角度数为5
设置圆角度数等于Rect radius大小。
drawDRRect(RRect outer, RRect inner, Paint paint)
和drawRRect类似,使用RRect确定内部、外部矩形大小及弧度,使用paint来完成绘制。
我们使用Rect.fromCircle来创建Rect,使用RRect.fromRectAndRadius来创建RRect
可以看到两个圆角矩形哦,淡然我们可以尝试调整角度的度数大小。
当然,你可以可以调整两个圆弧的位置来获得交叉的圆弧效果。
好了,今天先说这么多,还有一些其他的绘制方法下篇文章再来看,哈
把今天讲到的绘制方法都尝试下,包括paint的属性等。