dynamik_theme 0.0.2
dynamik_theme: ^0.0.2 copied to clipboard
Easy to use Dynamic Theme for Flutter with automatic persistence support.
example/lib/main.dart
import 'dart:math';
import 'package:dynamik_theme/dynamik_theme.dart';
import 'package:flutter/material.dart';
void main() {
/// Set ThemeStorage. If not set InMemoryThemeStorage will be used.
ThemeConfig.storage = InMemoryThemeStorage();
runApp(const MyApp());
}
const _space = SizedBox(height: 16, width: 16);
final _colors = List.generate(
8,
(index) =>
Color((Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(1.0));
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return DynamikTheme(
config: ThemeConfig(
useMaterial3: true,
// You can also create schemes from:
// https://m3.material.io/theme-builder#/custom
lightScheme: ColorScheme.fromSeed(
seedColor: Colors.red,
),
darkScheme: ColorScheme.fromSeed(
seedColor: Colors.red,
brightness: Brightness.dark,
),
defaultThemeState: SimpleThemeType.dynamik.themeData,
builder: (themeData) {
return themeData.copyWith(
appBarTheme: const AppBarTheme(centerTitle: true),
inputDecorationTheme: const InputDecorationTheme(
border: OutlineInputBorder(),
),
);
},
),
builder: (theme, darkTheme, themeMode) {
return MaterialApp(
themeMode: themeMode,
theme: theme,
darkTheme: darkTheme,
debugShowCheckedModeBanner: false,
home: const Home(),
);
},
);
}
}
class Home extends StatelessWidget {
const Home({super.key});
@override
Widget build(BuildContext context) {
final themeState = DynamikTheme.of(context).themeState;
return Scaffold(
appBar: AppBar(
title: const Text('Dynamik Theme'),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.create),
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(8),
child: Column(
children: [
Center(
child: Text(
'SimpleThemeType:',
style: Theme.of(context).textTheme.titleMedium,
),
),
_space,
Wrap(
runSpacing: 10,
spacing: 10,
children: SimpleThemeType.values
.map((e) => InputChip(
label: Text(e.name),
selected: themeState == e.themeData,
onPressed: () {
DynamikTheme.of(context).setTheme(e.themeData);
},
))
.toList(),
),
_space,
_space,
Text(
'Custom Colors:',
style: Theme.of(context).textTheme.titleMedium,
),
_space,
Wrap(
runSpacing: 10,
spacing: 10,
children: ThemeMode.values
.map(
(e) => InputChip(
label: Text(e.name),
selected: themeState.themeMode == e,
onPressed: () {
DynamikTheme.of(context).setThemeMode(e);
},
),
)
.toList(),
),
_space,
Wrap(
runSpacing: 10,
spacing: 10,
children: ColorMode.values
.map(
(e) => InputChip(
label: Text(e.name),
selected: themeState.colorMode == e,
onPressed: e == ColorMode.dynamik
? () {
DynamikTheme.of(context).setDynamikColorMode();
}
: null,
),
)
.toList(),
),
_space,
Wrap(
spacing: 10,
runSpacing: 10,
key: const ValueKey('value'),
children: _colors.map((e) {
return GestureDetector(
onTap: () {
DynamikTheme.of(context).setCustomColorMode(e);
},
child: CircleAvatar(
backgroundColor: e,
),
);
}).toList(),
),
_space,
const Divider(),
_space,
Wrap(
runSpacing: 10,
spacing: 10,
children: [
TextButton(onPressed: () {}, child: const Text('TextButton')),
ElevatedButton.icon(
onPressed: () {},
icon: const Icon(Icons.image),
label: const Text('ElevatedButton'),
),
FilledButton(
onPressed: () {},
child: const Text('FilledButton'),
),
],
),
_space,
const TextField(),
_space,
const TextField(
decoration: InputDecoration(
border: UnderlineInputBorder(),
errorText: 'ErrorText',
),
),
_space,
CheckboxListTile(
title: const Text('CheckboxListTile'),
value: true,
onChanged: (_) {},
),
RadioListTile(
value: true,
groupValue: true,
onChanged: (_) {},
title: const Text('RadioListTile'),
),
],
),
),
);
}
}