我试图了解 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;
  }
}

最佳答案

DocsshouldRepaint() :



还,



所以,一个好方法是使用

@override
bool shouldRepaint(MyPainter oldDelegate) =>
    oldDelegate.completePercent != completePercent;

关于flutter - 什么时候调用 flutter 中自定义画家类的 shouldRepaint 方法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56370921/

10-13 04:35