Skip to content

Instantly share code, notes, and snippets.

@MelbourneDeveloper
Last active January 30, 2023 10:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MelbourneDeveloper/e27f4cb613cf33116db222b30db5c998 to your computer and use it in GitHub Desktop.
Save MelbourneDeveloper/e27f4cb613cf33116db222b30db5c998 to your computer and use it in GitHub Desktop.
ValueNotifier Sample Inspired By flutter_bloc Library Example
import 'package:flutter/material.dart';
void main() {
runApp(App());
}
void observe(
String change,
String state,
) =>
// ignore: avoid_print
print('change: $change state: $state');
class App extends StatelessWidget {
App({Key? key}) : super(key: key);
final themeCubit = ThemeValueNotifier();
@override
Widget build(BuildContext context) => ValueListenableBuilder<ThemeData>(
valueListenable: themeCubit,
builder: (_, theme, widget) => MaterialApp(
theme: theme,
home: CounterPage(themeCubit: themeCubit),
),
);
}
class CounterPage extends StatefulWidget {
const CounterPage({Key? key, required this.themeCubit}) : super(key: key);
final ThemeValueNotifier themeCubit;
@override
State<CounterPage> createState() => _CounterPageState();
}
class _CounterPageState extends State<CounterPage> {
final CounterValueNotifier counterBloc = CounterValueNotifier();
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: const Text('Counter')),
body: Center(
child: ValueListenableBuilder<int>(
valueListenable: counterBloc,
builder: (context, count, widget) =>
Text('$count', style: Theme.of(context).textTheme.displayLarge),
),
),
floatingActionButton: Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () => counterBloc.increment(),
),
const SizedBox(height: 4),
FloatingActionButton(
child: const Icon(Icons.remove),
onPressed: () => counterBloc.decrement(),
),
const SizedBox(height: 4),
FloatingActionButton(
child: const Icon(Icons.brightness_6),
onPressed: () {
widget.themeCubit.toggleTheme();
},
),
],
),
);
}
class CounterValueNotifier extends ValueNotifier<int> {
CounterValueNotifier.internal() : super(0);
void increment() => value = value + 1;
void decrement() => value = value - 1;
factory CounterValueNotifier() {
var counterValueNotifier = CounterValueNotifier.internal();
return counterValueNotifier
..addListener(
() => observe(
'Counter',
counterValueNotifier.value.toString(),
),
);
}
}
class ThemeValueNotifier extends ValueNotifier<ThemeData> {
ThemeValueNotifier.internal() : super(_lightTheme);
factory ThemeValueNotifier() {
var themeValueNotifier = ThemeValueNotifier.internal();
return themeValueNotifier
..addListener(
() => observe(
'Theme',
themeValueNotifier.toString(),
),
);
}
static final _lightTheme = ThemeData(
floatingActionButtonTheme: const FloatingActionButtonThemeData(
foregroundColor: Colors.white,
),
brightness: Brightness.light,
);
static final _darkTheme = ThemeData(
floatingActionButtonTheme: const FloatingActionButtonThemeData(
foregroundColor: Colors.black,
),
brightness: Brightness.dark,
);
void toggleTheme() {
value = value.brightness == Brightness.dark ? _lightTheme : _darkTheme;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment