由于上下文问题,无法从 child class 访问 bloc?

Cannot access bloc from a child class due to context issues?

当我尝试从 child class 访问 bloc 时,它给我一个错误

flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
flutter: The following assertion was thrown building Builder:
flutter:         BlocProvider.of() called with a context that does not contain a Bloc of type
flutter: TopRatedMovieBloc.
flutter:         No ancestor could be found starting from the context that was passed to
flutter: BlocProvider.of<TopRatedMovieBloc>().
flutter:
flutter:         This can happen if:
flutter:         1. The context you used comes from a widget above the BlocProvider.
flutter:         2. You used MultiBlocProvider and didn't explicity provide the BlocProvider types.
flutter:
flutter:         Good: BlocProvider<TopRatedMovieBloc>(builder: (context) => TopRatedMovieBloc())
flutter:         Bad: BlocProvider(builder: (context) => TopRatedMovieBloc()).

我的代码如下所示:

**main.dart**

void main() {
  final MovieRepository movieRepository = MovieRepository(
    movieApiClient: MovieApiClient(
      httpClient: http.Client(),
    ),
  );
  BlocSupervisor.delegate = SimpleBlocDelegate();
  runApp(App(movieRepository: movieRepository),
    );
  }

class App extends StatelessWidget {
  final MovieRepository movieRepository;
  App({Key key, @required this.movieRepository})
      : assert(movieRepository != null),
        super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Infinite Scroll',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
          primarySwatch: Colors.blue, canvasColor: Colors.transparent),
home: MyHomePage(),
    );
  }
}
class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  final MovieRepository movieRepository = MovieRepository(
    movieApiClient: MovieApiClient(
      httpClient: http.Client(),
    ),
  );

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<ChangeThemeBloc, ChangeThemeState>(
      builder: (context, state) {
        return Scaffold(body: Container(
            color: state.themeData.primaryColor,
            child: ListView(
              physics: BouncingScrollPhysics(),
              children: <Widget>[
                DiscoverMovies(
                  themeData: state.themeData,
                ),
                BlocProvider(
                  builder: (BuildContext context) =>
                      TopRatedMovieBloc(movieRepository: movieRepository),
                  child: ScrollingMovies(
                    themeData: state.themeData,
                    title: 'Top Rated',
                    api: Api.toprated,
                  ),
                ),
],
            ),
          ),
        );
      },
    );
  }
}



class ScrollingMovies extends StatefulWidget {
  final ThemeData themeData;
  final String title;
  final Api api;
  ScrollingMovies({
    this.themeData,
    this.api,
    this.title,
  });
  @override
  _ScrollingMoviesState createState() => _ScrollingMoviesState();
}

class _ScrollingMoviesState extends State<ScrollingMovies> {
  @override
  void initState() {
    super.initState();
    TopRatedMovieBloc _topRatedMovieBloc =
        BlocProvider.of<TopRatedMovieBloc>(context);
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[])
  }

这行给我错误:

TopRatedMovieBloc _topRatedMovieBloc = BlocProvider.of<TopRatedMovieBloc>(context);

谁能帮我理解这个问题?

您无法在 initState 中访问 context。 您在这里有一些选择:
1. 将 bloc 用法移动到 build 方法中。
2. 覆盖 didChangeDependencies 并在那里使用它。第一次在 initState 之后立即调用,但 context 可用。如果依赖关系发生变化,它可能会被调用多次,所以如果你只想做一次 - 检查你之前是否没有做过。
3. 通过构造函数传递 bloc

原始错误消息中描述了另一个问题:

flutter:         Good: BlocProvider<TopRatedMovieBloc>(builder: (context) => TopRatedMovieBloc())
flutter:         Bad: BlocProvider(builder: (context) => TopRatedMovieBloc()).

您需要通过向 BlocProvider 添加类型参数来更新 _MyHomePageState build 方法中的代码,因此它应该类似于

BlocProvider<TopRatedMovieBloc>(
                  builder: (BuildContext context) =>
                      TopRatedMovieBloc(movieRepository: movieRepository),
                  child: ScrollingMovies(
                    themeData: state.themeData,
                    title: 'Top Rated',
                    api: Api.toprated,
                  ),
                ),