shared_preference_signals 1.0.1
shared_preference_signals: ^1.0.1 copied to clipboard
A Flutter package that provides reactive SharedPreferences integration using signals.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:signals/signals.dart';
import 'package:signals/signals_flutter.dart';
import 'package:shared_preference_signals/shared_preference_signals.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Shared Preference Signals Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
// Example 1: User profile signal
late final Signal<User?> userSignal = jsonSharedPreferenceSignal<User>(
key: 'user_profile',
value: null,
fromJson: User.fromJson,
toJson: (user) => user.toJson(),
);
// Example 2: Theme mode signal
late final Signal<ThemeMode> themeSignal =
enumSharedPreferenceSignal<ThemeMode>(
key: 'theme_mode',
value: ThemeMode.system,
fromString: ThemeMode.values.byName,
);
// Example 3: App settings signal
late final Signal<AppSettings?> settingsSignal =
jsonSharedPreferenceSignal<AppSettings>(
key: 'app_settings',
value: AppSettings.defaultSettings(),
fromJson: AppSettings.fromJson,
toJson: (settings) => settings.toJson(),
);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Shared Preference Signals Demo'),
actions: [
// Theme mode switcher
IconButton(
icon: Icon(themeSignal.value == ThemeMode.dark
? Icons.light_mode
: Icons.dark_mode),
onPressed: () {
themeSignal.value = themeSignal.value == ThemeMode.dark
? ThemeMode.light
: ThemeMode.dark;
},
),
],
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// User Profile Section
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'User Profile',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 16),
Watch((context) {
final user = userSignal.value;
if (user == null) {
return ElevatedButton(
onPressed: () {
userSignal.value = User(
name: 'John Doe',
age: 30,
);
},
child: const Text('Create User Profile'),
);
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Name: ${user.name}'),
Text('Age: ${user.age}'),
const SizedBox(height: 8),
ElevatedButton(
onPressed: () {
userSignal.value = null;
},
child: const Text('Delete Profile'),
),
],
);
}),
],
),
),
),
const SizedBox(height: 16),
// App Settings Section
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'App Settings',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 16),
Watch((context) {
final settings = settingsSignal.value;
if (settings == null) return const SizedBox.shrink();
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SwitchListTile(
title: const Text('Enable Notifications'),
value: settings.enableNotifications,
onChanged: (value) {
settingsSignal.value = settings.copyWith(
enableNotifications: value,
);
},
),
SwitchListTile(
title: const Text('Dark Mode'),
value: settings.darkMode,
onChanged: (value) {
settingsSignal.value = settings.copyWith(
darkMode: value,
);
},
),
const SizedBox(height: 8),
Text('Last Updated: ${settings.lastUpdated}'),
],
);
}),
],
),
),
),
],
),
),
);
}
}
// Example data models
class User {
final String name;
final int age;
User({required this.name, required this.age});
factory User.fromJson(Map<String, dynamic> json) {
return User(
name: json['name'] as String,
age: json['age'] as int,
);
}
Map<String, dynamic> toJson() {
return {
'name': name,
'age': age,
};
}
}
class AppSettings {
final bool enableNotifications;
final bool darkMode;
final DateTime lastUpdated;
AppSettings({
required this.enableNotifications,
required this.darkMode,
required this.lastUpdated,
});
factory AppSettings.defaultSettings() {
return AppSettings(
enableNotifications: true,
darkMode: false,
lastUpdated: DateTime.now(),
);
}
factory AppSettings.fromJson(Map<String, dynamic> json) {
return AppSettings(
enableNotifications: json['enableNotifications'] as bool,
darkMode: json['darkMode'] as bool,
lastUpdated: DateTime.parse(json['lastUpdated'] as String),
);
}
Map<String, dynamic> toJson() {
return {
'enableNotifications': enableNotifications,
'darkMode': darkMode,
'lastUpdated': lastUpdated.toIso8601String(),
};
}
AppSettings copyWith({
bool? enableNotifications,
bool? darkMode,
DateTime? lastUpdated,
}) {
return AppSettings(
enableNotifications: enableNotifications ?? this.enableNotifications,
darkMode: darkMode ?? this.darkMode,
lastUpdated: lastUpdated ?? this.lastUpdated,
);
}
}