当前位置:网站首页>BlocProvider为什么感觉和Provider很相似?
BlocProvider为什么感觉和Provider很相似?
2022-07-01 23:31:00 【岛上码农@公众号同名】
前言
上一篇Flutter 入门与实战(八十六):不到40行代码手撸一个BlocProvider,我们只用了不到40行代码手撸了一个 SimpleBlocProvider,用起来感觉也还可以,这就是 Bloc 的优势之一,你可以基于 Bloc 这种模式自己做扩展,形成自己的状态管理组件。我们这一篇来看看官方 flutter_bloc 插件提供的 BlocProvider 怎么样。
Provider 的模仿者?
我们先来看 BlocProvider 实现的计数器示例代码:
class BlocCounterWrapper extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (_) => CounterCubit(),
child: BlocCounterPage(),
);
}
}
class BlocCounterPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Bloc 计数器'),
),
body: Center(
child: BlocBuilder<CounterCubit, int>(
builder: (context, count) => Text(
'$count',
style: TextStyle(
fontSize: 32,
color: Colors.blue,
),
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
context.read<CounterCubit>().increment();
},
tooltip: '点击增加',
child: Icon(Icons.add),
),
);
}
}
这代码是不是十分熟悉?如果回顾我们之前的 Provider 状态管理,感觉是十分相似啊!比如:
Widget build(BuildContext context) {
return BlocProvider(
create: (_) => CounterCubit(),
child: BlocCounterPage(),
);
}
在 Provider 里实现就是下面这样。
Widget build(BuildContext context) {
return Provider(
create: (_) => CounterCubit(),
child: BlocCounterPage(),
);
}
而在 FloatingActionButton 里的 context.read 用法也和 Provider 里的一样。所以,如果要从 Provider 迁移到 Bloc 也是十分简单的。实际从源码逐层向上,你会发现里面就有 provider 的代码。
library flutter_bloc;
export 'package:bloc/bloc.dart';
export 'package:provider/provider.dart'
show ProviderNotFoundException, ReadContext, SelectContext, WatchContext;
而从 Provider 和 bloc 的GitHub源码贡献者中我们也发现 Provider 的代码贡献者Felix Angelov 就是 bloc 代码的发起者。。 
所以这就不奇怪 Bloc 中使用 Provider 了。
与 Provider 的异同
BlocProvider 和 Provider一样,通过组件树为子组件提供状态数据。也就是我们可以像使用 Provider 一样使用 BlocProvider,比如使用已有的状态对象时的哟用法和 Provider 一样使用 value 参数赋值:
final counter = CounterCubit();
//...
BlocProvider.value(
value: counter,
child: SomeWidget(),
);
在比如可以在子组件中使用 context.read 和 context.watch。以及使用 select 方法监听状态数据的部分变化。
final isPositive = context.select((CounterBloc b) => b.state >= 0);
还有 MultiBlocProvider来向子组件树传递多个Bloc状态对象。
MultiBlocProvider(
providers: [
BlocProvider<BlocA>(
create: (BuildContext context) => BlocA(),
),
BlocProvider<BlocB>(
create: (BuildContext context) => BlocB(),
),
BlocProvider<BlocC>(
create: (BuildContext context) => BlocC(),
),
],
child: ChildA(),
)
可以说,如果之前你用 Provider 状态管理的话,可以无缝迁移到 BlocProvider。当然,状态对象类还是需要改一下的。这也是 BlocProvider 和 Provider 的区别。比如状态对象不需要实现 ChangeNotifier 接口,在状态数据改变的时候也无需调用 notifyListeners 来通知刷新。实际我们从 BlocProvider 的源码扒出了一段监听状态对象实现的方法,这里其实也是使用我们在 SimpleBlocProvider 中使用的 Stream.listen 方法来实现的。
static VoidCallback _startListening(
InheritedContext<BlocBase?> e,
BlocBase value,
) {
final subscription = value.stream.listen(
(dynamic _) => e.markNeedsNotifyDependents(),
);
return subscription.cancel;
}
而其他部分的代码基本就是复用 Provider 的代码。所以 BlocProvider 可以看成是使用了 Stream.listen 监听状态数据的方式替换 ChangeNotifer 的 Provider 的变种。因此,如果想从 Provider 切换到 BlocProvider,可以大胆地切换,代码修改工作量很低。而且无需在状态对象里反复调用 notifyListeners来通知界面刷新了。
总结
本篇介绍了 BlocProvider 的使用,从写法上来看,感觉不到太多的优势,个人估计这是作者想让 Provider 的用户可以直接切换到 BlocProvider 才提供了这么一个 Provider的替代品。不过,这只是冰山一脚,实际上,flutter_bloc 还提供了很多其他的选择,我们接下来会一一介绍。 
边栏推荐
- 内存泄露和内存溢出的区别是什么?
- Current situation and future development trend of Internet of things
- Applet form verification encapsulation
- 物联网开发零基础教程
- 硅谷产品实战学习感触
- 距离度量 —— 汉明距离(Hamming Distance)
- What is the mosaic tailgate?
- PostgreSQL source code (57) why is the performance gap so large in hot update?
- 2021 RoboCom 世界机器人开发者大赛-高职组复赛
- 【.Net Core】程序相关各种全局文件
猜你喜欢

PostgreSQL source code (57) why is the performance gap so large in hot update?

安全协议重点

Huisheng Huiying 2022 intelligent, fast and simple video editing software

Redis RDB快照

深度学习 | 三个概念:Epoch, Batch, Iteration

Linux基础 —— CentOS7 离线安装 MySQL

Stm32f030f4 drives tim1637 nixie tube chip

flutter Unable to load asset: assets/images/888. png

神经网络物联网的未来趋势与发展

物联网现状及未来发展趋势
随机推荐
门级建模—课后习题
What category does the Internet of things application technology major belong to
Win 10 mstsc connect RemoteApp
excel如何打开100万行以上的csv文件
[untitled]
Linux基础 —— CentOS7 离线安装 MySQL
共享电商的背后: 共创、共生、共享、共富,共赢的共富精神
Typescript enumeration
Linux foundation - centos7 offline installation of MySQL
Create Ca and issue certificate through go language
How to display real-time 2D map after rviz is opened
SWT / anr problem - SWT causes low memory killer (LMK)
有没有一段代码,让你为人类的智慧所折服
Redis RDB snapshot
使用 pair 做 unordered_map 的键值
Is it safe to choose mobile phone for stock trading account opening in Shanghai?
物联网现状及未来发展趋势
Yunxin small class | common cognitive misunderstandings in IM and audio and video
URL introduction
Door level modeling - after class exercises