InheritFromWidgetOfExactType不适用于通用InheritedWidget

时间:2019-04-19 10:59:07

标签: flutter bloc

如果小部件是通用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包装bloc提供程序,这样每次重新构建widgets树时都不会重建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提供程序。

1 个答案:

答案 0 :(得分:0)

我的问题不是在BlocHolder中创建状态时指定通用类型。这行

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

应为:

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