我需要一个可以将正弦和余弦函数绘制到画布上的加载小部件。我使用CustomPaint小部件和CustomPainter编写了代码,但是当我对其进行分析时,发现它运行在约49fps而不是60fps。UI线程工作良好,每帧大约需要6ms,但光栅线程需要更长时间。我尝试在画布上绘制更少的点(在for循环中使用i=i+5代替i++),但结果几乎相同。
有人能否建议我如何提高性能的想法?下面是该小部件的代码,以及每帧光栅线程执行情况的DevTools截图,如果有用的话。
import 'dart:math';
import 'package:flutter/material.dart';
class LoadingChart extends StatefulWidget{
final Color color1;
final Color color2;
final double lineWidth;
final bool line;
final Size size;
const LoadingChart({
@required this.color1,
@required this.color2,
@required this.size,
@required this.lineWidth,
this.line = true,
Key key
}): super(key: key);
@override
State<StatefulWidget> createState() => _LoadingChartState();
}
class _LoadingChartState extends State<LoadingChart>
with SingleTickerProviderStateMixin{
AnimationController _controller;
double randomHeight(Random random, double max){
return random.nextDouble()*max;
}
@override
void initState() {
_controller = AnimationController(vsync: this, duration: Duration(seconds: 1));
_controller.addListener(() {setState(() {});});
_controller.repeat();
super.initState();
}
@override
void dispose(){
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SizedBox(
height: widget.size.height,
width: widget.size.width,
child: CustomPaint(
painter: PathPainter(
color1: widget.color1,
color2: widget.color2,
value: _controller.value,
line: widget.line,
),
)
);
}
}
class PathPainter extends CustomPainter {
final Color color1;
final Color color2;
final double lineWidth;
final bool line;
final double value;
PathPainter({
@required this.value,
this.color1=Colors.red,
this.color2=Colors.green,
this.line = true,
this.lineWidth=4.0,
}): super();
@override
void paint(Canvas canvas, Size size) {
final height = size.height;
final width = size.width;
Paint paint1 = Paint()
..color = color1
..style = PaintingStyle.stroke
..strokeWidth = lineWidth;
Paint paint2 = Paint()
..color = color2
..style = PaintingStyle.stroke
..strokeWidth = lineWidth;
Path path1 = Path();
Path path2 = Path();
/* If line is true, draw sin and cos functions, otherwise, just some points */
for (double i = 0; i < width; i=i+5){
double f = i*2*pi/width + 2*pi*value;
double g = i*2*pi/width - 2*pi*value;
if (i == 0){
path1.moveTo(0, height/2 + height/6*sin(f));
path2.moveTo(0, height/2 + height/6*cos(g));
continue;
}
path1.lineTo(i, height/2 + height/6*sin(f));
path2.lineTo(i, height/2 + height/6*cos(g));
}
/* Draw both lines */
canvas.drawPath(path1, paint1);
canvas.drawPath(path2, paint2);
}
@override
bool shouldRepaint(PathPainter oldDelegate) {
return oldDelegate.value != value || oldDelegate.color1 != color1
|| oldDelegate.color2 != color2 || oldDelegate.line != line
|| oldDelegate.lineWidth != lineWidth;
}
}
PS:我正在使用配置文件模式运行应用程序,因此这不应该是问题。另外,我想提一下,它是屏幕上唯一重新绘制的小部件。 非常感谢!
setState
,所以基本上我在这里做的就是一样的。 - Javierd98