Search code examples
flutterflutter-layoutflutter-dependenciesflutter-sliver

BlocProvider not available within inherited widget


Facing an issue with BlocProviders.

As I understand, a bloc should be accessible anywhere within the scope of inherited widgets.

I have an App class, which happens to be my core class, where I build my material App

 Widget build(BuildContext context) {
  return MaterialApp(
    debugShowCheckedModeBanner: false,
    title: 'E-Form',
    color: Color(0xFF44697D),
    home: BlocProvider(child: LaunchScreen()),
  );
}

Now I have the LaunchScreen class, here I am not using my BlocProvider, but I have wrapped LaunchScreen altogether in my App class with BlocProvider

class  LaunchScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final bloc = BlocProvider.of(context);
    return Scaffold(
      appBar: AppBar(
        title: Text('First Screen'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('Launch screen'),
          onPressed: () {
            // Navigate to second screen when tapped!
            Navigator.of(context).push(
              MaterialPageRoute(builder: (context) => Home()),
            );
          },
        ),
      ),
    );
  }
}

Now again in my third class, that is Home() class. I am trying to use my BlocProvider. Here I get an error saying the bloc is null

class Home extends StatelessWidget {
  Widget build(context) {
    final bloc = BlocProvider.of(context);
    return  Scaffold(
      appBar: AppBar(
        title: Text('Reduced Course Load'),
        backgroundColor: Color(0xFF44697D),
      ),
      body: CustomWidget(),
    );
  }
}

I am unable to figure out why this is null. The bloc is initialized perfectly if I initialize and print the bloc in LaunchScreen class. Does BlocProvider work only within a single class scope?

There's another error, I think my Navigator isn't working properly. For some reason, my Home() class constructor is getting recalled again. I am unable to fix the error in Navigator. An example would be great for me to understand a navigator.

Here is my flutter doctor results

$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, v0.8.2, on Mac OS X 10.13.6 17G65, locale en-US)
[✓] Android toolchain - develop for Android devices (Android SDK 28.0.0)
[✓] iOS toolchain - develop for iOS devices (Xcode 9.4.1)
[✓] Android Studio (version 3.2)
[✓] VS Code (version 1.27.2)
[✓] Connected devices (1 available)

Please take a look, and share a solution. Thank you!


Solution

  • You should use your BlocProvider() above the MaterialApp widget.

    Navigator is a widget added by MaterialApp and when you call it to change a route it replaces the widget in home: property and hence replaces your BlocProvider.

     Widget build(BuildContext context) {
      return BlocProvider(
        child: MaterialApp(
          debugShowCheckedModeBanner: false,
          title: 'E-Form',
          color: Color(0xFF44697D),
          home: LaunchScreen(),
        ),
      );
     }