Упрощение Работы с Расширениями темам в Flutter: Инструменты и Пакеты для Генерации Стилей
Содержание
Пример организации и работы с темами через контекст
Немного о кодогенерации
Как работать с темами
В Flutter есть встроенный инструмент для работы с темами — ThemeData
. В нем хранится все стили для всех сущностей. Например, можно переопределить TextTheme
и кастомизировать шрифты в приложении или изменить фон для Scaffold
. Но как быть если 12 текстовых стилей вам не хватает?
Храним темы в BuildContext
Если вам недостаточно полей в TextTheme
или вы хотите добавить больше цветов в приложение, используйте ThemeExtension
. ThemeExtension
позволяет хранить собственные свойства темы.
Рассмотрим на примере текстовых стилей
Для начала нужно создать файл, который будет наследовать ThemeExtension
. В нашем случае это будет AppThemeTextStyles
. Нужно сразу добавить необходимые текстовые стили.
Конструктор
Метод copyWith
Метод lerp
class AppThemeTextStyles extends ThemeExtension{
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? 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 >[
lightTextStyle,
],
);
}
ThemeData createDarkTheme(){
return ThemeData(
extensions: const >[
darkTextStyle,
],
);
}
А для добавления данных о стиле в BuildContext
нужно только создать расширение (extension
).
extension BuildContextExtention on BuildContext {
AppThemeTextStyles get appText =>
Theme.of(this).extension()!;
}
И всё. Теперь можно получить доступ к текстовым стилям через 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);
}
Посетить телеграмм канал автора можно посетить тут
Подкинте программисту на кофе, ему еще песика кормить,