inheritFromWidgetOfExactType 不适用于通用 InheritedWidget

Posted

技术标签:

【中文标题】inheritFromWidgetOfExactType 不适用于通用 InheritedWidget【英文标题】:inheritFromWidgetOfExactType not working for generic InheritedWidget 【发布时间】:2019-09-09 15:54:12 【问题描述】:

如果小部件是泛型StatefulWidget 的子级并且本身是泛型,则inheritFromWidgetOfExactType 方法似乎找不到InheritedWidget

我正在使用 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()
    );
  

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

【问题讨论】:

你可能想让包处理这种东西,而不是重写你自己的。 provider 2.0-dev 版本的包正在成为处理这类东西的官方包 【参考方案1】:

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

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

应该是:

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

【讨论】:

以上是关于inheritFromWidgetOfExactType 不适用于通用 InheritedWidget的主要内容,如果未能解决你的问题,请参考以下文章