Flutter状态共享插件inherited_store的使用
Flutter状态共享插件inherited_store的使用
inherited_store
是一个持有数据并重建依赖于更改数据的小部件的继承小部件。此包以 InharitedModel
作为其基础。
优点
- 轻量级(约100行代码)
- 使用Flutter自身的
InheritedModel
来检测需要重建的部分。 - 没有样板代码
缺点
- 没有计算值
- 使用键很麻烦
示例
示例代码在示例标签页中。
开始使用
步骤1:用Store包装你的应用
Store(
data: {
'counter': 1,
},
child: MaterialApp(
/* ... */
),
);
步骤2:使用它
class CounterText extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return Text(Store.of(context, 'counter').get().toString());
}
}
如果你编辑 counter
使用 Store.of(context,'counter').set(2)
,则 CounterText
小部件将自动重建。
什么会被重建?
当你调用 Store.of(context,key)
时,所有当前使用 context
的小部件都会订阅该键的变化。如果键的值发生变化,则使用订阅上下文的小部件将被重建。
例如,在下面的例子中,当 counter
修改时,
只有构建器内部的文本小部件会更新
因为它是通过 c
上下文订阅的,并且只有 c
的后代会被重建。
如果我们将 Store.of(c,'counter')
替换为 Store.of(context,'counter')
,那么当 counter
改变时,整个小部件将被重建,显示时间的文本也会更新。
class StoreText extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Text(DateTime.now().toString()), // 显示此文本小部件构建的时间
Builder(builder: (c) {
return Text(Store.of(c, 'counter').get().toString());
}),
],
);
}
}
示例用例
不可变数据管理
存储在数据映射中的事物应仅使用 set
方法替换。
Store(
data: {
UnmodifiableListView<Post> : UnmodifiableListView<Post>([]), // 在列表上使用add不会通知订阅者
User : User.getSavedUser(),
MyService : MyService(),
AppTheme : AppTheme(),
420 : false, // 键可以是任何东西
'balance' : 12000,
},
child: MaterialApp(
/* ... */
),
);
管理应用程序偏好设置
你可以使用 Inherited_Store
来有效地管理你的应用程序偏好设置。将偏好设置加载到 store
的 data
字段中,然后使用 onValueModified
回调来更新存储的偏好设置。
示例代码
import 'package:flutter/material.dart';
import 'package:inherited_store/inherited_store.dart';
void main() => runApp(SettingsApp());
class SettingsApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return Store(
data: {
'counter': 1,
'counter2': 1,
},
child: MaterialApp(
debugShowCheckedModeBanner: false,
home: MainPage(),
),
);
}
}
class MainPage extends StatefulWidget {
[@override](/user/override)
_MainPageState createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(32.0),
child: SettingsDisplay(),
),
Expanded(
child: Row(
children: <Widget>[
Expanded(
child: Counter(
stKy: 'counter',
),
),
Expanded(
child: Counter(
stKy: 'counter2',
),
),
],
),
),
Expanded(
child: Row(
children: <Widget>[
Expanded(
child: StoreText(
storeKey: 'counter2',
),
),
Expanded(
child: StoreText(
storeKey: 'counter',
),
),
],
),
),
],
),
);
}
}
class SettingsDisplay extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return Column(
children: InheritedStore.of(context)
.data
.entries
.map((e) => Text('${e.key} : ${e.value}'))
.toList());
}
}
class StoreText extends StatelessWidget {
final String storeKey;
const StoreText({Key? key, required this.storeKey}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
FutureBuilder(
future: Future.delayed(Duration(milliseconds: 600)),
builder: (c, s) {
if (s.connectionState != ConnectionState.done) {
return CircularProgressIndicator();
}
return Text(Store.of(context, storeKey).get().toString());
}),
Container(),
],
);
}
}
class Counter extends StatelessWidget {
final String stKy;
const Counter({Key? key, required this.stKy}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
return Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
FutureBuilder(
future: Future.delayed(Duration(milliseconds: 600)),
builder: (context, s) {
if (s.connectionState != ConnectionState.done)
return CircularProgressIndicator();
return Text(Store.of(context, stKy).get().toString());
},
),
ElevatedButton(
child: Text('increment'),
onPressed: () {
Store.of(context, stKy).set(Store.of(context, stKy).get() + 1);
},
),
],
),
);
}
}
更多关于Flutter状态共享插件inherited_store的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter状态共享插件inherited_store的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
inherited_store
是一个用于 Flutter 应用中的状态管理插件,它基于 Flutter 的 InheritedWidget
机制,能够方便地在 widget 树中共享状态。InheritedWidget
是 Flutter 中用于在 widget 树中传递数据的一种机制,而 inherited_store
则在其基础上进行了封装,使得状态管理更加简便。
安装
首先,你需要在 pubspec.yaml
文件中添加 inherited_store
依赖:
dependencies:
flutter:
sdk: flutter
inherited_store: ^1.0.0
然后运行 flutter pub get
来安装依赖。
基本用法
-
创建 Store
Store
是inherited_store
中的核心类,用于存储和管理状态。你可以通过继承Store
来定义自己的状态管理类。import 'package:inherited_store/inherited_store.dart'; class MyStore extends Store { int counter = 0; void increment() { counter++; notifyListeners(); // 通知监听者状态已更新 } }
-
在 Widget 树中提供 Store
使用
InheritedStore
widget 将Store
提供给子 widget。InheritedStore
是一个InheritedWidget
,它可以在 widget 树中传递Store
。import 'package:flutter/material.dart'; import 'package:inherited_store/inherited_store.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: InheritedStore( store: MyStore(), child: HomePage(), ), ); } }
-
在子 Widget 中访问 Store
在子 widget 中,你可以通过
InheritedStore.of<MyStore>(context)
来访问Store
,并且可以在状态更新时自动重建 widget。class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { final store = InheritedStore.of<MyStore>(context); return Scaffold( appBar: AppBar( title: Text('InheritedStore Example'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'Counter: ${store.counter}', style: Theme.of(context).textTheme.headline4, ), SizedBox(height: 20), ElevatedButton( onPressed: store.increment, child: Text('Increment'), ), ], ), ), ); } }