【问题标题】:What color system does flutter use and why do we use `const Color` instead of `new Color`Flutter 使用什么颜色系统,为什么我们使用 `const Color` 而不是 `new Color`
【发布时间】:2018-06-08 08:22:30
【问题描述】:

今天我跟着sn-p的代码在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")。如果需要const,为什么TileMode.clamp不也是const?

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    来自 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?

    【讨论】:

    • 性能提升并不是那么小。因为它也允许在小部件上使用const 构造函数;这将导致树渲染中的快捷方式。
    • @Darky 也许吧。猜测可能的性能提升是困难的。只有具体用例的基准才是可靠的。
    • 是的,但在这种情况下,正是 Flutter 团队为此确切目的推荐了 const 小部件。因为它会跳过build 方法调用。另外:youtu.be/dkyY9WCGMi0?t=30m59s
    【解决方案2】:

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

    在 dart 中,即使您调用了数百次,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 do 有一个 const 构造函数。

    【讨论】:

    • 这是很棒的信息,感谢您提供的链接,现在一定会看看!像这样的事情是我大部分时间在 JavaScript 环境中所错过的,它消耗了很多知识:/
    【解决方案3】:

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

    在构建自己的小部件或使用 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-29
      • 2020-08-11
      • 1970-01-01
      • 2018-05-12
      • 1970-01-01
      • 2011-11-24
      • 1970-01-01
      相关资源
      最近更新 更多