What color system does flutter use and why do we use `const Color` instead of `new Color`

前端 未结 3 1831
鱼传尺愫
鱼传尺愫 2020-12-06 12:11

Today I came over following snippet of code that implements gradient in flutter

return new Container(
  ...
  decoration: new BoxDecoration(
    gradient: ne         


        
相关标签:
3条回答
  • 2020-12-06 12:21

    When we use setState() Flutter calls the build method and rebuilds every widget tree inside it. The best way to avoid this is by using const costructors.

    Use const constructors whenever possible when building your own widgets or using Flutter widgets. This helps Flutter to rebuild only widgets that should be updated

    So if you have a StatefulWidget and you are using setState((){}) to update that widget and you have widgets like:

    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');
            },
          ),
        );
      }
    }
    

    If you run this code and press the floating action button, all the widgets defined as const won't get rebuilded.

    For more info: const constructors

    0 讨论(0)
  • 2020-12-06 12:23

    From the Flutter source

    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 instances are canonicalized.

    If you have multiple const Color(0xFF00CCFF) in your code, only one instance will be created.

    const instances are evaluated at compile time. In the Dart VM this is when the code is loaded, but in Flutter production AoT compilation is used and const values therefore provide a small performance benefit.

    See also How does the const constructor actually work?

    0 讨论(0)
  • 2020-12-06 12:35

    As explained by the accepted answer, const constructors are a small optimization.

    In dart a const MyObject(42) will only be allocated once even when you call it hundreds of time. Which means less memory allocation > faster


    But isn't it a negligible optimization ?

    Well, from dart point of view, yes. But we're in flutter here. We also have a Widget tree that can also use const constructors. Which means that we could change your code example to something like this :

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

    Here, thanks to Color being a constant, we managed to get a constant LinearGradient, and ultimately a constant DecoratedBox widget. So not only will the DecoratedBox widget be instantiated only once ; but thanks to widgets being immutable ; Flutter will recognize that the widget is the same.

    Consequence :

    • The whole sub-tree of DecoratedBox will be built once.
    • The associated RenderObject (RenderDecoratedBox in this case) will be not be updated at all even when it's parent Container change

    This is explained in "Flutter's layered design" video talk. At 31mn to be exact. But I'd suggest to start the video from here to have a bigger understanding of what's skipped.

    PS : Some widgets don't have a const constructor at all. Such as Container. But in the case of Container you could simply use a DecoratedBox instead, which is basically what Container use under the hood. The advantage here is that DecoratedBox do have a const constructor.

    0 讨论(0)
提交回复
热议问题