Flutter偏好设置管理插件easy_prefs_gen的使用
Flutter偏好设置管理插件easy_prefs_gen的使用
Flutter代码生成器,用于生成易于使用的shared_preferences。
Setup
在依赖项中添加easy_prefs和shared_preferences,并在开发依赖项中添加easy_prefs_gen和build_runner。
注意:如果将[providerExtensionMethods]设置为true,则还需要添加provider。
dependencies:
easy_prefs: [version]
shared_preferences: ^2.0.11
dev_dependencies:
build_runner: [version]
easy_prefs_gen: [version]
在你的main.dart文件中:
// 导入这两个包
import 'package:easy_prefs/easy_prefs.dart';
import 'package:shared_preferences/shared_preferences.dart';
Future<void> main() async {
// 添加这两行
WidgetsFlutterBinding.ensureInitialized();
await EasyPrefs.initialize(await SharedPreferences.getInstance());
// ...
runApp(const MyApp());
}
运行代码生成器
一旦你在代码中添加了注解,就需要运行代码生成器来生成缺失的.g.dart生成的Dart文件。
dart run build_runner build
// 或者监听模式
dart run build_runner watch
示例
假设有一个名为example.dart的Dart文件,其中包含一个带有[PrefsAnnotation]注解的Settings类:
import 'package:easy_prefs/easy_prefs.dart';
import 'package:flutter/material.dart'; // 如果设置了[changeProvider]为true,则需要导入
import 'package:provider/provider.dart'; // 如果设置了[providerExtensionMethods]为true,则需要导入
part 'example.g.dart';
@PrefsAnnotation(
{
"username": "",
"notification": true,
"notificationSound": true,
"exchangeRate": 1.1,
"language": LanguageCodes.kmr,
"likeCount": 0,
"favs": PrefsStringList(["asf", "afsaf"]),
"favs2": ["asf", "afsaf"],
},
changeNotifier: true,
onlyModifier: true,
providerExtensionMethods: true,
toggleMethodForBoolValues: true,
)
class Settings extends _$Settings {}
构建后会创建相应的部分文件example.g.dart:
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'example.dart';
// **************************************************************************
// PrefsGenerator
// **************************************************************************
class _Keys {
static const String username = 'username';
static const String notification = 'notification';
static const String notificationSound = 'notificationSound';
static const String exchangeRate = 'exchangeRate';
static const String language = 'language';
static const String likeCount = 'likeCount';
static const String favs = 'favs';
static const String favs2 = 'favs2';
}
class _$Settings extends IEasyPrefs with ChangeNotifier {
final _helper = SharedPreferencesHelper();
final _Keys = const _Keys();
/// 如果[silent]为true,则值更改不会通知。
_$Settings({bool silent = false}) {
if (silent) return;
_helper.onNotify = onValueChanged;
}
[@override](/user/override)
void onValueChanged(String key) {
notifyListeners();
}
String? _$username;
String get username => _$username ?? _helper.getString(_Keys.username, '');
set username(String val) => _helper.setString(_Keys.username, val, (_) => _$username = val);
bool? _$notification;
bool get notification => _$notification ?? _helper.getBool(_Keys.notification, true);
set notification(bool val) => _helper.setBool(_Keys.notification, val, (_) => _$notification = val);
bool toggleNotification() => _helper.toggleBool(_Keys.notification, true, (val) => _$notification = val);
bool? _$notificationSound;
bool get notificationSound => _$notificationSound ?? _helper.getBool(_Keys.notificationSound, true);
set notificationSound(bool val) => _helper.setBool(_Keys.notificationSound, val, (_) => _$notificationSound = val);
bool toggleNotificationSound() => _helper.toggleBool(_Keys.notificationSound, true, (val) => _$notificationSound = val);
double? _$exchangeRate;
double get exchangeRate => _$exchangeRate ?? _helper.getDouble(_Keys.exchangeRate, 1.1);
set exchangeRate(double val) => _helper.setDouble(_Keys.exchangeRate, val, (_) => _$exchangeRate = val);
LanguageCodes? _$language;
LanguageCodes get language => _$language ?? _helper.getEnum(_Keys.language, LanguageCodes.values, LanguageCodes.kmr);
set language(LanguageCodes val) => _helper.setInt(_Keys.language, val.index, (_) => _$language = val);
int? _$likeCount;
int get likeCount => _$likeCount ?? _helper.getInt(_Keys.likeCount, 0);
set likeCount(int val) => _helper.setInt(_Keys.likeCount, val, (_) => _$likeCount = val);
NotifiableStringList? _$favs;
NotifiableStringList get favs => _$favs ?? _helper.getStringList(_Keys.favs, ['asf', 'afsaf']);
set favs(NotifiableStringList val) => _helper.setStringList(_Keys.favs, val, (_) => _$favs = val);
NotifiableStringList? _$favs2;
NotifiableStringList get favs2 => _$favs2 ?? _helper.getStringList(_Keys.favs2, ['asf', 'afsaf']);
set favs2(NotifiableStringList val) => _helper.setStringList(_Keys.favs2, val, (_) => _$favs2 = val);
[@override](/user/override)
void initializeAll() {
final tmp = _helper.onNotify;
_helper.onNotify = null;
username = username;
notification = notification;
notificationSound = notificationSound;
exchangeRate = exchangeRate;
language = language;
likeCount = likeCount;
favs = favs;
favs2 = favs2;
_helper.onNotify = tmp;
_helper.onNotify?.call("");
}
[@override](/user/override)
bool isTouched() {
return _helper.hasKey(_Keys.username) ||
_helper.hasKey(_Keys.notification) ||
_helper.hasKey(_Keys.notificationSound) ||
_helper.hasKey(_Keys.exchangeRate) ||
_helper.hasKey(_Keys.language) ||
_helper.hasKey(_Keys.likeCount) ||
_helper.hasKey(_Keys.favs) ||
_helper.hasKey(_Keys.favs2);
}
[@override](/user/override)
String toString() {
return '''
{
"username" : "$username",
"notification" : $notification,
"notificationSound" : $notificationSound,
"exchangeRate" : $exchangeRate,
"language" : $language,
"likeCount" : $likeCount,
"favs" : [
${favs.map((e) => '"$e"').join(",\n ")}
],
"favs2" : [
${favs2.map((e) => '"$e"').join(",\n ")}
]
}
''';
}
}
extension SettingsProviderExtensionMethodsOnBuildContext on BuildContext {
Settings readSettings() => read<Settings>();
Settings watchSettings() => watch<Settings>();
R selectSettings<R>(R Function(Settings s) selector) => select(selector);
}
消费该类(main.dart)
import 'package:easy_prefs/easy_prefs.dart';
import 'package:easy_prefs_example/settings.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized(); // 重要
await EasyPrefs.initialize(await SharedPreferences.getInstance()); // 重要
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'EasyPrefs Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ChangeNotifierProvider(
create: (_) => Settings(),
builder: (_, __) {
return const MyHomePage();
},
),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
final settings = context.watchSettings();
final lastValInFavList = int.parse(settings.favs.isNotEmpty ? settings.favs.last : "0");
return Scaffold(
appBar: AppBar(
title: const Text("EasyPrefs Demo"),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
CheckboxListTile(
value: settings.notification,
title: const Text("Enable notification"),
onChanged: (t) => settings.notification = t!,
),
CheckboxListTile(
value: settings.notificationSound,
title: const Text("Enable notification sound"),
onChanged: (t) => settings.notificationSound = t!,
),
const Divider(height: 1),
ListTile(
title: const Text("Language"),
trailing: DropdownButton(
value: settings.language,
items: LanguageCodes.values
.map((e) => DropdownMenuItem(
child: Text(e.name, textScaler: TextScaler.linear(1.2)),
value: e,
))
.toList(),
onChanged: (LanguageCodes? lang) {
if (lang != null) {
settings.language = lang;
}
},
),
),
const Divider(height: 1),
Row(
children: [
const Padding(
padding: EdgeInsets.all(16.0),
child: Text("View Count: ", textScaler: TextScaler.linear(1.2)),
),
const Spacer(),
IconButton(onPressed: () => settings.likeCount--, icon: const Icon(Icons.remove)),
Text(settings.likeCount.toString(), textScaler: TextScaler.linear(1.2)),
IconButton(onPressed: () => settings.likeCount++, icon: const Icon(Icons.add)),
],
),
const Divider(height: 1),
Row(
children: [
const Padding(
padding: EdgeInsets.all(16.0),
child: Text("Fav Items: ", textScaler: TextScaler.linear(1.2)),
),
const Spacer(),
ElevatedButton(onPressed: () => settings.favs.removeLast(), child: const Icon(Icons.remove)),
const SizedBox(width: 5),
ElevatedButton(onPressed: () => settings.favs.add("${lastValInFavList + 1}"), child: const Icon(Icons.add)),
],
),
const Divider(height: 20),
const Padding(
padding: EdgeInsets.fromLTRB(20, 10, 20, 0),
child: Text("settings.toString() :", textScaler: TextScaler.linear(1.1)),
),
Padding(
padding: const EdgeInsets.fromLTRB(20, 5, 20, 10),
child: Text(settings.toString()),
),
],
),
),
),
);
}
}
更多关于Flutter偏好设置管理插件easy_prefs_gen的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter偏好设置管理插件easy_prefs_gen的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
easy_prefs_gen 是一个用于 Flutter 应用的插件,它基于 shared_preferences 包,帮助开发者更方便地管理和生成偏好设置(Preferences)的代码。通过代码生成,easy_prefs_gen 可以自动生成用于读取和写入偏好设置的代码,减少手动编写重复代码的工作量。
安装 easy_prefs_gen
首先,你需要在 pubspec.yaml 文件中添加 easy_prefs_gen 和 build_runner 依赖:
dependencies:
flutter:
sdk: flutter
shared_preferences: ^2.0.6 # 或者最新版本
easy_prefs_gen: ^0.1.0 # 或者最新版本
dev_dependencies:
build_runner: ^2.1.0 # 或者最新版本
然后运行 flutter pub get 来安装依赖。
使用 easy_prefs_gen
1. 创建偏好设置类
首先,你需要创建一个 Dart 类,并使用 @Prefs 注解来标记这个类。在这个类中,你可以定义需要存储的偏好设置字段。
import 'package:easy_prefs_gen/easy_prefs_gen.dart';
part 'prefs.g.dart'; // 自动生成的代码将会放在这个文件中
@Prefs()
class MyPrefs {
@PrefsField(defaultValue: 'Guest')
String username;
@PrefsField(defaultValue: 0)
int score;
@PrefsField(defaultValue: false)
bool isLoggedIn;
}
2. 生成代码
接下来,你需要运行 build_runner 来生成代码。在终端中运行以下命令:
flutter pub run build_runner build
运行完成后,easy_prefs_gen 会自动生成一个名为 prefs.g.dart 的文件,其中包含了读取和写入偏好设置的代码。
3. 使用生成的代码
生成的代码中包含了一个 MyPrefs 类的单例实例,你可以直接使用它来读取和写入偏好设置。
import 'package:flutter/material.dart';
import 'prefs.dart'; // 导入生成的代码
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 初始化偏好设置
await MyPrefs.init();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Easy Prefs Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Username: ${MyPrefs.instance.username}'),
ElevatedButton(
onPressed: () {
// 更新偏好设置
MyPrefs.instance.username = 'JohnDoe';
},
child: Text('Update Username'),
),
],
),
),
),
);
}
}

