我试图了解shouldRepaint的工作原理。我找到了一个教程,该教程在圆圈按钮周围绘制了一个表盘,以显示其值。该示例让shouldRepaint始终返回true。基本上,它只是在按钮周围绘制了一个局部圆圈以显示%值。如果值为50,则圆会绕过一半。
我将shouldRepaint设置为始终返回false,以查看会发生什么。仍然可以正确地绘制按钮圆圈。
我的理论是,当重绘有状态的小部件时,它将始终绘制。因此,当按钮值从40%变为50%时,无论如何,小部件都会重新绘制并完成绘制。
因此,如果状态改变时我的窗口小部件仍然被绘制,我什么时候应该使用shouldRepaint?
以下是该教程中的相关代码:
class HomeContent extends StatefulWidget {
@override
_HomeContentState createState() => _HomeContentState();
}
class _HomeContentState extends State<HomeContent> {
int percentage;
@override
void initState() {
super.initState();
setState(() {
percentage = 0;
});
}
@override
Widget build(BuildContext context) {
return new Center(
child: new Container(
height: 200.0,
width: 200.0,
child: new CustomPaint(
foregroundPainter: new MyPainter(
lineColor: Colors.amber,
completeColor: Colors.blueAccent,
completePercent: percentage,
width: 8.0),
child: new Padding(
padding: const EdgeInsets.all(8.0),
child: new RaisedButton(
color: Colors.purple,
splashColor: Colors.blueAccent,
shape: new CircleBorder(),
child: new Text("$percentage%"),
onPressed: () {
setState(() {
percentage += 10;
if (percentage > 100) {
percentage = 0;
}
});
}),
),
),
),
);
}
}
class MyPainter extends CustomPainter {
Color lineColor;
Color completeColor;
int completePercent;
double width;
MyPainter(
{this.lineColor, this.completeColor, this.completePercent, this.width});
@override
void paint(Canvas canvas, Size size) {
Paint line = new Paint()
..color = lineColor
..strokeCap = StrokeCap.round
..style = PaintingStyle.stroke
..strokeWidth = width;
Paint complete = new Paint()
..color = completeColor
..strokeCap = StrokeCap.round
..style = PaintingStyle.stroke
..strokeWidth = width;
Offset center = new Offset(size.width / 2, size.height / 2);
double radius = min(size.width / 2, size.height / 2);
canvas.drawCircle(center, radius, line);
double arcAngle = 2 * pi * (completePercent / 100.0);
if (arcAngle >= 2 * pi) arcAngle = 2 * pi - 0.001; // cannot draw a complete circle arc
canvas.drawArc(new Rect.fromCircle(center: center, radius: radius), -pi / 2,
arcAngle, false, complete);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}
答案 0 :(得分:1)
来自Docs,shouldRepaint()
:
如果新实例表示的信息与旧实例不同,则该方法应返回true,否则应返回false
也是
即使shouldRepaint返回false,也有可能调用paint方法(例如,如果需要重绘祖先或后代)。也有可能在完全不应该调用shouldRepaint的情况下调用paint方法(例如,如果框更改了大小)
所以,一个好方法就是使用
@override
bool shouldRepaint(MyPainter oldDelegate) =>
oldDelegate.completePercent != completePercent;
答案 1 :(得分:0)
仅当CustomPainter已更改时才应重新绘制。这是我通常要做的
return this!=oldDelegate;