Содержание
-
Пример организации и работы с темами через контекст
-
Немного о кодогенерации
Как работать с темами
В Flutter есть встроенный инструмент для работы с темами — ThemeData
. В нем хранится все стили для всех сущностей. Например, можно переопределить TextTheme
и кастомизировать шрифты в приложении или изменить фон для Scaffold
. Но как быть если 12 текстовых стилей вам не хватает?
Храним темы в BuildContext
Если вам недостаточно полей в TextTheme
или вы хотите добавить больше цветов в приложение, используйте ThemeExtension
. ThemeExtension
позволяет хранить собственные свойства темы.
Рассмотрим на примере текстовых стилей
Для начала нужно создать файл, который будет наследовать ThemeExtension
. В нашем случае это будет AppThemeTextStyles
. Нужно сразу добавить необходимые текстовые стили.
-
Конструктор
-
Метод copyWith
-
Метод lerp
class AppThemeTextStyles extends ThemeExtension<AppThemeTextStyles>{ final TextStyle header; final TextStyle body; const AppThemeTextStyles({ required this.header, required this.body, }); @override $AppThemeTextStyles copyWith({ TextStyle? header, TextStyle? body, }) { return AppThemeTextStyles( header: header ?? this.header, body: body ?? this.body, ); } @override AppThemeTextStyles lerp( ThemeExtension<AppThemeTextStyles>? other, double t) { if (other is! AppThemeTextStyles) return this; return AppThemeTextStyles( header: TextStyle.lerp(header, other.header, t)!, body: TextStyle.lerp(body, other.body, t)!, ); } }
Отлично, теперь мы можем создавать darkTextStyle
, lightTextStyle
, blueTextStyle
или любой другой TextStyle
.
static const AppThemeTextStyles darkTextStyle = AppThemeTextStyles( header: TextStyle( fontSize: 24, fontWeight: FontWeight.bold, color: Colors.black, ), body: TextStyle( fontSize: 16, fontWeight: FontWeight.normal, color: Colors.black, ), ); static const AppThemeTextStyles lightTextStyle = AppThemeTextStyles( header: TextStyle( fontSize: 24, fontWeight: FontWeight.bold, color: Colors.blue, ), body: TextStyle( fontSize: 16, fontWeight: FontWeight.normal, color: Colors.blue, ), ); static const AppThemeTextStyles blueTextStyle = AppThemeTextStyles( header: TextStyle( fontSize: 16, fontWeight: FontWeight.normal, color: Colors.black, ), body: TextStyle( fontSize: 24, fontWeight: FontWeight.bold, color: Colors.white, );
Теперь нужно добавить наше расширение в тему.
ThemeData createLightTheme(){ return ThemeData( extensions: const <ThemeExtension<dynamic>>[ lightTextStyle, ], ); } ThemeData createDarkTheme(){ return ThemeData( extensions: const <ThemeExtension<dynamic>>[ darkTextStyle, ], ); }
А для добавления данных о стиле в BuildContext
нужно только создать расширение (extension
).
extension BuildContextExtention on BuildContext { AppThemeTextStyles get appText => Theme.of(this).extension<AppThemeTextStyles>()!; }
И всё. Теперь можно получить доступ к текстовым стилям через context.appText.header
. Стиль будет зависеть от выбранной темы приложения. Вы можете добавить всё, что угодно: цвета, текстовые стили — всё, что может зависеть от выбранной темы.
А так ли это удобно?
Да, только для добавления стиля нужно внести его в несколько мест в ThemeExtension
.
А можно ли это как то автоматизировать?
Да, для работы с темами есть пакет theme_tailor.
И я написал небольшой кодогенератор: extension_theme_generator. Он генерирует файл для текстовых стилей и цветов. Работает просто:
-
Отмечаем декоратором
@TextStyleAnnotation()
все текстовые стили. -
Отмечаем декоратором
@ColorAnnotation()
классы с цветами.
// Пример для работы с цветами @ColorAnnotation() class LightColors { static const Color primary = Color(0xFFFFFFFF); static const Color secondary = Color(0xFFEEEEEE); static const Color background = Color(0xFFEDF6F6); } @ColorAnnotation() class DarkColors { static const Color primary = Color(0xFF000000); static const Color secondary = Color(0xFF111111); static const Color textColor = Color(0xFF111111); // Также создастся, но для `LightColors` будет красным. static const Color background = Color(0xFF015D60); }
-
Запускаем команду
flutter pub run build_runner build
. -
Профит! Осталось добавить созданные
AppThemeColors
иAppTextStyles
в ваши темы.
Пример с кодогенератором
//example/lib/theme import 'package:flutter/material.dart'; import 'package:extension_theme_generator/extension_theme_generator.dart'; part 'text_styles.dart'; // Тут все текстовые стили part 'app_colors.dart'; /// тут все для цветов part 'theme.g.dart'; /// путь до выходного файла
//example/lib/theme/text_styles.dart part of 'theme.dart'; @TextStyleAnnotation() class DarkTextStyle { static const TextStyle header = TextStyle( fontSize: 24, fontWeight: FontWeight.bold, color: Colors.white, ); } @TextStyleAnnotation() class LightTextStyle { static const TextStyle header = TextStyle( fontSize: 24, fontWeight: FontWeight.bold, color: Colors.black, ); }
// example/lib/theme/app_colors.dart part of 'theme.dart'; @ColorAnnotation() class LightColors { static const Color primary = Color(0xFFFFFFFF); static const Color secondary = Color(0xFFEEEEEE); } @ColorAnnotation() class DarkColors { static const Color primary = Color(0xFF000000); static const Color secondary = Color(0xFF111111); }
Посетить телеграмм канал автора можно посетить тут
Подкинте программисту на кофе, ему еще песика кормить,
ссылка на оригинал статьи https://habr.com/ru/articles/833626/
Добавить комментарий