Цвет и стиль: глобальная константа против темы
Сегодня я искал статьи о Flutter и нашел статью Деррита Мвити с заголовком Лучшие практики разработки Flutter. Я учусь трепетать с января 2020 года и считаю, что очень важно не привыкать к вредным привычкам. Поэтому такие статьи мне очень интересны. Я могу понять большинство практик, рекомендованных Дерритом. Но первый в его списке заставил меня усомниться.
Неужели темы такие классные?
Он начинает с совета по использованию тем и указывает на следующие преимущества:
- С ссылками на свойства в любом месте кода проще.
- Это предотвращает повторение кода
- Легче настроить свойство в одном месте и увидеть изменения повсюду.
Затем он дает несколько примеров кода, чтобы показать, как темы определены и как они используются.
Это все хорошо, но мне пришло в голову, что все эти преимущества также могут быть достигнуты с помощью простых глобальных констант. Впервые я увидел эти глобалы в исходном коде Dane Mackier на github. В своем проекте 014 он определяет цвета и шрифты с помощью глобальных констант в таких файлах, как app_colors.dart и textstyles.dart.
Я обнаружил похожую практику в великолепном курсе Анжелы Ю на Удеми. У нее есть файл под названием constants.dart, в котором все стили текста определены в одном месте.
Поэтому я задал себе вопрос: как можно взвесить плюсы и минусы этих двух практик? Что лучше"?
Давайте сначала посмотрим, достигаются ли три преимущества стандартной флаттер-темы с помощью global const.
С ссылками на свойства в любом месте кода проще.
Это еще проще с глобальными константами. Всплывающее окно Intellisense перечисляет все определенные константы, как только я ввожу маленький k. Это соглашение также используется в исходном коде Googles flutter и dart.
Это предотвращает повторение кода
Это тоже достигается. Определите константу один раз и используйте ее где угодно.
Легче настроить свойство в одном месте и увидеть изменения везде.
Это применимо и здесь. Если я настрою глобальную константу, все виджеты, которые ее используют, изменятся.
На стороне глобалов еще больше преимуществ?
Что ж, на мой взгляд, есть: меньше кода. И чем меньше, тем лучше, правда?
Обычно на свойство чаще ссылаются, чем на определение. Итак, давайте сначала посмотрим, как используются свойства.
Например цвет:
backgroundColor: Theme.of(context).accentColor,
or
backgroundColor: kAccentColor,
и стиль текста:
Text("Theming",style: Theme.of(context).textTheme.title,)
or
Text("Theming",style: kStyleTitle,)
В обоих случаях использование константного значения короче.
По моему мнению, определение свойств также проще. Я помню, что видел определения тем, но не могу вспомнить точный синтаксис и возможные сочетания клавиш с copyWith и так далее.
Что-то вроде этого примера от Деррита:
theme: ThemeData(
primarySwatch: Colors.lightBlue,
accentColor: Colors.teal,
fontFamily: 'Lato',
textTheme: ThemeData.light().textTheme.copyWith(
title: TextStyle(
fontSize: 20,
fontFamily: 'Lato',
fontWeight: FontWeight.bold,
),),)
Я бы определил как:
const kStyleTitle = TextStyle(
fontSize: 20, fontFamily: 'Lato', fontWeight: FontWeight.bold,
)
const Color kSliderColor = Color.fromARGB(0xff, 0xe1, 0x0c, 0x35);
TextStyle - это просто копирование и вставка из свойства стиля текстового виджета. Так что вспоминать особо не о чем.
Еще одно преимущество заключается в том, что файл констант содержит все используемые шрифты и цвета приложения в одном месте. С другой стороны, тема предоставит все стандартные настройки, а также, возможно, некоторые дополнительные настраиваемые свойства. Поэтому использование непреднамеренного стиля шрифта по умолчанию сопряжено с повышенным риском.
А как насчет производительности во время выполнения?
Я ожидаю, что простое использование константы требует меньше циклов процессора, чем поиск значения в дереве виджетов с помощью вызова Theme.of (context).
Так в чем же загвоздка?
После этого преимущества перевешивают, каковы недостатки глобальных констант?
Что ж - глобальные константы имеют запах кода. Это нелегко игнорировать.
Но: я думаю, что в каждой области очень важно знать, когда нарушать правила.
Есть несколько общих советов о нарушении правил на Medium. Например: 20 причин, почему нужно нарушать правила и Какие правила и когда нарушать.
Плохое изображение глобальных объектов в основном связано с двумя опасностями:
- Нет никакого контроля над тем, были ли такие объекты изменены где-либо непреднамеренно.
- Могут возникнуть непредвиденные конфликты имен, например, когда добавленный плагин или обновленная библиотека внезапно использует то же имя.
Первый риск на самом деле не существует, потому что, в конце концов, они константы. Их можно считать неизменными.
Остается второй риск. Однако в этом случае VS Code отображает очень полезное сообщение об ошибке.
В конце концов, для меня глобальные константы - это нормально. И есть еще несколько причин использовать глобалы без угрызений совести.
Причина номер один:
Библиотека flutter также предоставляет множество глобальных значений const.
Отсюда и возникла традиция начинать имена с буквы «k» в нижнем регистре.
Команда grep в Sublime Text приводит к 5 файлам с 35 совпадениями при поиске в файлах с именем constants.dart. И гораздо больше kName отображается во всплывающем окне Intellisense, когда вы вводите «k» и Ctrl + Пробел. Возможные значения варьируются от kA lwaysCompleteAnimation (определяется как global const в animations.dart) до kZ oomControlsTimeout в жестах / constants.dart.
Вторая причина для меня - это примеры кода Дейна Макки. Для меня он образец для подражания с большим опытом. Думаю, он очень тщательно подумал об использовании глобальных констант. Кстати: Его статьи на Medium и руководства на его веб-сайте просто великолепны!
И последнее, но не менее важное: Анджела Ю. Она дважды подумает, чтобы использовать глобальные константы при создании примеров своего курса. Это повлияет на многих будущих разработчиков флаттера. В своем примере приложения Flash-Chat она даже определяет полное оформление текстовых полей как константные значения.
const kTextFieldDecoration = InputDecoration(
hintText: 'Enter a value',
contentPadding: EdgeInsets.symmetric(
vertical: 10.0, horizontal: 20.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(32.0)),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.blueAccent, width: 1.0),
borderRadius: BorderRadius.all(Radius.circular(32.0)),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.blueAccent,
width: 2.0),
borderRadius: BorderRadius.all(Radius.circular(32.0)),
),
);
или украшение тары:
const kMessageContainerDecoration = BoxDecoration(
border: Border(
top: BorderSide(
color: Colors.lightBlueAccent, width: 2.0),
),
);
Этот пример демонстрирует еще одно преимущество перед использованием темы: такие глобальные константы также могут использоваться для виджетов. Это имеет смысл, если они используются более одного раза.
Если вы не можете жить с глобальной константой
затем оберните их как статику в такой класс:
class Constants{ String appName = "Flutter App";
static Color lightPrimary = Colors.white; static Color darkPrimary = Colors.black; }
и используйте их вместе с именем класса:
barColor: isDark ? Constants.darkPrimary : Constants.lightPrimary,
Я нашел это решение на github в источнике FlutterEbookApp от Фестуса Бабаджиде Олусегуна. Использование более подробное, но вы избегаете риска столкновения с уже существующими именами в глобальном пространстве имен.
Заключение
В этой статье просто сравнивались стандартные темы флаттера с глобальными константами. Я предпочитаю использовать коллекцию глобальных констант в одном файле, который я называю app_constants.dart.
Я думаю о сборе часто используемых констант из всех моих приложений в общий шаблон констант. По сравнению с набором фрагментов кода в редакторе эта коллекция значительно упростит запуск нового приложения.
BTW: На мой взгляд, можно рекомендовать и другие передовые методы, изложенные в статье Деррита.
Flutter - молодой и быстро развивающийся фреймворк. Время покажет, какие практики преобладают. Может быть, я замечаю преимущества тематики. Может быть, тематика лучше в действительно больших приложениях. Если у вас есть еще какие-то идеи, пожалуйста, добавьте свое замечание к моей статье. Добро пожаловать.
Спасибо Дэйну Маккеру и Деррику Мвити за их статьи о Flutter.