我想知道是否有人知道何时处理InheritedWidget?
这个问题的原因是我正在做一些实验,并且正在使用InheritedWidget作为BLoC的提供者。 此BLoC在InheritedWidget级别初始化,并使用StreamController。
由于不建议关闭StreamController,因此我正在寻找解决方案。
下面是一段代码(用于实验的傻瓜代码)来说明问题:
///
/// ApplicationProvider
///
/// A provider of ApplicationBloc
///
class ApplicationProvider extends InheritedWidget {
//
// Initialization of the BLoC
//
final ApplicationBloc bloc = new ApplicationBloc();
ApplicationProvider({Key key, Widget child}) : super(key: key, child: child);
@override
bool updateShouldNotify(_) => true;
static ApplicationBloc of(BuildContext context, [bool redraw = true]) {
return redraw ? (context.inheritFromWidgetOfExactType(ApplicationProvider) as ApplicationProvider).bloc
: (context.ancestorWidgetOfExactType(ApplicationProvider) as ApplicationProvider).bloc;
}
}
//
// The BLoC
//
class ApplicationBloc {
int _counter;
StreamController<int> _counterController = new StreamController<int>.broadcast();
Sink get inCounter => _counterController;
Stream<int> get outCounter => _counterController.stream;
ApplicationBloc(){
_counter = 0;
}
void increment(){
_counter++;
inCounter.add(_counter);
}
int get counter => _counter;
//
// How could I call this method ???
//
void dispose(){
_counterController.close();
}
}
所以主要问题是“ 如何调用BLoC的dispose()方法”?
非常感谢您的帮助。
答案 0 :(得分:10)
InheritedWidget
的行为与其他Widget
相同。
它们的寿命很短:通常不超过一个build
通话。
如果您想存储更长的数据,InheritedWidget
不是您想要的。为此,您需要一个State
。
这也意味着最终,您可以将State
的dispose用于您的集团处置。
class BlocHolder extends StatefulWidget {
final Widget child;
BlocHolder({this.child});
@override
_BlocHolderState createState() => _BlocHolderState();
}
class _BlocHolderState extends State<BlocHolder> {
final _bloc = new MyBloc();
@override
Widget build(BuildContext context) {
return MyInherited(bloc: _bloc, child: widget.child,);
}
@override
void dispose() {
_bloc.dispose();
super.dispose();
}
}
class MyInherited extends InheritedWidget {
final MyBloc bloc;
MyInherited({this.bloc, Widget child}): super(child: child);
@override
bool updateShouldNotify(InheritedWidget oldWidget) {
return oldWidget != this;
}
}
class MyBloc {
void dispose() {
}
}
答案 1 :(得分:0)
继承的窗口小部件的行为非常类似于无状态窗口小部件,后者也没有dispose
方法。继承的窗口小部件会经常重建,并且存储在其中的所有值都会丢失(并且如果没有适当的updateShouldNotify
实现,依赖的窗口小部件树也将被频繁重建!)。
要解决此问题,您可以使用StatefulWidget
:
import 'dart:async';
import 'package:flutter/widgets.dart';
class ApplicationProvider extends StatefulWidget {
const ApplicationProvider({Key key, this.child}) : super(key: key);
final Widget child;
@override
State<StatefulWidget> createState() => _ApplicationProviderState();
}
class _ApplicationProviderState extends State<ApplicationProvider> {
final ApplicationBloc bloc = new ApplicationBloc();
@override
void dispose() {
bloc.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return _ApplicationProvider(
bloc: bloc,
child: widget.child,
);
}
}
class _ApplicationProvider extends InheritedWidget {
_ApplicationProvider({
Key key,
this.bloc,
Widget child,
}) : super(key: key, child: child);
final ApplicationBloc bloc;
@override
bool updateShouldNotify(_ApplicationProvider oldWidget) {
return bloc != oldWidget.bloc;
}
}
class ApplicationBloc {
ApplicationBloc of(BuildContext context) {
final _ApplicationProvider provider = context.inheritFromWidgetOfExactType(_ApplicationProvider);
return provider.bloc;
}
int _counter;
StreamController<int> _counterController = new StreamController<int>.broadcast();
Sink get inCounter => _counterController;
Stream<int> get outCounter => _counterController.stream;
ApplicationBloc() {
_counter = 0;
}
void increment() {
_counter++;
inCounter.add(_counter);
}
int get counter => _counter;
void dispose() {
_counterController.close();
}
}