dart - Flutter:在 StatelessWidget 中哪里添加监听器?
问题描述
如果我使用的是 StatefulWidget,那么我将在 initState 方法中监听 Stream。我会在 StatelessWidget 中哪里做同样的事情(比如使用 Bloc 和流进行状态管理)?我可以在构建方法中做到这一点,但由于这些是重复的,我想知道是否有比检查现有侦听器更有效的方法,如下所示。我知道这是一个多余且无用的示例,但这只是为了说明问题。
import "package:rxdart/rxdart.dart";
import 'package:flutter/material.dart';
final counter = BehaviorSubject<int>();
final notifier = ValueNotifier<int>(0);
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
if (!counter.hasListener)
counter.listen((value) => notifier.value += value);
return MaterialApp(
home: Scaffold(
body: Center(
child:FlatButton(
onPressed: () => counter.add(1),
child: ValueListenableBuilder(
valueListenable: notifier,
builder: (context, value, child) => Text(
value.toString()
),
),
)
),
)
);
}
}
解决方案
没有一种干净的方法可以让 StatelessWidget 监听 Listenable/Stream。你总是需要一个 StatefulWidget。
另一方面,您可以使用组合来编写 StatefulWidget 一次,然后就可以完成它。
该模式的常见示例是小部件,例如ValueListenableBuilder
、StreamBuilder
或AnimatedBuilder
。但也可以做同样的事情,听。
你会这样使用它:
class Foo extends StatelessWidget {
Foo({Key key, this.counter}): super(key: key);
final ValueListenable<int> counter;
@override
Widget build(BuildContext context) {
return ValueListenableListener(
valueListenable: counter,
onChange: (value) {
// TODO: do something
},
child: Something(),
);
}
}
ValueListenableListener
以这种方式实现的地方:
class ValueListenableListener<T> extends StatefulWidget {
const ValueListenableListener(
{Key key, this.valueListenable, this.onChange, this.child})
: super(key: key);
final ValueListenable<T> valueListenable;
final ValueChanged<T> onChange;
final Widget child;
@override
_ValueListenableListenerState createState() =>
_ValueListenableListenerState();
}
class _ValueListenableListenerState extends State<ValueListenableListener> {
@override
void initState() {
super.initState();
widget.valueListenable?.addListener(_listener);
_listener();
}
@override
void didUpdateWidget(ValueListenableListener oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.valueListenable != widget.valueListenable) {
oldWidget.valueListenable?.removeListener(_listener);
widget.valueListenable?.addListener(_listener);
_listener();
}
}
@override
void dispose() {
widget.valueListenable?.removeListener(_listener);
super.dispose();
}
void _listener() {
widget.onChange?.call(widget.valueListenable.value);
}
@override
Widget build(BuildContext context) {
return widget.child;
}
}
推荐阅读
- python - 将字典与另一个字典合并
- sql - 使用 SQL 查询逐行打印单词的每个字符
- hyperledger-fabric - Hyperledger Fabric:背书策略 3 个中的两个对等方。错误
- swift - 当发布者的失败类型不相等时如何使用 CombineLates?
- node.js - 如何修复找不到浏览器修订版 756035
- reactjs - 在firebase上进行某些更改后如何重新部署应用程序
- python - 如何检查 Python 代码中的当前字符串和上一个字符串?
- javascript - 使用 JS 从 JSON 数据样本中获取 HTML 编码/解码问题
- python - 使用 Flask-Appbuilders ModelView 如何更改列和表的宽度?
- java - 一个 Scanner 应该只被实例化一次吗?如果是这样,为什么会这样?