Эта статья рассказывает о двух важных компонентах в Flutter 3.0: ThemeExtensions и Material3, возможно, вы ещё не знакомы с ними.
Каждый из нас уже использовал Theme
в Flutter, где можно изменять глобальные свойства ThemeData
, чтобы настроить внешний вид приложения, например, отключить эффекты нажатия для InkWell
и TextButton
.
theme: ThemeData(
primarySwatch: Colors.blue,
// Отключение эффекта водяной пленки для InkWell
splashFactory: NoSplash.splashFactory,
// Отключение эффекта высветления для InkWell
highlightColor: Colors.transparent,
textButtonTheme: TextButtonThemeData(
// Отключение эффекта водяной пленки для TextButton
style: ButtonStyle(splashFactory: NoSplash.splashFactory),
),
),
Разработчики также могут использовать метод Theme.of(context)
для чтения глобальных стилей ThemeData
. Однако, что делать, если вам нужна опция, которой нет в ThemeData
, или вы хотите, чтобы эта опция была доступна только для определённого компонента?
Flutter 3 предлагает решение этой проблемы через ThemeExtensions
.
Разработчики могут расширить возможности ThemeData
, создав собственные расширения путём наследования от ThemeExtension
и переопределения методов copyWith
и lerp
, как показано ниже:
@immutable
class StatusColors extends ThemeExtension<StatusColors> {
static const light = StatusColors(open: Colors.green, closed: Colors.red);
static const dark = StatusColors(open: Colors.white, closed: Colors.brown);
const StatusColors({required this.open, required this.closed});
final Color open;
final Color closed;
@override
StatusColors copyWith({Color? open, Color? closed}) {
return StatusColors(open: open ?? this.open, closed: closed ?? this.closed);
}
@override
void lerpFrom(StatusColors a, StatusColors b, double t) {}
@override
void lerpTo(StatusColors a, StatusColors b, double t) {}
}
``` final Color? open;
final Color? closed;
@override
StatusColors copyWith({
Color? success,
Color? info,
}) {
return StatusColors(
open: success ?? this.open,
closed: info ?? this.closed,
);
}
@override
StatusColors lerp(ThemeExtension<StatusColors>? other, double t) {
if (other is! StatusColors) {
return this;
}
return StatusColors(
open: Color.lerp(open, other.open, t),
closed: Color.lerp(closed, other.closed, t),
);
}
@override
String toString() => 'StatusColors('
'open: $open, closed: $closed'
')';
}
```После этого можно будет настроить `StatusColors` в расширении темы `Theme`, а затем получить конфигурацию с помощью `Theme.of(context).extension<StatusColors>()`.
```dart
theme: ThemeData(
primarySwatch: Colors.blue,
extensions: <ThemeExtension<dynamic>>[
StatusColors.light,
],
),
...
@override
Widget build(BuildContext context) {
// Получаем цвет статуса из ThemeExtensions
final statusColors = Theme.of(context).extension<StatusColors>();
return Scaffold(
extendBody: true,
body: Container(
alignment: Alignment.center,
child: ElevatedButton(
style: TextButton.styleFrom(
backgroundColor: statusColors?.open,
),
onPressed: () {},
child: Text("Кнопка"),
),
),
);
}
Не сложно, правда? С помощью ThemeExtensions
сторонние пакеты могут предоставлять объекты ThemeExtensions
, что позволяет реализовать более гибкую настройку стилей.
Material3 также известна как MaterialYou — это новая стандартная модель дизайна пользовательского интерфейса, представленная Google вместе с Android 12. В Flutter 3.0 вы можете активировать её с помощью useMaterial3: true
.
theme: ThemeData(
primarySwatch: Colors.blue,
// Активация использования Material3
useMaterial3: true,
),
```Однако перед активацией Material3 вам стоит узнать больше о ней, так как она значительно влияет на стиль вашего пользовательского интерфейса.
На следующем рисунке показано различие между компонентами `AppBar`, `Card`, `TextButton` и `ElevatedButton` при использовании `primarySwatch: Colors.blue`:

