与天地兮比寿,与日月兮齐光。这篇文章主要讲述Flutter 专题47 图解新的状态管理 Provider#yyds干货盘点#相关的知识,希望能为你提供帮助。
小菜前几天学习了一下新的状态管理框架 Provider,Provier 支持多种类型的状态管理方式,小菜继续学习其余几种;
ListenableProvider 方式
1. 数据绑定
- ListenableProvider(Key key, @required ValueBuilder< T> builder, Disposer< T> dispose, Widget child )
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
return ListenableProvider<
User>
(
builder: (_) =>
User(Flutter, 0),
child: MaterialApp(
title: Flutter Demo,
theme: ThemeData(primarySwatch: Colors.blue),
home: MyHomePage(title: Peovider Demo)));
- ListenableProvider.value(Key key, @required T listenable, Widget child )
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
return ListenableProvider<
User>
.value(
listenable: User(Flutter, 0),
child: MaterialApp(
title: Flutter Demo,
theme: ThemeData(primarySwatch: Colors.blue),
home: MyHomePage(title: Peovider Demo)));
2. 获取数据 小菜在上一篇博客中未曾提及,基本所有的获取数据方式基本相同且均支持两种方式;
- Provider.of(context) 方式
class ProviderText extends StatelessWidget @override Widget build(BuildContext context) final user = Provider.of< User> (context); return Text($user.getName);
- Consumer Widget 构造器方式
class ProviderText extends StatelessWidget @override Widget build(BuildContext context) return Consumer< User> (builder: (context, user, _) return Text(user.getName); );
ValueListenableProvider 方式
【Flutter 专题47 图解新的状态管理 Provider#yyds干货盘点#】 使用 ValueListenableProvider 方式时要注意,需要绑定的数据要继承自 ValueNotifier< T> ,并实现其构造方法,通过对 value 的操作进行更新;小菜新建一个 person 实体类进行操作;
// 基本数据类型 class StringBean extends ValueNotifier< String> StringBean(String value) : super(value);
class Person extends ValueNotifier< User>
Person(User value) : super(value);
String get getPersonName => value.name;
void setPersonName(String name)
value.name = name;
notifyListeners();
#### 1. 绑定数据
1. **ValueListenableProvider(Key key, @required ValueBuilder<
ValueNotifier<
T>
>
builder, UpdateShouldNotify<
T>
updateShouldNotify, Widget child )**&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
通过构造器绑定数据并进行监听,且构造器 **builder** 不可为空;
class MyApp extends StatelessWidget @override
br/>@override
return ValueListenableProvider< User> (
builder: (_) => Person(User(person, 101)),
child: MaterialApp(
title: Flutter Demo,
theme: ThemeData(primarySwatch: Colors.blue),
home: MyHomePage(title: Peovider Demo)));
2. **ValueListenableProvider.value(Key key, @required ValueListenable<
T>
valueListenable, UpdateShouldNotify<
T>
updateShouldNotify, Widget child )**&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
通过 **.value** 方式对数据进行绑定监听;
class MyApp extends StatelessWidget @override
br/>@override
return ValueListenableProvider< User> .value(
valueListenable: Person(User(person, 101)),
child: MaterialApp(
title: Flutter Demo,
theme: ThemeData(primarySwatch: Colors.blue),
home: MyHomePage(title: Peovider Demo)));
#### 2. 获取数据
&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
获取数据的方式与上述基本一致;
class ProviderText extends StatelessWidget @override
br/>@override
final number = Provider.of< String> (context);
final person = Provider.of< User> (context);
return Center(
child: Column(children: < Widget> [
Text($number.toString()==$person.getName),
Consumer< User> (builder: (context, user, _)
return Text(user.getName);
)
]));
![4701.gif](https://s2.51cto.com/images/20211227/1640568764211683.gif)### StreamProvider 方式
#### 1. Stream 简介
&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
**Stream** 存在于 **Dart:async** 库中,主要用于处理异步操作;在 **ListView** 展示网络接口数据时曾用到过;小菜对 **Stream** 的理解还不够深入,基本理解为一个处理器,通过 **StreamController<
T>
()..sink.add()** 输入需要处理的数据,通过 **StreamController<
T>
()..stream** 输出处理后的数据;整个过程都需要通过 **StreamController** 来控制;具体的单 **stream** 和多 **stream** 方式小菜稍后研究;
#### 2. 绑定数据
1. **StreamProvider(Key key, @required ValueBuilder<
StreamController<
T>
>
builder, T initialData, ..., Widget child )**&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
通过构建器创建 **StreamController** 然后绑定数据,注意需要在 **initialData** 中初始化绑定数据;
class MyApp extends StatelessWidget @override
br/>@override
return StreamProvider< Teacher> (
builder: (_) => StreamController< Teacher> (),
initialData: Teacher(Teacher, 101),
child: MaterialApp(
title: Flutter Demo,
theme: ThemeData(primarySwatch: Colors.blue),
home: MyHomePage(title: Peovider Demo)));
class Teacher
var tname;
var tage;
Teacher(this.tname, this.tage);
Expanded(child: TextField(
onChanged: (changed)
teacher.tname = changed;
teacher.tage = 150;
StreamController< Teacher> ().sink.add(teacher);
,
controller: _phonecontroller,
decoration: InputDecoration(
hintText: 请输入用户名,
suffixIcon: IconButton(
icon: Icon(Icons.clear, color: Colors.black45),
onPressed: ()
_phonecontroller.clear();
))))
2. **StreamProvider.value(Key key, @required Stream<
T>
stream, T initialData, ..., Widget child )**&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
通过 **.value** 方式对 **StreamController** 的 **stream** 进行数据绑定,同样需要在 **initialData** 中初始化数据;
class MyApp extends StatelessWidget @override
br/>@override
return StreamProvider< Teacher> .value(
stream: StreamController< Teacher> ().stream,
initialData: Teacher(Teacher, 101),
child: MaterialApp(
title: Flutter Demo,
theme: ThemeData(primarySwatch: Colors.blue),
home: MyHomePage(title: Peovider Demo)));
#### 3. 获取数据
class ProviderText extends StatelessWidget @override
br/>@override
final teacher = Provider.of< Teacher> (context);
return Center(
child: Column(children: < Widget> [
Text($teacher.tname),
Consumer< Teacher> (builder: (context, teacher, _)
return Text($teacher.tname==$teacher.tage);
)
]));
![4702.gif](https://s2.51cto.com/images/20211227/1640568752477209.gif)
### 小结
1. 为方便理解,结合上一节的 **ChangeNotifierProvider**,发现与 **ListenableProvider** 和 **ValueListenableProvider** 的使用基本相同;
class ChangeNotifierProvider< T extends ChangeNotifier>
extends ListenableProvider< T> implements SingleChildCloneableWidget
class ChangeNotifier implements Listenable
class ValueListenableProvider< T>
extends AdaptiveBuilderWidget< ValueListenable< T> , ValueNotifier< T> >
implements SingleChildCloneableWidget
class ValueNotifier< T> extends ChangeNotifier implements ValueListenable< T>
&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
分析源码:**ChangeNotifierProvider** 继承自 **ListenableProvider** 且对应的 **ChangeNotifier** 继承自 **listenable**;算是 **ListenableProvider** 的子类;**ValueNotifier** 继承自 **ChangeNotifier** 也与 **ChangeNotifierProvider** 相似;2. 使用 **ChangeNotifierProvider** 和 **ValueListenableProvider** 绑定实体类时需要注意分别继承对应的 **ChangeNotifier** 和 **ValueNotifier**;
class User with ChangeNotifier
class Person extends ValueNotifier< User>
3. 无论使用那种 **.value** 方式,均建议在 **dispose** 中进行 **listener** 的关闭;
@override
void dispose()
stream.dispose();
super.dispose();
***
&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
&
nbsp;
小菜将 **Provier** 中提及的五种方式均尝试了一下,对于同一类的实体类也进行测试,如有错误请多多指导!>
来源:阿策小和尚
推荐阅读
- 开源app 控制ESP8266,通过mqtt,app inventor开发
- Linux之locate命令
- #yyds干货盘点#算法开启小码农双链表血脉
- #yyds干货盘点# springboot实现文件上传
- #私藏项目实操分享# 如何解决 Angular custom library module 在 ng build 时无法被识别的错误
- 初识应急响应 (持续更新中)
- #yyds干货盘点#CMake项目编译实战
- WordPress-所有页面链接到index.php文件
- WooCommerce(如何在商店页面中隐藏/删除产品标题下的类别())