Skip to content

Instantly share code, notes, and snippets.

@wingkit-leung
Created February 13, 2022 08:44
Show Gist options
  • Save wingkit-leung/89aa038f7978bd0b947cafeb2e679a0f to your computer and use it in GitHub Desktop.
Save wingkit-leung/89aa038f7978bd0b947cafeb2e679a0f to your computer and use it in GitHub Desktop.
A CustomCounter example implemented with riverpod and shared_preferences using StateNotifier
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
// A CustomCounter example implemented with riverpod and shared_preferences
// using StateNotifier
class CustomCounter {
final int value;
final DateTime dateTime;
const CustomCounter(this.value, this.dateTime);
String get counter {
return (value < 0) ? '-' : value.toString();
}
String get lastUpdatedAt {
return dateTime.toIso8601String();
}
String get lastUpdatedAtFormatted {
return "${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')}:${dateTime.second.toString().padLeft(2, '0')}";
}
}
class CounterStateNotifier extends StateNotifier<CustomCounter> {
final SharedPreferences prefs;
CounterStateNotifier(this.prefs) : super(CustomCounter(0, DateTime.now())) {
init();
}
void init() {
final counter = prefs.getInt('counter');
final lastUpdatedAt = prefs.getString('lastUpdatedAt');
if (counter == null || lastUpdatedAt == null) {
state = CustomCounter(0, DateTime.now());
} else {
state = CustomCounter(counter, DateTime.parse(lastUpdatedAt));
}
}
void increment() {
final countPref = state.value + 1;
state = CustomCounter(countPref, DateTime.now());
prefs.setInt('counter', state.value);
prefs.setString('lastUpdatedAt', state.lastUpdatedAt);
}
}
/// Providers are declared globally and specify how to create a state
final sharedPrefs = Provider<SharedPreferences>((ref) {
throw UnimplementedError();
});
final counterStateNotifier =
StateNotifierProvider<CounterStateNotifier, CustomCounter>(
(ref) => CounterStateNotifier(ref.watch(sharedPrefs)));
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
final sharedPreferences = await SharedPreferences.getInstance();
runApp(
// Adding ProviderScope enables Riverpod for the entire project
ProviderScope(overrides: [
sharedPrefs.overrideWithValue(sharedPreferences),
], child: const MyApp()),
);
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(home: Home());
}
}
class Home extends ConsumerWidget {
const Home({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
appBar: AppBar(title: const Text('Flutter101')),
body: Center(
child: Consumer(builder: (context, ref, _) {
final myCounter = ref.watch(counterStateNotifier);
return Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Counter: ${myCounter.counter}',
style: DefaultTextStyle.of(context)
.style
.apply(fontSizeFactor: 3.0),
),
const SizedBox(height: 50),
Text(
myCounter.lastUpdatedAtFormatted,
style: DefaultTextStyle.of(context)
.style
.apply(fontSizeFactor: 3.0),
),
],
),
);
}),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
ref.read(counterStateNotifier.notifier).increment();
},
child: const Icon(Icons.add),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment