我创建了一个自定义窗口小部件,每当通知程序触发时,它都会侦听ChangeNotifier
并调用提供的回调。当通知程序更改时,它用于执行一次性任务,例如导航。
一切似乎都工作正常,但偶然地,我偶然发现documentation of didUpdateWidget
指出:
如果状态的构建方法依赖于本身可以更改状态的对象,例如ChangeNotifier或Stream,或可以订阅以接收通知的其他对象,那么请确保在initState,didUpdateWidget中正确地订阅和取消订阅,并处理:
- 在initState中,订阅该对象。
- 在didUpdateWidget中,退订旧对象,如果更新的窗口小部件配置需要替换该对象,则订阅新对象。
- 处置时,取消订阅该对象。
出于明显的原因,我正在处理第一点和最后一点,但是有人可以阐明为什么我也必须实现didUpdateWidget
吗?如果我不这样做怎么办?
奖金问题:我尚未在应用程序中使用提供程序。它是否已提供开箱即用的类似功能?我找不到这样的东西。
我的小部件代码:
didUpdateWidget
class ChangeNotifierListener<T extends ChangeNotifier> extends StatefulWidget {
final Widget child;
final T changeNotifier;
final void Function(T changeNotifier) onChanged;
ChangeNotifierListener(
{@required this.child,
@required this.changeNotifier,
@required this.onChanged});
@override
_ChangeNotifierListenerState createState() =>
_ChangeNotifierListenerState<T>();
}
class _ChangeNotifierListenerState<T extends ChangeNotifier>
extends State<ChangeNotifierListener<T>> {
VoidCallback _callback;
@override
Widget build(BuildContext context) => widget.child;
@override
void initState() {
super.initState();
_callback = () {
widget.onChanged(widget.changeNotifier);
};
widget.changeNotifier.addListener(_callback);
}
@override
void dispose() {
widget.changeNotifier.removeListener(_callback);
super.dispose();
}
}
,第一个构建可能类似于:StreamBuilder
然后发生一些变化,并使用以下命令重建StreamBuilder(
stream: Stream.value(42),
builder: ...
)
:
StreamBuilder
在这种情况下,StreamBuilder(
stream: Stream.value(21),
builder: ...
)
已更改。因此,stream
需要停止收听前一个StreamBuilder
并收听新的Stream
。
这将通过以下didUpdateWidget
完成:
StreamSubscription<T> subscription; @override void didUpdateWidget(StreamBuilder<T> oldWidget) { super.didUpdateWidget(oldWidget); if (widget.stream != oldWidget.stream) { subscription?.cancel(); subscription = widget.stream?.listen(...); } }
相同的逻辑适用于ChangeNotifier
和任何其他可观察对象。