Flutter价值存储与获取插件valuable的使用
Flutter价值存储与获取插件Valuable的使用
关于Valuable
什么是Valuable?
Valuable是另一个状态管理库,它从Riverpod中汲取灵感,并且每个Provider-like都是自治的,可以独立工作。它是一个图状态管理库,旨在尽可能多地构建无状态的小部件树,同时能够在不必要将小部件树分割成无限多个StatelessWidget的情况下刷新部分树。
为什么选择Valuable?
- Riverpod:用于应用的全局状态。
- Valuable:用于局部状态(如小部件、视图等)。
如何使用Valuable?
声明Valuable
根据需要声明一个Valuable:
StatefulValuable<T>
:最常见的类型,可以设置值。FutureValuable<Output, Res>
:处理Future<Res>
并提供Output
。StreamValuable<Output, Msg>
:处理Stream<Msg>
并提供Output
。Valuable<T>
:其他情况,可以是不可变值或评估函数。
对所有Valuable的操作
获取当前值
Valuable<T> myValuable = ...;
myValuable.getValue(); // 获取当前值
在某些情况下,getValue
需要一个ValuableContext
,但通常不是必需的。
监听变化
myValuable.addListener(() {
// 值发生变化时触发
});
标记为无效
myValuable.markToReevaluate();
比较操作
Valuable重定义了一些常见的比较运算符,例如>
、<
、<=
、>=
等。
示例:
Valuable<int> a = ...;
Valuable<int> b = ...;
Valuable<bool> equality = a.equals(b);
StatefulValuable<T>
这是最常用的Valuable类型,可以直接设置其值。
实例化
StatefulValuable<int> counter = StatefulValuable<int>(0);
设置值
counter.setValue(1);
FutureValuable<Output, Res>
用于将Valuable<Future<Res>>
转换为安全运行时的Output
值。
计算构造函数
late final Valuable<Future<int>> distantCounter = ...;
late final FutureValuable<String, int> distantCounterStr = FutureValuable<String, int>(
distantCounter,
dataValue: (ValuableContext? context, int result) => "My counter is $result",
noDataValue: (ValuableContext? context) => "Still in progress",
errorValue: (ValuableContext? context, Object error, StackTrace st) => "Can't retrieve counter !",
);
StreamValuable<Output, Msg>
类似于FutureValuable
,但它处理的是Stream
而不是Future
。
计算构造函数
late final Valuable<Stream<int>> continuousCounter = ...;
late final StreamValuable<String, int> continuousCounterStr = StreamValuable<String, int>(
continuousCounter,
dataValue: (ValuableContext? context, int result) => "$result",
doneValue: (ValuableContext? context) => "Done.",
errorValue: (ValuableContext? context, Object error, StackTrace st) => "On error !",
initialValue: "0",
);
Valuable<T>
这是所有Valuable的基类,提供了两个工厂方法:
简单不可变值
final Valuable<int> zero = Valuable.value(0);
自动评估
final StatefulValuable<int> counter = StatefulValuable<int>(2);
final Valuable<double> halfCounter = Valuable.evaluate((ValuableWatcher watch) => watch(counter) / 2);
print(halfCounter.getValue()); // 输出 '1'
counter.setValue(3); // halfCounter 被通知并重新计算
print(halfCounter.getValue()); // 输出 '1.5'
Valuable与Widget树
ValuableConsumer
这是在Widget树中使用Valuable的最常见方式,用于创建响应式UI。
示例:
final StatefulValuable<Color> myColor = StatefulValuable<Color>(Colors.red);
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Container(
color: Colors.amber,
width: 100,
height: 100,
),
ValuableConsumer(
builder: (BuildContext context, ValuableWatcher watch, _) =>
Container(
color: watch(myColor),
width: 100,
height: 100,
),
),
Row(
children: <Widget>[
TextButton(
onPressed: () => myColor.setValue(Colors.blue),
child: const Text("Blue"),
),
TextButton(
onPressed: () => myColor.setValue(Colors.red),
child: const Text("Red"),
),
],
),
],
);
}
ValuableWidget
在某些情况下,你可能希望定义一个依赖于一个或多个Valuable的可重用Widget。
示例:
class ColoredSquare extends ValuableWidget {
final Valuable<Color> myColor;
const ColoredSquare({
required this.myColor,
Key? key,
}) : super(key: key);
Widget build(BuildContext context, ValuableWatcher watch) {
return Container(
color: watch(myColor),
width: 100,
height: 100,
);
}
}
// 使用
final StatefulValuable<Color> myColor = StatefulValuable<Color>(Colors.red);
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Container(
color: Colors.amber,
width: 100,
height: 100,
),
ColoredSquare(
myColor: myColor,
),
Row(
children: <Widget>[
TextButton(
onPressed: () => myColor.setValue(Colors.blue),
child: const Text("Blue"),
),
TextButton(
onPressed: () => myColor.setValue(Colors.red),
child: const Text("Red"),
),
],
),
],
);
}
watchIt
这是一个扩展方法,允许从最近的ValuableConsumer中读取值并订阅Valuable的变化。
示例:
final StatefulValuable<Color> myColor = StatefulValuable<Color>(Colors.red);
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Container(
color: Colors.amber,
width: 100,
height: 100,
),
Container(
color: myColor.watchIt(context),
width: 100,
height: 100,
),
),
Row(
children: <Widget>[
TextButton(
onPressed: () => myColor.setValue(Colors.blue),
child: const Text("Blue"),
),
TextButton(
onPressed: () => myColor.setValue(Colors.red),
child: const Text("Red"),
),
],
),
],
);
}
完整示例Demo
以下是一个完整的示例,展示了如何使用Valuable来管理颜色状态并在UI中显示:
import 'package:flutter/material.dart';
import 'package:valuable/valuable.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
final StatefulValuable<Color> myColor = StatefulValuable<Color>(Colors.red);
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Valuable Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
color: Colors.amber,
width: 100,
height: 100,
),
ValuableConsumer(
builder: (BuildContext context, ValuableWatcher watch, _) =>
Container(
color: watch(myColor),
width: 100,
height: 100,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
TextButton(
onPressed: () => myColor.setValue(Colors.blue),
child: const Text("Blue"),
),
TextButton(
onPressed: () => myColor.setValue(Colors.red),
child: const Text("Red"),
),
],
),
],
),
),
);
}
}
更多关于Flutter价值存储与获取插件valuable的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter价值存储与获取插件valuable的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter中使用valuable
插件进行值存储与获取的示例代码。valuable
插件允许你在Flutter应用中轻松存储和获取全局状态。
首先,你需要在你的pubspec.yaml
文件中添加valuable
依赖:
dependencies:
flutter:
sdk: flutter
valuable: ^x.y.z # 请替换为最新版本号
然后,运行flutter pub get
来安装依赖。
接下来是一个完整的示例代码,展示如何使用valuable
插件进行值的存储和获取。
主应用代码 (main.dart)
import 'package:flutter/material.dart';
import 'package:valuable/valuable.dart';
void main() {
// 创建一个全局的Valuable实例
final valuable = Valuable<String>();
runApp(MyApp(valuable: valuable));
}
class MyApp extends StatelessWidget {
final Valuable<String> valuable;
MyApp({required this.valuable});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Valuable Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(valuable: valuable),
);
}
}
class MyHomePage extends StatefulWidget {
final Valuable<String> valuable;
MyHomePage({required this.valuable});
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
TextEditingController _controller = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Valuable Demo'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextField(
controller: _controller,
decoration: InputDecoration(labelText: 'Enter a value'),
),
SizedBox(height: 16),
ElevatedButton(
onPressed: () {
// 存储值
widget.valuable.value = _controller.text;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Value stored')),
);
},
child: Text('Store Value'),
),
SizedBox(height: 16),
ElevatedButton(
onPressed: () {
// 获取值
final value = widget.valuable.value;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("Current Value: $value")),
);
},
child: Text('Get Value'),
),
],
),
),
);
}
}
解释
- 创建Valuable实例:在
main
函数中,我们创建了一个全局的Valuable<String>
实例。 - 传递Valuable实例:我们将
Valuable
实例传递给MyApp
,然后进一步传递给MyHomePage
。 - 存储值:在
_MyHomePageState
的build
方法中,我们有一个TextField
用于输入值,并通过点击按钮将输入的值存储到Valuable
实例中。 - 获取值:通过点击另一个按钮,我们从
Valuable
实例中获取当前存储的值,并通过SnackBar
显示出来。
这样,你就可以在Flutter应用中轻松地存储和获取全局状态了。希望这个示例对你有帮助!