啊......这......
这种很鸡肋的需求,是来自WX某公众号推送的恰饭文章中偶然发现的,整体为弧形卡片设计的音乐播放器,包括音乐播放的进度条,而后觉得弧形进度条因吹斯汀,翻遍已有的Flutter教程帖后,并没有发现类似的帖子,所以我来了!
本人Flutter萌新,第一次发文章,代码写的比较烂,还望大佬嘴下留情......
话不多说,直接开整:
一、进度条的属性以及成员变量
Flutter中为我们提供了封装好的组件CustomerPaint
Widget,这个组件与画笔Paint
Widget组合使用就可以绘制出需要的图形,在这之前,我们需要先创建一个继承于基类的绘制类。
进度条最直观的就是颜色,因此就需要前景色和背景色,初次之外还有其他参数,这里就不一一列举了,直接上代码:
class Progress extends CustomPainter {
final Color backgroundColor; //背景色
final Color progressColor; //前景色
final double startPointAngle; //Canvas绘制开始位置
final double endPointAngle; //结束位置
final bool centerClose; //圆弧是否闭合
final double radius; //半径
final double lineWidth; //所绘制线条的宽度
final double value; //进度条的value
final TextStyle style; //进度条文本风格(非必须)
final String completeText; //进度条文本(非必须)
const Progress(
{this.backgroundColor,
this.progressColor,
this.startPointAngle,
this.endPointAngle,
this.centerClose,
this.radius,
this.lineWidth,
this.value,
this.style,
this.completeText});
}
如上所述,列举了一些基本的属性,也可以根据需要添加其他参数
二、初始化画笔Paint
,调用Canvas
绘制图形
在绘制类中重写paint()
和shouldRepaint()
方法
在我们所创建的继承于基类CustomPainter
的绘制类中,会有如下两个方法,需要我们进行重写:
class ProgresPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
// TODO: implement paint
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
return null;
}
重写paint()
方法:
void paint(Canvas canvas, Size size) {
// TODO: implement paint
Paint paint = Paint() //初始化画笔
..color = backgroundColor //背景颜色
..style = PaintingStyle.stroke //画笔样式
..strokeCap = StrokeCap.round //画笔笔头类型
..strokeWidth = lineWidth; //画笔的宽度
Rect rect = Rect.fromCircle(
center: Offset(size.width / 2, size.height / 2), radius: radius);
//通过Canvas绘制一条弧线
canvas.drawArc(rect, startPointAngle, endPointAngle, centerClose, paint);
//背景弧线绘制完成
paint
..color = progressColor //前景色
..strokeWidth = lineWidth + 1.0 //画笔宽度,在这里我们设置得比背景的宽度稍宽些
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round;
canvas.drawArc(
rect, startPointAngle, endPointAngle * value, centerClose, paint);
}
//前景弧线绘制完成
重写shouldRepaint()
方法:
bool shouldRepaint(CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
return true;
}
三、在其他Widget中使用绘制好的进度条
为了更快捷的预览到进度条的效果,在这里我们直接使用Slider
Widget来控制value
的值。
首先,创建一个StatefulWidget
:
class ArcProgress extends StatefulWidget {
double value; //在其他地方调用该Widget时,可以直接给value赋值
ArcProgress({
this.value,
});
@override
_ArcProgressState createState() => _ArcProgressState();
}
class _ArcProgressState extends State<ArcProgress> {
@override
Widget build(BuildContext context) {
return CustomPaint(
child: Slider( //在这里我们直接使用Slider对value进行赋值,实际使用时,应当移除
value: widget.value,
onChanged: (value) {
setState(() {
widget.value = value;
});
}),
painter: Progress(
backgroundColor: Colors.grey, //设置背景色
progressColor: Colors.amber, //设置前景色
radius: MediaQuery.of(context).size.width, //设置背景色
lineWidth: 5.0, //设置线条宽度(此处为背景线条宽度)
startPointAngle: math.pi - (math.pi / 9), //设置起始点
endPointAngle: -(7 * math.pi / 9),
centerClose: false, //是否闭合,闭合后即为扇形
value: widget.value,
),
);
}
}
==在其他Widget中直接使用
CustomPainter
绘制的图形时,一定要在父控件的child里使用CustomPaint
进行包裹==
到这里,就已经完成了绘制和使用了。此文章并没有什么技术可言,初次发文,希望大家见谅