Dart Flatter使用什么颜色系统?为什么我们使用“const color”而不是“new color”`

Dart Flatter使用什么颜色系统?为什么我们使用“const color”而不是“new color”`,dart,flutter,Dart,Flutter,今天我看了下面的代码片段,它在flutter中实现了梯度 return new Container( ... decoration: new BoxDecoration( gradient: new LinearGradient( colors: [ const Color(0xFF3366FF), const Color(0xFF00CCFF), ] begin: const FractionalOffset

今天我看了下面的代码片段,它在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) 这是什么颜色系统?它看起来有点像十六进制,但它不是


2) 为什么我们使用
const
作为
const Color()
而不是
new Color()
我理解两者之间的不同,但是这里的const对我来说并不直观,我希望它创建一个
new Color()
类实例,类似于我们使用
新文本(“某些文本”)
的方式。如果需要常数,为什么TileMode.clamp不也是一个常数?

来自颤振源

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中,这是在加载代码时进行的,但在颤振生产中使用AoT编译,因此const值提供了较小的性能优势


另请参见

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

在dart中,常量MyObject(42)仅分配一次,即使您多次调用它。这意味着更少的内存分配>更快


但这不是一个微不足道的优化吗

从dart的角度来看,是的。 但我们在这里。我们还有一个小部件树,它也可以使用
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
小部件只能实例化一次;但由于小部件是不可变的;颤振将识别小部件是相同的

后果:

  • DecoratedBox
    的整个子树将构建一次
  • 关联的RenderObject(
    renderdercoratedbox
    ,在本例中)即使其父容器发生更改,也不会更新
这在“颤振的分层设计”视频演讲中有解释。 确切地说。但我建议从开始的时候开始,对跳过的内容有更深入的了解

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

当我们使用
setState()
时,flatter调用build方法并重建其中的每个小部件树。避免这种情况的最好方法是使用
const
costructor

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

因此,如果您有
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');
        },
      ),
    );
  }
}
class\u MyWidgetState扩展状态{
字符串title=“title”;
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(标题),
),
正文:专栏(
儿童:[
常量文本(“文本1”),
常数填充(
填充:常数边集全部(8.0),
子:const Text(“另一个文本小部件”),
),
常量文本(“文本3”),
],
),
浮动操作按钮:浮动操作按钮(
子:常量图标(Icons.add),
已按下:(){
设置状态(()=>title='newtitle');
},
),
);
}
}
如果运行此代码并按下浮动操作按钮,则所有定义为const的小部件都不会得到重建


有关更多信息:

性能增益并不是那么小。因为它也允许在小部件上使用
const
构造函数;这将导致树渲染中的快捷方式。@Darky可能。猜测可能的性能增益是困难的。只有Concerte用例的基准是可靠的。是的,但在这种情况下,正是Flatter团队推荐const小部件来达到这个确切的目的。因为它将跳过
build
方法调用。另外:这是非常棒的信息,谢谢你的链接,现在一定会看看的!这些都是我在JavaScript环境中所缺少的东西,它需要很多知识:/