preferences_generator 1.1.0
preferences_generator: ^1.1.0 copied to clipboard
A powerful code generator that creates type-safe, boilerplate-free preference modules from simple abstract classes, used with `preferences_annotation`.
preferences_generator #
A powerful, type-safe code generation solution for creating preference and settings classes in Dart & Flutter.
This package provides a clean, annotation-based API to eliminate boilerplate code for managing user
settings, allowing you to interact with shared_preferences, flutter_secure_storage, or any other
key-value store in a fully type-safe manner.
Features #
- β Type-Safe: No more magic strings. Get compile-time safety for all your preference keys and types.
- π§± Storage Agnostic: Use
shared_preferences,flutter_secure_storage, or a custom backend by implementing a simplePreferenceAdapter. - βοΈ Boilerplate Reduction: Define your preferences once in an abstract class and let the generator do the rest.
- π¨ Rich Type Support: Out-of-the-box support for
int,String,double,bool,DateTime,Color,List,Map,Enum, andRecord. - π Developer Friendly: Fails at build-time with clear, helpful errors for misconfigurations.
Getting Started #
Follow these steps to integrate the Preferences Suite into your project.
1. Installation #
Add the necessary dependencies to your pubspec.yaml file. You will need the
preferences_annotation package as a regular dependency, and this package (preferences_generator)
along with build_runner as dev dependencies.
dependencies:
preferences_annotation: ^1.0.0
dev_dependencies:
preferences_generator: ^1.0.0
build_runner: ^2.4.15
2. Create Your Preference Module #
Create an abstract class annotated with @PreferenceModule. This class must mix in the generated
_$YourClassName interface to inherit the generated method signatures.
lib/settings.dart
import 'package:flutter/material.dart';
import 'package:preferences_annotation/preferences_annotation.dart';
import 'my_preference_adapter.dart'; // We will create this in the next step
part 'settings.g.dart';
@PreferenceModule()
abstract class AppSettings with _$AppSettings {
factory AppSettings(PreferenceAdapter adapter, {
@PreferenceEntry(defaultValue: ThemeMode.system)
final ThemeMode themeMode,
@PreferenceEntry()
final Color? accentColor,
}) = _AppSettings;
static Future<AppSettings> create(PreferenceAdapter adapter) async {
final instance = _AppSettings(adapter);
await instance._load();
return instance;
}
}
3. Implement a Preference Adapter #
This library is backend-agnostic. You must provide an implementation of the PreferenceAdapter
interface that connects to your desired storage solution. Here is a starter example for
shared_preferences:
lib/my_preference_adapter.dart
import 'dart:convert';
import 'dart:ui';
import 'package:preferences_annotation/preferences_annotation.dart';
import 'package:shared_preferences/shared_preferences.dart';
class MyPreferenceAdapter implements PreferenceAdapter {
final SharedPreferences _prefs;
const MyPreferenceAdapter(this._prefs);
@override
Future<void> clear() async {
await _prefs.clear();
}
@override
Future<T> get<T>(String key) async {
// ... (implementation of get)
}
// ... (full implementation of set, remove, etc.)
}
(A complete implementation can be found in the example package of the project repository.)
4. Run the Code Generator #
Run the build_runner command in your terminal to generate the settings.g.dart part file.
dart run build_runner build --delete-conflicting-outputs
5. Use Your Preference Module #
Instantiate and use your type-safe AppSettings class.
// Initialization
final adapter = MyPreferenceAdapter();
final appSettings = AppSettings(adapter);
// Usage
await appSettings.setThemeMode(ThemeMode.dark);
final currentTheme = appSettings.themeMode; // Access value synchronously
Advanced Usage #
Building a Reactive UI with ChangeNotifier #
For building UIs that react automatically to preference changes, you can mix in Flutter's
ChangeNotifier. The generator will detect this and automatically call notifyListeners() after a
preference is updated.
-
Add the
ChangeNotifierMixin:import 'package:flutter/foundation.dart'; // Required for ChangeNotifier // ... other imports @PreferenceModule() abstract class AppSettings with _$AppSettings, ChangeNotifier { // Add ChangeNotifier // ... same factory constructor as before } -
Listen to Changes in Your UI: You can now use a
ListenableBuilder(or other state management solutions that work withListenable) to rebuild only the widgets that depend on a specific preference. This is highly efficient.// In your UI widget // Get your settings instance (e.g., via a DI framework like get_it) final appSettings = getIt<AppSettings>(); ListenableBuilder( listenable: appSettings, builder: (context, child) { // This Text widget will rebuild whenever any setting changes. return Text('Current theme is: ${appSettings.themeMode.name}'); }, )
License #
This project is licensed under the MIT License.