CustomPainter.shouldRepaint() 在 Flutter 中是如何工作的?

How does CustomPainter.shouldRepaint() work in Flutter?

在 Flutter 中,当创建一个 CustomPainter 时,有一个覆盖方法 shouldRepaint() ,你可以 return true 或 false ...大概是告诉系统是否要重新绘制视图。

in the docs,方法的描述是:

shouldRepaint(covariant CustomPainter oldDelegate) → bool Called whenever a new instance of the custom painter delegate class is provided to the RenderCustomPaint object, or any time that a new CustomPaint object is created with a new instance of the custom painter delegate class (which amounts to the same thing, because the latter is implemented in terms of the former). [...]

除了 return 是一个布尔值之外,我基本上什么都不懂。这让我很头疼!我还怀疑深入研究“自定义画家委托 class”或“RenderCustomPaint object”的定义不会有启发性。

我很困惑,因为:

知识渊博的人为什么以及如何决定 return 错误?

知识渊博的人为什么以及如何决定 return 正确?

任何人都可以像你在和一个 13 岁的孩子(不是 Linus Torvalds)谈话一样解释吗?

一个简单的代码示例和 counter-example 会很棒(而不是详尽的明确解释!)

我广泛使用了 CustomPainter,这里是我的答案。

首先,这是完整文档。您可能只阅读了开头的句子而不是完整的文档。 https://api.flutter.dev/flutter/rendering/CustomPainter/shouldRepaint.html

Why and how would a knowledgeable person decide to return false/true?

规则如下:If the new instance represents different information than the old instance, then the method should return true, otherwise it should return false.

示例:

class MyPainter extends CustomPainter {
  MyPainter() : super();

  @override
  void paint(Canvas canvas, Size size) => canvas.drawRect(Offset.zero & size, Paint());

  // false since all instances of MyPainter contain same information
  @override
  bool shouldRepaint(MyPainter oldDelegate) => false;
}

class MyPainter extends CustomPainter {
  final Color color;
  final double width;

  MyPainter(this.color, this.width) : super();

  @override
  void paint(Canvas canvas, Size size) => canvas.drawRect(
      Offset.zero & size,
      Paint()
        ..color = color
        ..strokeWidth = width);

  @override
  bool shouldRepaint(MyPainter oldDelegate) => oldDelegate.color != this.color || oldDelegate.width != this.width;
}

I thought we didn't have to worry about when a widget "should repaint" because Flutter was supposed to decide where and when to re-render the widget tree based on it's own complex optimization decisions.

是也不是。这个 shouldRepaint() 基本上是对速度的优化。如果您不关心性能,您可以 return 始终为真。

I thought the paint() method was where you define "this is how this view paints itself, (always and whenever that is necessary)"

“这就是这个视图描绘自己的方式”- 是的。 “无论何时何地都是必要的” - 部分没有。如果您向 shouldRepaint() 提供了错误的信息,您可能会错过一些绘画。

All the examples I have found simply return false from this method... but I have noticed different behavior when using true vs false.

什么???我看到人们 return 是真的,或者 return 是比较的(见我下面的例子)。但是当 returning 为 false 时,它​​可能会导致问题。即使只是查看此函数的注释,您也会发现它应该会导致常量 false 出现问题。不过不管怎样,如果你的painter真的不包含任何可以改变的信息,那也没关系...

If we are always returning false, then how does it ever repaint? (And it does repaint even when false)

  /// If the method returns false, then the [paint] call might be optimized
  /// away.
  ///
  /// It's possible that the [paint] method will get called even if
  /// [shouldRepaint] returns false (e.g. if an ancestor or descendant needed to
  /// be repainted). It's also possible that the [paint] method will get called
  /// without [shouldRepaint] being called at all (e.g. if the box changes
  /// size).

注意“可能”和下面的段落。 Flutter可以选择画或者不画

If the only possible logic available to us is comparing the "oldDelegate" to (something?) then why are we required to override the method at all?

看我的例子

I haven't seen any example that demonstrates why or how you would return TRUE, and what the logic of such an example would look like in order to make that decision.

看我的例子


顺便说一句,如果你对Flutter有一些了解,比如widget/layout/paint逻辑等,那就太好了,那么你会很容易理解这个问题。但无论如何,我在上面的回答中使用了即使没有深入了解 Flutter 也很容易理解的词语。