Flutter持久化上下文管理插件persistent_context的使用
Flutter持久化上下文管理插件persistent_context的使用
PersistentContext
PersistentContext
是一个 Flutter 小部件,它提供了简单的同步接口来存储持久变量,并在底层依赖于共享偏好设置。
基本用法
要在一个小部件中开始使用持久变量,只需将其包装在 PersistentContext
小部件内。你可以通过 PersistentContext.of(context)
从任何后代小部件访问 PersistentContext
实例及其方法。
简单调用 set(key, value)
方法来设置名为 key
的持久变量并带有值 value
,而 get(key)
方法用于访问该值。请注意,由于共享偏好设置的限制,value
只能有以下类型:
int
double
bool
String
每次设置值时,它将立即反映在 UI 上,并异步地在后台进行持久化。
然而,当你的应用程序第一次启动时,数据会从本地存储异步加载,因此如果在 PersistentContext
初始化之前调用 get
方法,则可能会返回 null
(或者指定的默认值)。
你可以检查 ready
未来来等待初始化完成,以避免任何不便。
下面的示例展示了如何使用 PersistentContext
构建一个简单的计数器应用,该应用保持计数的持久性。注意,不需要状态小部件,因为 PersistentContext
也充当简单的状态管理器。
import 'package:flutter/material.dart';
import 'package:persistent_context/persistent_context.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'PersistentContext Demo',
home: Scaffold(
appBar: AppBar(
title: Text('PersistentContext Demo'),
),
body: Center(
child: PersistentContext(
child: CounterWidget(),
),
),
),
);
}
}
class CounterWidget extends StatelessWidget {
void _increment(BuildContext context) {
final currentCount = PersistentContext.of(context).get('counter') ?? 0;
PersistentContext.of(context).set(
'counter',
currentCount + 1,
);
}
void _reset(BuildContext context) {
PersistentContext.of(context).set('counter', 0);
}
[@override](/user/override)
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'This counter will persist after restarting the app:',
),
Text(
'${PersistentContext.of(context).get('counter') ?? 0}',
style: Theme.of(context).textTheme.headline4,
),
ButtonBar(
alignment: MainAxisAlignment.center,
children: [
ElevatedButton.icon(
onPressed: () => _increment(context),
icon: Icon(Icons.add),
label: Text('Increment'),
),
ElevatedButton.icon(
onPressed: () => _reset(context),
icon: Icon(Icons.refresh),
label: Text('Reset'),
),
],
),
],
);
}
}
高级功能
PersistentContext
构造函数包含以下可选参数,这些参数可能在高级用例中很有用:
defaultValues
: 一个键值映射,定义持久记录的默认值。注意,如果定义了默认值,则变量只能设置为相同类型的值。prefix
: 一个字符串前缀,将添加到所有共享偏好设置的键上。如果有多个PersistentContext
实例,应使用它来避免冲突。sharedPreferencesInstance
: 一个可以直接使用的SharedPreferences
实例。如果没有提供,则构造函数将异步创建一个新的SharedPreferences
对象,这会导致一个小延迟。
以下代码片段说明了如何在前面的示例中使用这些参数:
PersistentContext(
child: CounterWidget(),
prefix: 'counterContext',
defaultValues: {
'counter': 0,
},
sharedPreferencesInstance: sharedPrefs,
)
扩展
为了保持代码尽可能干净和健壮,建议不要直接使用 PersistentContext
,而是扩展它以创建一个自定义类,该类通过专用的 getter 和 setter 为每个持久变量调用 get
和 set
方法,并且还静态地定义了默认值。
例如,考虑以下实现的计数器应用程序示例:
class CustomPersistentContext extends PersistentContext {
// 默认值
static final _counterDefault = 0;
// 构造函数
CustomPersistentContext({
Key? key,
required Widget child,
}) : super(
key: key,
child: child,
defaultValues: {
'counter': _counterDefault,
},
);
// Getter 和 Setter
int get counter => get('counter') ?? _counterDefault;
set counter(int value) {
set('counter', value);
}
// 这是为了让 `of` 方法工作
static CustomPersistentContext of(BuildContext context) {
return context
.dependOnInheritedWidgetOfExactType<CustomPersistentContext>()!;
}
}
CounterWidget
中的 _increment
和 _reset
方法可以简化如下:
void _increment(BuildContext context) {
CustomPersistentContext.of(context).counter++;
}
void _reset(BuildContext context) {
CustomPersistentContext.of(context).counter = 0;
}
完整示例
以下是完整的示例代码,包括 MyApp
和 CounterWidget
类:
import 'package:flutter/material.dart';
import 'package:persistent_context/persistent_context.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'PersistentContext Demo',
home: Scaffold(
appBar: AppBar(
title: Text('PersistentContext Demo'),
),
body: Center(
child: CustomPersistentContext(
child: CounterWidget(),
),
),
),
);
}
}
class CounterWidget extends StatelessWidget {
void _increment(BuildContext context) {
CustomPersistentContext.of(context).counter++;
}
void _reset(BuildContext context) {
CustomPersistentContext.of(context).counter = 0;
}
[@override](/user/override)
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'This counter will persist after restarting the app:',
),
Text(
'${CustomPersistentContext.of(context).counter}',
style: Theme.of(context).textTheme.headline4,
),
ButtonBar(
alignment: MainAxisAlignment.center,
children: [
ElevatedButton.icon(
onPressed: () => _increment(context),
icon: Icon(Icons.add),
label: Text('Increment'),
),
ElevatedButton.icon(
onPressed: () => _reset(context),
icon: Icon(Icons.refresh),
label: Text('Reset'),
),
],
),
],
);
}
}
class CustomPersistentContext extends PersistentContext {
// 默认值
static final _counterDefault = 0;
// 构造函数
CustomPersistentContext({
Key? key,
required Widget child,
}) : super(
key: key,
child: child,
defaultValues: {
'counter': _counterDefault,
},
);
// Getter 和 Setter
int get counter => get('counter') ?? _counterDefault;
set counter(int value) {
set('counter', value);
}
// 这是为了让 `of` 方法工作
static CustomPersistentContext of(BuildContext context) {
return context
.dependOnInheritedWidgetOfExactType<CustomPersistentContext>()!;
}
}
更多关于Flutter持久化上下文管理插件persistent_context的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter持久化上下文管理插件persistent_context的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter应用中使用persistent_context
插件进行持久化上下文管理的代码示例。persistent_context
插件允许你在Flutter应用中轻松地进行状态持久化,特别是在需要跨页面或应用重启后保持数据的情况下。
首先,确保你已经在pubspec.yaml
文件中添加了persistent_context
依赖:
dependencies:
flutter:
sdk: flutter
persistent_context: ^x.y.z # 请替换为最新版本号
然后,运行flutter pub get
来获取依赖。
接下来,让我们看看如何在Flutter应用中使用persistent_context
。
1. 初始化PersistentContext
在你的应用入口(通常是main.dart
)中初始化PersistentContext
:
import 'package:flutter/material.dart';
import 'package:persistent_context/persistent_context.dart';
void main() {
// 初始化PersistentContext
PersistentContext.init(
storage: Storage.sharedPreferences, // 使用SharedPreferences作为存储后端
);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomeScreen(),
);
}
}
2. 保存和读取数据
现在,你可以在任何需要的地方保存和读取数据。以下是一个简单的示例,展示如何在两个屏幕之间持久化数据。
HomeScreen.dart
import 'package:flutter/material.dart';
import 'package:persistent_context/persistent_context.dart';
import 'second_screen.dart';
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home Screen'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Persistent Context Demo'),
ElevatedButton(
onPressed: () async {
// 保存数据到PersistentContext
await PersistentContext.of(context).save('key', 'Hello, Persistent Context!');
Navigator.push(context, MaterialPageRoute(builder: (context) => SecondScreen()));
},
child: Text('Save and Go to Second Screen'),
),
],
),
),
);
}
}
SecondScreen.dart
import 'package:flutter/material.dart';
import 'package:persistent_context/persistent_context.dart';
class SecondScreen extends StatefulWidget {
@override
_SecondScreenState createState() => _SecondScreenState();
}
class _SecondScreenState extends State<SecondScreen> {
String? _value;
@override
void initState() {
super.initState();
// 在initState中读取数据
_readValue();
}
Future<void> _readValue() async {
String? value = await PersistentContext.of(context).read<String>('key');
setState(() {
_value = value;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Screen'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Persistent Context Demo - Second Screen'),
if (_value != null)
Text(
'Retrieved Value: $_value',
style: TextStyle(fontSize: 20),
),
],
),
),
);
}
}
总结
以上代码示例展示了如何在Flutter应用中使用persistent_context
插件进行持久化上下文管理。通过在main.dart
中初始化PersistentContext
,你可以在任何需要的地方使用PersistentContext.of(context).save
和PersistentContext.of(context).read
方法来保存和读取数据。这非常适合于需要跨页面或应用重启后保持数据的场景。