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

时间:2017-12-27 17:40:50

标签: dart flutter

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

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
    ),
  ),
),

它提出了两个问题:

1)这是什么颜色系统0xFF3366FF?它看起来有点类似于HEX,但它不是。

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

3 个答案:

答案 0 :(得分:11)

来自Flutter来源

percent+number

(个实例是规范化的。

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

在编译时评估

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; 个实例。 在Dart VM中,这是加载代码的时间,但在Flutter生产中使用AoT编译,因此const值提供了很小的性能优势。

另见How does the const constructor actually work?

答案 1 :(得分: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构造函数。

答案 2 :(得分:0)

当我们使用setState()时,Flutter会调用build方法并重建其中的每个小部件树。避免这种情况的最佳方法是使用const构造函数。

在构建自己的小部件或使用Flutter小部件时,尽可能使用const构造函数。这有助于Flutter仅重建应更新的小部件

因此,如果您有一个StatefulWidget,并且您正在使用setState((){})更新该小部件,并且您有这样的小部件:

class _MyWidgetState extends State<MyWidget> {

  String title = "Title";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: Column(
        children: <Widget>[
          const Text("Text 1"),
          const Padding(
            padding: const EdgeInsets.all(8.0),
            child: const Text("Another Text widget"),
          ),
          const Text("Text 3"),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.add),
        onPressed: () {
          setState(() => title = 'New Title');
        },
      ),
    );
  }
}

如果运行此代码并按浮动操作按钮,则所有定义为const的小部件都不会重建。

有关更多信息:const constructors