0

似乎inheritFromWidgetOfExactType方法无法找到InheritedWidget小部件是否是泛型的子级StatefulWidget并且本身是泛型的。

我正在使用 InheritedWidget 来实现 bloc 模式。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 包装 bloc 提供程序,这样每次重建小部件树时都不会重建 bloc 状态。

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;
}

现在,当我尝试使用此模式inheritFromWidgetOfExactType返回null而不是 InheritedWidget 时:

@override
Widget build(BuildContext context) {
    return BlocHolder(
      createBloc: () => BlocTop(),
      child: BlocConsumer()
    );
  }

有什么办法可以克服这个问题?请注意,我希望能够使用这种方法嵌套 bloc 提供程序。

4

1 回答 1

2

我的问题是在 BlocHolder 中创建状态时没有指定泛型类型。这条线

@override
_BlocHolderState createState() => _BlocHolderState();

应该:

@override
_BlocHolderState<T> createState() => _BlocHolderState<T>();
于 2019-04-19T14:32:55.847 回答