4 Commits

Author SHA1 Message Date
Artem Luzin m
ead44f1b1a feat: добавить визуальный элемент 2025-06-17 20:44:23 +07:00
Artem Luzin m
f64f63641e fix: исправил ширину строки 2025-06-17 20:25:24 +07:00
Artem Luzin m
3895b9a7fc fix 2025-06-17 20:09:34 +07:00
Artem Luzin m
f7d4c02623 feat 2025-06-17 20:05:59 +07:00
6 changed files with 124 additions and 17 deletions

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:friflex_starter/app/theme/app_colors_scheme.dart';
import 'package:friflex_starter/app/theme/theme_notifier.dart'; import 'package:friflex_starter/app/theme/theme_notifier.dart';
import 'package:friflex_starter/di/di_container.dart'; import 'package:friflex_starter/di/di_container.dart';
import 'package:friflex_starter/l10n/gen/app_localizations.dart'; import 'package:friflex_starter/l10n/gen/app_localizations.dart';
@@ -11,7 +12,7 @@ extension AppContextExt on BuildContext {
DiContainer get di => read<DiContainer>(); DiContainer get di => read<DiContainer>();
/// Геттер для получения цветовой схемы /// Геттер для получения цветовой схемы
ColorScheme get colors => Theme.of(this).colorScheme; AppColors get colors => Theme.of(this).extension<AppColors>()!;
/// Геттер для получения темы /// Геттер для получения темы
ThemeNotifier get theme => read<ThemeNotifier>(); ThemeNotifier get theme => read<ThemeNotifier>();

View File

@@ -1,18 +1,103 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
/// {@template app_colors}
/// Класс, реализующий расширение для добавления токенов в цветовую схему /// Класс, реализующий расширение для добавления токенов в цветовую схему
extension AppColorsScheme on ColorScheme { /// {@endtemplate}
bool get _isDark => brightness == Brightness.dark; class AppColors extends ThemeExtension<AppColors> with DiagnosticableTreeMixin {
/// {@macro app_colors}
///
/// Принимает:
///
/// * [testColor] - цвет тестового текста
/// * [errorSnackbarBackground] - цвет фона снекбара ошибки
/// * [successSnackbarBackground] - цвет фона снекбара успеха
/// * [infoSnackbarBackground] - цвет фона снекбара информации
/// * [itemTextColor] - цвет элемента текста
const AppColors({
required this.testColor,
required this.itemTextColor,
required this.errorSnackbarBackground,
required this.successSnackbarBackground,
required this.infoSnackbarBackground,
});
// Тестовый цвет /// Цвет тестовый
Color get testColor => _isDark ? Colors.green : Colors.red; final Color testColor;
/// Цвет заднего фона снекбара с ошибкой /// Цвет элемента текста
Color get errorSnackbarBackground => const Color(0xFFD24720); final Color itemTextColor;
/// Цвет заднего фона снекбара с успехом /// Цвет фона снекбара ошибки
Color get successSnackbarBackground => const Color(0xFF6FB62C); final Color errorSnackbarBackground;
/// Цвет заднего фона снекбара с информацией /// Цвет фона снекбара успеха
Color get infoSnackbarBackground => const Color.fromARGB(255, 220, 108, 77); final Color successSnackbarBackground;
/// Цвет фона снекбара информации
final Color infoSnackbarBackground;
/// Цвета светлой темы
static final AppColors light = AppColors(
testColor: Colors.red,
errorSnackbarBackground: const Color(0xFFD24720),
successSnackbarBackground: const Color(0xFF6FB62C),
infoSnackbarBackground: const Color.fromARGB(255, 220, 108, 77),
itemTextColor: const Color(0xFFFAF3EB),
);
/// Цвета тёмной темы
static final AppColors dark = AppColors(
testColor: Colors.green,
errorSnackbarBackground: const Color(0xFF638B8B),
successSnackbarBackground: const Color(0xFF93C499),
infoSnackbarBackground: const Color.fromARGB(255, 35, 147, 178),
itemTextColor: Colors.white,
);
@override
ThemeExtension<AppColors> copyWith({
Color? testColor,
Color? errorSnackbarBackground,
Color? successSnackbarBackground,
Color? infoSnackbarBackground,
Color? itemTextColor,
}) => AppColors(
testColor: testColor ?? this.testColor,
errorSnackbarBackground:
errorSnackbarBackground ?? this.errorSnackbarBackground,
successSnackbarBackground:
successSnackbarBackground ?? this.successSnackbarBackground,
infoSnackbarBackground:
infoSnackbarBackground ?? this.infoSnackbarBackground,
itemTextColor: itemTextColor ?? this.itemTextColor,
);
@override
ThemeExtension<AppColors> lerp(
covariant ThemeExtension<AppColors>? other,
double t,
) {
if (other is! AppColors) return this;
return AppColors(
testColor: Color.lerp(testColor, other.testColor, t)!,
errorSnackbarBackground: Color.lerp(
errorSnackbarBackground,
other.errorSnackbarBackground,
t,
)!,
successSnackbarBackground: Color.lerp(
successSnackbarBackground,
other.successSnackbarBackground,
t,
)!,
infoSnackbarBackground: Color.lerp(
infoSnackbarBackground,
other.infoSnackbarBackground,
t,
)!,
itemTextColor: Color.lerp(itemTextColor, other.itemTextColor, t)!,
);
}
} }

View File

@@ -1,10 +1,15 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:friflex_starter/app/theme/app_colors_scheme.dart';
/// Класс для конфигурации светлой/темной темы приложения /// Класс для конфигурации светлой/темной темы приложения
abstract class AppTheme { abstract class AppTheme {
/// Геттер для получения светлой темы /// Геттер для получения светлой темы
static ThemeData get light => ThemeData.light(); static ThemeData get light => ThemeData.light().copyWith(
extensions: <ThemeExtension<Object?>>[AppColors.light],
);
/// Геттер для получения темной темы /// Геттер для получения темной темы
static ThemeData get dark => ThemeData.dark(); static ThemeData get dark => ThemeData.dark().copyWith(
extensions: <ThemeExtension<Object?>>[AppColors.dark],
);
} }

View File

@@ -2,7 +2,6 @@ import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:friflex_starter/app/app_context_ext.dart'; import 'package:friflex_starter/app/app_context_ext.dart';
import 'package:friflex_starter/app/theme/app_colors_scheme.dart';
import 'package:friflex_starter/app/ui_kit/app_box.dart'; import 'package:friflex_starter/app/ui_kit/app_box.dart';
/// {@template app_snackbar} /// {@template app_snackbar}

View File

@@ -1,6 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:friflex_starter/app/app_context_ext.dart'; import 'package:friflex_starter/app/app_context_ext.dart';
import 'package:friflex_starter/app/theme/app_colors_scheme.dart';
import 'package:friflex_starter/gen/assets.gen.dart'; import 'package:friflex_starter/gen/assets.gen.dart';
import 'package:friflex_starter/gen/fonts.gen.dart'; import 'package:friflex_starter/gen/fonts.gen.dart';

View File

@@ -1,6 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:friflex_starter/app/app_context_ext.dart'; import 'package:friflex_starter/app/app_context_ext.dart';
import 'package:friflex_starter/app/theme/app_colors_scheme.dart';
/// {@template ThemeScreen} /// {@template ThemeScreen}
/// Экран для отладки темы приложения /// Экран для отладки темы приложения
@@ -11,6 +10,7 @@ class ThemeScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final colors = context.colors;
return Scaffold( return Scaffold(
appBar: AppBar(title: const Text('Theme')), appBar: AppBar(title: const Text('Theme')),
body: Center( body: Center(
@@ -29,7 +29,25 @@ class ThemeScreen extends StatelessWidget {
child: const SizedBox(height: 100, width: 100), child: const SizedBox(height: 100, width: 100),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
Text('Текущая тема: ${context.theme.themeMode}'), Card(
elevation: 4,
shadowColor: colors.infoSnackbarBackground,
margin: const EdgeInsets.symmetric(vertical: 10),
color: colors.infoSnackbarBackground,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: ListTile(
title: Text(
'Текущая тема: ${context.theme.themeMode}',
style: TextStyle(
color: colors.itemTextColor,
fontWeight: FontWeight.bold,
),
),
trailing: Icon(Icons.color_lens, color: colors.itemTextColor),
),
),
], ],
), ),
), ),