flutter - Flutter:与 Provider 的 UI 反应
问题描述
- 在某些情况下,我想使用 Navigator 导航到另一个屏幕。 我可以使用 BlocListener 轻松实现它:
BlocListener<BlocA, BlocAState>(
bloc: blocA,
listener: (context, state) {
if (state is Success) {
Navigator.of(context).pushNamed('/details');
}
},
child: Container(),
)
但是我在纯提供者中找不到它的直接等价物。我看到的唯一方法是交换屏幕:
home: Consumer<Auth>(
builder: (_, auth, __) => auth.user == null ? LoginPage() : MainPage()
)
这是一种常见的方式。但它不会使用 Navigator,因此它只会“弹出”MainPage 而没有屏幕转换。
- 在某些情况下,我想在 UI 中播放一些动画。
我在文档中发现Listenable
该类旨在处理动画,但没有详细解释。
在某些情况下,我想清除 TextEditingController。
在某些情况下,我想显示一个对话框。
还有更多类似的任务……如何解决?提前致谢!
解决方案
经过一番研究,我找到了一种方法。我不确定这是否是唯一或最好的方式,或者 Provider 的创建者所预见的方式,但它确实有效。
这个想法是在我的 Store 类(我的意思是 Provider 提供的业务逻辑类)中保留一个助手 Stream,并在我的小部件中订阅它的更改。
所以在我的商店课程中,我有:
final _eventStream = StreamController.broadcast();
Stream get eventStream => _eventStream.stream;
void dispose() {
_eventStream.close();
super.dispose();
}
我在动作中向这个流添加事件:
void navigateToNextScreen() {
_eventStream.sink.add('nav');
}
void openDialog() {
_eventStream.sink.add('dialog');
}
在我的 UI 小部件中,我有:
@override
void afterFirstLayout(BuildContext context) {
context.read<Transactions>().eventStream.listen((event) {
if (event == 'nav') {
Navigator.push(
context,
MaterialPageRoute(
builder: (ctx) => SecondScreen(),
),
);
} else if (event == 'dialog') {
showDialog(
context: context,
builder: (context) => AlertDialog(content: Text("Meow")));
}
});
}
我在这里使用afterFirstLayout
了包中的生命周期方法after_layout
,它只是一个包装器WidgetsBinding.instance.addPostFrameCallback
07.07.20 UPD.:刚刚找到一个可以用于事件反应的包: https ://pub.dev/packages/event_bus
它基本上使用与引擎盖下的 StreamController 相同的方法。
推荐阅读
- javascript - 是的,当联系人为空时不会触发 useForm 验证错误
- swift - OpenStack Swift proxy-server.conf 已经有 [filter:authtoken] 部分
- javascript - POST 请求在客户端接收重定向
- firebase - 有没有办法知道 Firestore 实时查询正在返回初始数据获取与更新?
- python - 在字典中交换一个键和它的一个值
- java - 使用 gson 时的空 json 文件
- jquery - Bootstrap 5 菜单不切换主要内容
- python - 记录/打印语句在 Python Django 应用程序的子进程中不起作用
- c# - WPF Mediaelement 在重复快进的位置属性时冻结
- android - Ionic Capacitor 页面在某些 Android 设备上闪烁