注意:这其实是一篇CustomPaint的使用教程!!
源码地址:https://github.com/yumi0629/FlutterUI/tree/master/lib/circleprogressbar
在Flutter中,CustomPaint
就像是Android中的Paint一样,可以用它绘制出各种各样的自定义图形。确实,Paint的使用比较复杂,我觉得直接讲API的话也太无聊了,要记住Paint的用法,还是自己动手画一个比较实在。
那为什么是画一个CircleProgressBar呢?其实这个控件本来是为了交作业的,之前在讲Hero的时候留了一个小练习,里面有一个页面,有一个很炫酷的圆形ProgressBar选择器,当时为了偷懒我就没写(不要打我),所以现在来补交来。在写这个CircleProgressBar的时候发现,CustomPaint
中基本的API都使用到了,画圆、画弧线、画布旋转、Paint的各种属性的意义等等知识点都有涉及到。所以说,看完这篇文章,你绝对可以自己动手尝试画一些炫酷的UI控件来!
国际惯例,先上效果图:
const CustomPaint({
Key key,
this.painter,
this.foregroundPainter,
this.size = Size.zero,
this.isComplex = false,
this.willChange = false,
Widget child,
})
CustomPaint
是一个继承自SingleChildRenderObjectWidget
的控件,所以注意,不能用setState的方式来刷新它!!painter
就是我们的主绘制工具,它是一个CustomPainter
;foregroundPainter
是用来绘制前景的工具;size
为画布大小,这个size会传递给Painter
;isComplex
和willChange
是告诉Flutter你的CustomPaint
是否复杂到需要使用cache相关的功能;child
属性我们一般不填,即使你是想要在你的CustomPaint
上添加一些其他的布局,也不建议放在child属中性,因为你会发现你并不会得到你想要的结果。
所有的绘制都是发生在Painter里面的,绘制的代码写在我们的自定义CustomPainter
中:
class ProgressPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
// 绘制代码
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
我们需要重写paint()
和shouldRepaint()
这两个方法,一个是绘制流程,一个是在刷新布局的时候告诉Flutter是否需要重绘。注意下paint
方法中的size参数,就是我们在CustomPaint
中定义的size属性,它包含了基本的画布大小信息。
真正地绘制则是通过canvas
和Paint
来实现的,我们将定义好了的Paint画笔传递给canvas.drawXXX()
方法,这个方法会告诉Flutter我们需要绘制一个什么东西,是一个圆呢、还是一条线呢?
一些常用的canvas
绘制API:
// 绘制弧线
drawArc(Rect rect, double startAngle, double sweepAngle, bool useCenter, Paint paint)
// 绘制图片
drawImage(Image image, Offset p, Paint paint)
// 绘制圆
drawCircle(Offset c, double radius, Paint paint)
// 绘制线条
drawLine(Offset p1, Offset p2, Paint paint)
// 绘制椭圆
drawOval(Rect rect, Paint paint)
// 绘制文字
drawParagraph(Paragraph paragraph, Offset offset)
// 绘制路径
drawPath(Path path, Paint paint)
// 绘制点
drawPoints(PointMode pointMode, List points, Paint paint)
// 绘制Rect
drawRect(Rect rect, Paint paint)
// 绘制阴影
drawShadow(Path path, Color color, double elevation, bool transparentOccluder)
一些常用的Paint
属性:
color:画笔颜色
style:绘制模式,画线 or 充满
maskFilter:绘制完成,还没有被混合到布局上时,添加的遮罩效果,比如blur效果
strokeWidth:线条宽度
strokeCap:线条结束时的绘制样式
shader:着色器,一般用来绘制渐变效果或ImageShader