我需要一个将移动的正弦和余弦函数绘制到画布中的加载小部件。我使用 CustomPaint 小部件和 CustomPainter 毫无问题地对其进行了编码,但是当我对其进行分析时,我发现它以大约 49 fps 的速度运行,而不是 60 fps。UI 线程运行良好,每帧大约需要 6 毫秒,但 Raster 线程需要更长的时间。我尝试在画布上绘制更少的点(在 for 循环中执行 i=i+5 而不是 i++),但结果完全相同。
¿ 有人可以建议我如何提高性能吗?下面是小部件代码,以及 Raster 线程在每一帧中所做的 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:我在配置文件模式下运行应用程序,所以这不应该是问题。我还想提一下,它是唯一在屏幕上重绘的小部件。非常感谢!!