Как видно, произошли изменения в закругленности углов и в базовых цветах. Кроме того, помимо более округлого внешнего вида, некоторые эффекты взаимодействия также были изменены, такие как:
- Эффект клика и дефолтный стиль диалогового окна;
- Дефолтный эффект прокрутки списка "overscroll" на Android;
| Интерактивный эффект | Пример списка |
| ---------------------------------------------------------------- | ------------------------------------------------------------ |
|  |  |
В Flutter 3 (Material Design 3) в основном влияние оказывает параметр `useMaterial3`, который затрагивает следующие виджеты:
* [AlertDialog]
* [AppBar]
* [Card]
* [Dialog]
* [ElevatedButton]
* [FloatingActionButton]
* [Material]
* [NavigationBar]
* [NavigationRail]
* [OutlinedButton]
* [StretchingOverscrollIndicator]
* [GlowingOverscrollIndicator]
* [TextButton]
### Вопрос: Какие различия между Material3 и Material2?
Пример с виджетом AppBar показывает, что способ получения цвета фона отличается в Material2 и Material3. В Material3 отсутствует проверка на темную яркость (`Brightness.dark`). Это значит, что Material3 не поддерживает темную тему?На самом деле, это не так. Основное отличие заключается в том, что стиль Material3 теперь генерируется автоматически. В `_TokenDefaultsM3` используется скрипт для создания версий стилей, а текущая версия — `v0_92`.

В папке gen_defaults можно найти данные, используемые для автоматической генерации стилей Material3.

Основной причиной того, почему в Material3 нет необходимости использовать `Brightness.dark`, является то, что `ColorScheme` уже выполняет эту проверку внутри себя.

Сейчас в Flutter 3.0 ключевой частью темы являются параметры `colorScheme`. Параметры типа `primaryColorBrightness` и `primarySwatch` будут в будущем废弃。Поэтому, если вы сейчас всё ещё используете `primarySwatch`, то в `ThemeData` внутренне будет преобразовано через `ColorScheme.fromSwatch` метод в `ColorScheme`.
```dart
ColorScheme.fromSwatch(
primarySwatch: primarySwatch,
primaryColorDark: primaryColorDark,
accentColor: accentColor,
cardColor: cardColor,
backgroundColor: backgroundColor,
errorColor: errorColor,
brightness: effectiveBrightness,
);
Вы также можете использовать методы ColorScheme.fromSeed
или colorSchemeSeed
для прямого конфигурирования ColorScheme
в ThemeData
.
ColorScheme
представляет собой набор цветовых значений, используемых для стилизации компонентов UI. Он позволяет создавать согласованную цветовую схему для всего приложения.
тема: ThemeData(
цветовая_схема: ColorScheme.fromSeed(seedColor: Color(0xFF4285F4)),
/// Включает использование стиля Material3
useMaterial3: true,
),
```**Здесь мы сталкиваемся с интересной концепцией: пакет HCT цветов в рамках Material3: [material-color-utilities](https://github.com/material-foundation/material-color-utilities)**.
В рамках Material3 цвета не вычисляются строго по RGB, а проходят через преобразование с использованием [material-color-utilities](https://github.com/material-foundation/material-color-utilities). Через внутренний объект `CorePalette`, RGB преобразуется в значения, связанные с HCT, для расчета отображения.

HCT — это аббревиатура для Hue (тон), Chroma (насыщенность) и Tone (тональность). Благодаря открытому гуглом плагину [material-color-utilities](https://github.com/material-foundation/material-color-utilities) можно легко использовать пространство цветов HCT. На данный момент этот репозиторий поддерживает Dart, Java и TypeScript, а также скоро будет поддерживать C/C++ и Objective-C.

Благодаря HCT, например, метод `ColorScheme.fromSeed(seedColor: Color(0xFF4285F4))` позволяет создать серию тематических цветов всего одним seedColor. Это и есть причина того, почему в Material3 можно иметь более богатую цветовую палитру.

> Дополнительно читайте [«Принципы дизайна цвета HCT»](https://material.io/blog/science-of-color-design).
# Подведение итогов
Напоследок давайте вспомним основные моменты:
- Расширение `ThemeData` с помощью `ThemeExtensions`
- Активация Material3 с помощью `useMaterial3` и настройка более богатой цветовой палитры с помощью `ColorScheme`.Теперь你可以询问你的设计师:你知道什么是HCT吗? -> Теперь你可以询问你的设计师:你知道什么是HCT吗?
Так как задача состоит в переводе на русский язык, исправлю:
Теперь вы можете спросить своего дизайнера: знаете ли вы, что такое HCT?
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )