Какую цветовую систему использует флаттер и почему мы используем `const Color` вместо`new Color`
Сегодня я пришел к следующему фрагменту кода, который реализует градиент во флаттере
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")
, Если это должно быть постоянным, почему нет TileMode.clamp
также const?
4 ответа
Из источника Флаттер
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 это происходит, когда код загружается, но в рабочей среде Flutter используется компиляция AoT, поэтому значения const обеспечивают небольшое повышение производительности.
Смотрите также Как на самом деле работает const конструктор?
Как объясняется принятым ответом, const
конструкторы - это небольшая оптимизация.
В дротик const MyObject(42)
будет выделяться только один раз, даже если вы вызываете его сотни раз. Что означает меньшее выделение памяти> быстрее
Но разве это не незначительная оптимизация?
Ну, с точки зрения дротика, да. Но мы здесь трепетали. У нас также есть дерево виджетов, которое также может использовать 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 (
RenderDecoratedBox
в этом случае) не будет обновляться вообще, даже если изменение родительского контейнера
Это объясняется в видео-лекции "Многослойный дизайн Флаттера". Точнее, в 31 мин. Но я бы предложил начать отсюда видео, чтобы лучше понять, что пропущено.
PS: некоторые виджеты не имеют const
конструктор вообще. Такие как Container
, Но в случае Container
Вы могли бы просто использовать DecoratedBox
вместо этого, что в основном то, что Container
использовать под капотом. Преимущество здесь в том, что DecoratedBox
действительно есть конструктор const.
Когда мы используем
setState()
Flutter вызывает метод сборки и перестраивает каждое дерево виджетов внутри него. Лучший способ избежать этого - использовать
const
кострукторы.
По возможности используйте константные конструкторы при создании собственных виджетов или при использовании виджетов Flutter. Это помогает 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
import 'package:flutter/material.dart';
class AppColors {
static const Color kTransparent = Colors.transparent;
static const Color kWhite = Colors.white;
static const Color kBlack = Colors.black;
static const Color kRed = Colors.red;
static const Color kRedA = Colors.redAccent;
static const Color kPink = Colors.pink;
static const Color kPinkA = Colors.pinkAccent;
static const Color kBlue = Colors.blue;
static const Color kBlueA = Colors.blueAccent;
static const Color kLightBlue = Colors.lightBlue;
static const Color kLightBlueA = Colors.lightBlueAccent;
static const Color kGreen = Colors.green;
static const Color kGreenA = Colors.greenAccent;
static const Color kLightGreen = Colors.lightGreen;
static const Color kLightGreenA = Colors.lightGreenAccent;
static const Color kLime = Colors.lime;
static const Color kLimeA = Colors.limeAccent;
static const Color kGrey = Colors.grey;
static const Color kBlueGrey = Colors.blueGrey;
static const Color kPurple = Colors.purple;
static const Color kPurpleA = Colors.purpleAccent;
static const Color kDeepPurple = Colors.deepPurple;
static const Color kDeepPurpleA = Colors.deepPurpleAccent;
static const Color kIndigo = Colors.indigo;
static const Color kIndigoA = Colors.indigoAccent;
static const Color kYellow = Colors.yellow;
static const Color kYellowA = Colors.yellowAccent;
static const Color kOrange = Colors.orange;
static const Color kOrangeA = Colors.orangeAccent;
static const Color kDeepOrange = Colors.deepOrange;
static const Color kDeepOrangeA = Colors.deepOrangeAccent;
static const Color kAmber = Colors.amber;
static const Color kAmberA = Colors.amberAccent;
static const Color kCyan = Colors.cyan;
static const Color kCyanA = Colors.cyanAccent;
static const Color kTeal = Colors.teal;
static const Color kTealA = Colors.tealAccent;
static const Color kBrown = Colors.brown;
}