ウィジェットがジェネリックの子であり、それ自体がジェネリックであるかどうかinheritFromWidgetOfExactType
をメソッドが見つけられないようです。InheritedWidget
StatefulWidget
ブロックパターンを実装するために InheritedWidget を使用しています。BlocProvider の初期実装は次のようになります。
class BlocProvider<T extends BlocBase> extends InheritedWidget {
final T bloc;
const BlocProvider({
Key key,
@required this.bloc,
@required Widget child,
})
: assert(bloc != null),
assert(child != null),
super(key: key, child: child);
static T of<T extends BlocBase>(BuildContext context) {
final type = _typeOf<BlocProvider<T>>();
final provider = context.inheritFromWidgetOfExactType(type) as BlocProvider<T>;
print("provider: $provider");
return provider.bloc;
}
static Type _typeOf<T>() => T;
@override
bool updateShouldNotify(BlocProvider old) => false;
}
直接使用すると問題なく動作します:
@override
Widget build(BuildContext context) {
return BlocProvider(
bloc: BlocTop(),
child: BlocConsumer()
);
}
しかし、ウィジェットツリーが再構築されるたびにブロックの状態が再構築されないように、ブロックプロバイダーを StatefulWidget でラップしたいと思います。
class BlocHolder<T extends BlocBase> extends StatefulWidget {
final Widget child;
final T Function() createBloc;
final bool wantKeepAlive;
BlocHolder({
@required this.child,
this.createBloc,
this.wantKeepAlive
});
@override
_BlocHolderState createState() => _BlocHolderState();
}
class _BlocHolderState<T extends BlocBase>
extends State<BlocHolder>
with AutomaticKeepAliveClientMixin<BlocHolder> {
T _bloc;
@override
void initState() {
super.initState();
_bloc = widget.createBloc();
}
@override
Widget build(BuildContext context) {
return BlocProvider(
child: widget.child,
bloc: _bloc,
);
}
@override
void dispose() {
_bloc?.dispose();
super.dispose();
}
@override
bool get wantKeepAlive => widget.wantKeepAlive ?? false;
}
ここで、 InheritedWidget の代わりにこのパターンを使用しようとすると、次のようにinheritFromWidgetOfExactType
返されます。null
@override
Widget build(BuildContext context) {
return BlocHolder(
createBloc: () => BlocTop(),
child: BlocConsumer()
);
}
この問題を克服する方法はありますか? このアプローチを使用してブロックプロバイダーをネストできるようにしたいことに注意してください。