Flutter 专题47 图解新的状态管理 Provider #yyds干货盘点#
Posted 阿策小和尚
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter 专题47 图解新的状态管理 Provider #yyds干货盘点#相关的知识,希望对你有一定的参考价值。
小菜前几天学习了一下新的状态管理框架 Provider,Provier 支持多种类型的状态管理方式,小菜继续学习其余几种;
ListenableProvider 方式
1. 数据绑定
- ListenableProvider(Key key, @required ValueBuilder<T> builder, Disposer<T> dispose, Widget child )
通过构造器绑定数据并进行监听,当从 Widget Tree 中删除时 dispose 要销毁;注意:构造器 builder 不可为空;
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 )
通过 .value 方式对数据进行监听 listenable;
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 方式
使用 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 )**
通过构造器绑定数据并进行监听,且构造器 **builder** 不可为空;
class MyApp extends StatelessWidget br/>@override
Widget build(BuildContext context)
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 )**
通过 **.value** 方式对数据进行绑定监听;
class MyApp extends StatelessWidget br/>@override
Widget build(BuildContext context)
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. 获取数据
获取数据的方式与上述基本一致;
class ProviderText extends StatelessWidget br/>@override
Widget build(BuildContext context)
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 简介
**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 )**
通过构建器创建 **StreamController** 然后绑定数据,注意需要在 **initialData** 中初始化绑定数据;
class MyApp extends StatelessWidget br/>@override
Widget build(BuildContext context)
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 )**
通过 **.value** 方式对 **StreamController** 的 **stream** 进行数据绑定,同样需要在 **initialData** 中初始化数据;
class MyApp extends StatelessWidget br/>@override
Widget build(BuildContext context)
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 br/>@override
Widget build(BuildContext context)
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>
分析源码:**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();
***
小菜将 **Provier** 中提及的五种方式均尝试了一下,对于同一类的实体类也进行测试,如有错误请多多指导!
> 来源:阿策小和尚
以上是关于Flutter 专题47 图解新的状态管理 Provider #yyds干货盘点#的主要内容,如果未能解决你的问题,请参考以下文章
Flutter 专题29 图解自定义底部状态栏 ACEBottomNavigationBar #yyds干货盘点#
Flutter 专题30 图解自定义底部状态栏 ACEBottomNavigationBar #yyds干货盘点#
Android:Flutter 专题03 图解第一个程序 Hello World