theme_tuner 0.0.2
theme_tuner: ^0.0.2 copied to clipboard
ThemeTuner – Effortless and flexible theme management for Flutter. Supports light, dark, and custom themes with runtime switching and persistent user preferences.
Theme Tuner #
A Flutter package for easily managing multiple themes in your application using the BLoC pattern.
Features #
- Light and dark theme support
- Custom theme creation
- System theme detection and automatic switching
- Theme persistence using SharedPreferences
- Smooth theme transitions with animations
- BLoC state management for clean architecture
Installation #
Add theme_tuner
to your pubspec.yaml
:
dependencies:
theme_tuner: ^0.0.2
🚀 Basic Usage #
import 'package:flutter/material.dart';
import 'package:theme_tuner/theme_tuner.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return RepositoryProvider(
create: (context) => ThemeRepository(),
child: BlocProvider(
create: (context) => ThemeBloc(
themeRepository: context.read<ThemeRepository>(),
)..add(ThemeInitialEvent()),
child: BlocBuilder<ThemeBloc, ThemeState>(
builder: (context, state) {
if (state is ThemeLoaded) {
return MaterialApp(
title: 'My App',
theme: state.themeModel.themeData,
home: const HomePage(),
);
}
return const MaterialApp(
home: Scaffold(body: Center(child: CircularProgressIndicator())),
);
},
),
),
);
}
}
🎛️ Changing Themes #
Dispatch the appropriate event to the ThemeBloc:
context.read<ThemeBloc>().add(ThemeChangedEvent(ThemeType.light));
context.read<ThemeBloc>().add(ThemeChangedEvent(ThemeType.dark));
context.read<ThemeBloc>().add(ThemeChangedEvent(ThemeType.green));
context.read<ThemeBloc>().add(ThemeChangedEvent(ThemeType.purple));
context.read<ThemeBloc>().add(ThemeFollowSystemEvent());
context.read<ThemeBloc>().add(CustomThemeEvent(primaryColor: Colors.orange));
🧪 Theme Settings Page Example #
class ThemeSettingsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Theme Settings')),
body: ListView(
children: [
ListTile(
title: const Text('Light Theme'),
leading: const Icon(Icons.light_mode),
onTap: () => context.read<ThemeBloc>().add(ThemeChangedEvent(ThemeType.light)),
),
ListTile(
title: const Text('Dark Theme'),
leading: const Icon(Icons.dark_mode),
onTap: () => context.read<ThemeBloc>().add(ThemeChangedEvent(ThemeType.dark)),
),
ListTile(
title: const Text('System Theme'),
leading: const Icon(Icons.brightness_auto),
onTap: () => context.read<ThemeBloc>().add(ThemeFollowSystemEvent()),
),
],
),
);
}
}
🎨 Custom Theme with Color Picker #
void showColorPicker(BuildContext context) {
Color pickerColor = Theme.of(context).primaryColor;
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('Pick a theme color'),
content: SingleChildScrollView(
child: ColorPicker(
pickerColor: pickerColor,
onColorChanged: (color) {
pickerColor = color;
},
),
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('Cancel'),
),
ElevatedButton(
onPressed: () {
context.read<ThemeBloc>().add(CustomThemeEvent(primaryColor: pickerColor));
Navigator.of(context).pop();
},
child: const Text('Apply'),
),
],
);
},
);
}
🖥️ System Theme Integration #
When users select the System Theme option, ThemeTuner will automatically adapt between light and dark themes based on the OS settings.
⚙️ Advanced Configuration #
Custom Theme Definitions #
static final ThemeModel customRed = ThemeModel(
type: ThemeType.custom,
themeData: ThemeData(
brightness: Brightness.light,
primarySwatch: Colors.red,
),
);
Theme Extensions #
class CustomThemeExtension extends ThemeExtension<CustomThemeExtension> {
final Color specialColor;
final BorderRadius borderRadius;
CustomThemeExtension({
required this.specialColor,
required this.borderRadius,
});
@override
CustomThemeExtension copyWith({
Color? specialColor,
BorderRadius? borderRadius,
}) {
return CustomThemeExtension(
specialColor: specialColor ?? this.specialColor,
borderRadius: borderRadius ?? this.borderRadius,
);
}
@override
CustomThemeExtension lerp(ThemeExtension<CustomThemeExtension>? other, double t) {
if (other is! CustomThemeExtension) return this;
return CustomThemeExtension(
specialColor: Color.lerp(specialColor, other.specialColor, t)!,
borderRadius: BorderRadius.lerp(borderRadius, other.borderRadius, t)!,
);
}
}
Add to your theme:
themeData: ThemeData().copyWith(
extensions: [
CustomThemeExtension(
specialColor: Colors.amber,
borderRadius: BorderRadius.circular(8),
),
],
);
Use in widgets:
final customTheme = Theme.of(context).extension<CustomThemeExtension>()!;
Container(
decoration: BoxDecoration(
color: customTheme.specialColor,
borderRadius: customTheme.borderRadius,
),
);
🙌 Contributions Welcome #
Feel free to open issues, suggest features, or submit pull requests!
Let’s make Flutter theme management smarter and smoother together.
🔗 Links #
- Pub.dev – Package page
- GitHub – Source code
- Example App – See it in action
Connect with me #
If you have any bugs or issues , If you want to explain my code please contact me on :
#