dynamic_themes_sl 1.0.0
dynamic_themes_sl: ^1.0.0 copied to clipboard
A lightweight Flutter package for managing dynamic themes with support for Light/Dark Mode, custom themes, and RTL.
example/main.dart
import 'package:dynamic_themes_sl/flutter_dynamic_theme.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final themeManager = await DynamicThemeManager.create();
runApp(MyApp(themeManager: themeManager));
}
class MyApp extends StatelessWidget {
final DynamicThemeManager themeManager;
const MyApp({super.key, required this.themeManager});
@override
Widget build(BuildContext context) {
return BlocProvider.value(
value: themeManager.bloc,
child: BlocBuilder<ThemeBloc, ThemeState>(
builder: (context, state) {
return MaterialApp(
title: 'Dynamic Theme Manager Demo',
theme: themeManager.bloc.getThemeData(context),
home: const MyHomePage(),
);
},
),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final bloc = context.read<ThemeBloc>();
return Scaffold(
appBar: AppBar(
title: const Text('Dynamic Theme Manager Demo'),
actions: [ThemeSwitcherDropdown()],
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Theme Preview',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
ThemePreviewGrid(
themes: [
CustomThemeData.light(),
CustomThemeData.dark(),
CustomThemeData(
primaryColor: Colors.purple,
accentColor: Colors.pink,
backgroundColor: Colors.white,
textColor: Colors.black,
brightness: Brightness.light,
surfaceColor: Colors.grey[100]!,
errorColor: Colors.red[700]!,
fontFamily: 'Roboto',
),
],
onThemeSelected: (theme) {
bloc.add(CustomThemeSet(theme));
},
),
const SizedBox(height: 32),
const Text(
'Theme Properties',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildColorRow('Primary Color', theme.colorScheme.primary),
_buildColorRow('Accent Color', theme.colorScheme.secondary),
_buildColorRow(
'Background Color',
theme.colorScheme.background,
),
_buildColorRow('Surface Color', theme.colorScheme.surface),
_buildColorRow('Error Color', theme.colorScheme.error),
const SizedBox(height: 8),
Text(
'Font Family: ${theme.textTheme.bodyLarge?.fontFamily ?? 'System'}',
),
],
),
),
),
const SizedBox(height: 32),
const Text(
'JSON Theme Example',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
final jsonTheme = '''
{
"primaryColor": "#FF5722",
"accentColor": "#FFC107",
"backgroundColor": "#212121",
"textColor": "#FFFFFF",
"brightness": "dark",
"surfaceColor": "#1E1E1E",
"errorColor": "#CF6679",
"fontFamily": "Roboto"
}
''';
final theme = CustomThemeData.fromJson(jsonTheme);
bloc.add(CustomThemeSet(theme));
},
child: const Text('Load JSON Theme'),
),
const SizedBox(height: 8),
ElevatedButton(
onPressed: () {
bloc.add(const CustomThemeCleared());
},
child: const Text('Clear Custom Theme'),
),
],
),
),
);
}
Widget _buildColorRow(String label, Color color) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Row(
children: [
Container(
width: 24,
height: 24,
decoration: BoxDecoration(
color: color,
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(4),
),
),
const SizedBox(width: 8),
Text(label),
],
),
);
}
}