什么颜色系统会颤动使用,为什么我们使用`const Color`而不是`new Color`

问题描述 投票:9回答:2

今天我来到了以下代码片段,它实现了渐变的渐变

return new Container(
  ...
  decoration: new BoxDecoration(
    gradient: new LinearGradient(
      colors: [
        const Color(0xFF3366FF), 
        const Color(0xFF00CCFF),
      ]
      begin: const FractionalOffset(0.0, 0.0),
      end: const FractionalOffset(1.0, 0.0),
      stops: [0.0, 1.0],
      tileMode: TileMode.clamp
    ),
  ),
),

它提出了2个问题:

1)什么颜色系统是0xFF3366FF这个?它看起来有点类似于HEX,但事实并非如此。

2)为什么我们使用const作为const Color()反对new Color()我理解两者之间的不同,但这里的const对我来说感觉不直观,我希望它创建一个new Color()类实例,类似于我们如何使用new Text("Some text")。如果它需要是const,为什么TileMode.clamp也不是const?

dart flutter
2个回答
11
投票

来自Flutter来源

class Color {
  /// Construct a color from the lower 32 bits of an [int].
  ///
  /// The bits are interpreted as follows:
  ///
  /// * Bits 24-31 are the alpha value.
  /// * Bits 16-23 are the red value.
  /// * Bits 8-15 are the green value.
  /// * Bits 0-7 are the blue value.
  ///
  /// In other words, if AA is the alpha value in hex, RR the red value in hex,
  /// GG the green value in hex, and BB the blue value in hex, a color can be
  /// expressed as `const Color(0xAARRGGBB)`.
  ///
  /// For example, to get a fully opaque orange, you would use `const
  /// Color(0xFFFF9000)` (`FF` for the alpha, `FF` for the red, `90` for the
  /// green, and `00` for the blue).
  const Color(int value) : value = value & 0xFFFFFFFF;

const实例是规范化的。

如果您的代码中有多个const Color(0xFF00CCFF),则只会创建一个实例。

const实例在编译时进行评估。在Dart VM中,这是加载代码的时候,但是在Flutter生产中使用AoT编译,因此const值提供了很小的性能优势。

另见How does the const constructor actually work?


11
投票

正如公认的答案所解释的那样,const构造函数是一个小优化。

在飞镖中,即使你召唤数百次,const MyObject(42)也只会被分配一次。这意味着更少的内存分配>更快


但这不是一个可以忽略不计的优化吗?

嗯,从飞镖的角度来看,是的。但是我们在这里扑了一下。我们还有一个Widget树,也可以使用const构造函数。这意味着我们可以将您的代码示例更改为以下内容:

return const DecoratedBox(
  decoration: const BoxDecoration(
    gradient: const LinearGradient(
      colors: const [
        const Color(0xFF3366FF), 
        const Color(0xFF00CCFF),
      ],
      begin: const FractionalOffset(0.0, 0.0),
      end: const FractionalOffset(1.0, 0.0),
      stops: const [0.0, 1.0],
      tileMode: TileMode.clamp
    ),
  ),
);

在这里,由于Color是一个常数,我们设法得到一个恒定的LinearGradient,并最终一个恒定的DecoratedBox小部件。因此,DecoratedBox小部件不仅仅会被实例化一次;但是由于小部件是不可变的; Flutter会认识到小部件是相同的。

后果:

  • DecoratedBox的整个子树将建造一次。
  • 相关的RenderObject(在这种情况下为RenderDecoratedBox)即使它的父容器更改也不会更新

这在“Flutter的分层设计”视频讲话中有所解释。 At 31mn确切地说。但我建议从here开始视频,以便更好地理解跳过的内容。

PS:有些小部件根本没有const构造函数。如Container。但是在Container的情况下你可以简单地使用DecoratedBox,这基本上是Container在引擎盖下使用。这里的优点是DecoratedBox确实有一个const构造函数。

© www.soinside.com 2019 - 2024. All rights reserved.