You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter升级后BlocProvider出现类型赋值与返回值错误求助

问题修复方案

错误原因分析

Flutter升级后,空安全规范与InheritedWidget相关API的用法发生了变化,导致原有代码的类型转换、空值处理逻辑不符合新版本要求。

具体修复步骤

1. 重写of方法的实现

原代码中通过_typeOf获取泛型类型的方式已不再需要,直接使用dependOnInheritedWidgetOfExactTypeAPI即可获取对应实例,同时补充空值校验以满足返回类型要求:

static T of<T extends BlocBase>(BuildContext context) {
  final _BlocProviderInherited<T>? provider =
      context.dependOnInheritedWidgetOfExactType<_BlocProviderInherited<T>>();
  if (provider == null) {
    throw StateError('No BlocProvider<$T> found in current context');
  }
  return provider.bloc;
}

2. 移除无用的_typeOf方法

新版本Flutter支持直接在dependOnInheritedWidgetOfExactType中指定泛型参数,无需通过_typeOf间接获取类型,直接删除如下代码:

// 删掉此行代码
Type _typeOf<T>() => T;

3. 修正updateShouldNotify的参数类型

原方法中oldWidget未指定泛型,补全后避免类型警告:

@override
bool updateShouldNotify(_BlocProviderInherited<T> oldWidget) => false;

完整修复后代码

abstract class BlocBase {
  void dispose();
}

class BlocProvider<T extends BlocBase> extends StatefulWidget {
  BlocProvider({
    Key? key,
    required this.child,
    required this.bloc,
  }) : super(key: key);

  final Widget child;
  final T bloc;

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

  static T of<T extends BlocBase>(BuildContext context) {
    final _BlocProviderInherited<T>? provider =
        context.dependOnInheritedWidgetOfExactType<_BlocProviderInherited<T>>();
    if (provider == null) {
      throw StateError('No BlocProvider<$T> found in current context');
    }
    return provider.bloc;
  }
}

class _BlocProviderState<T extends BlocBase> extends State<BlocProvider<T>> {
  @override
  void dispose() {
    widget.bloc.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return _BlocProviderInherited<T>(
      bloc: widget.bloc,
      child: widget.child,
    );
  }
}

class _BlocProviderInherited<T> extends InheritedWidget {
  _BlocProviderInherited({
    Key? key,
    required Widget child,
    required this.bloc,
  }) : super(key: key, child: child);

  final T bloc;

  @override
  bool updateShouldNotify(_BlocProviderInherited<T> oldWidget) => false;
}

修复核心说明

  • 用dependOnInheritedWidgetOfExactType替代旧API,直接获取目标InheritedWidget实例,无需额外转换element.widget
  • 增加空值判断并抛出异常,确保方法返回值非空,符合返回类型T的要求
  • 补全泛型参数,消除类型不匹配的编译警告

内容的提问来源于stack exchange,提问作者Bisclavret

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 21:45:35