简体   繁体   中英

Two providers in one Widget - Flutter

I have this problem. In my App I'm using the Provider package to manage the login State. In the MaterialApp I also want to manage some sort of the user configuration, in this case the Theme selection.

If I try to use two times Provider.of<LoginService>(context) I'm receiving this error:

 Could not find the correct Provider<LoginService> above this MyApp Widget

This likely happens because you used a `BuildContext` that does not include the provider
of your choice.

How can I use in Provider more of one time the Provider.of... or even two different Providers in a Widget (to, for instance, separate my LoginService and my UserconfigService )?

Thank you!

Actual code:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<LoginService>(
        create: (context) => LoginService(),
        child:  MaterialApp(
          title: 'My App',
          debugShowCheckedModeBanner: false,
          theme: ThemeData.dark(),
          routes: {
            '/': (BuildContext context) {
              var state = Provider.of<LoginService>(context);
              if (state.isLoggedIn()) {
                return HomeScreen();
              } else {
                return LoginScreen();
              }
            },
            MentorScreen.id: (BuildContext context) => MentorScreen(),
          },
        )
    );

  }

My objective:

child:  MaterialApp(
          title: 'MyApp',
          debugShowCheckedModeBanner: false,
          theme: state.isDarkThemeEnabled() == true ? ThemeData.dark() : ThemeData.light(),
          ...

You can use MultiProvider instead of ChangeNotifierProvider. Read more in here .

This type of Error comes when you use the context just after creating the ChangeNotifierProvider class.

Similarly, if you use the context of the Scaffold to showDialog gives a similar error. Here is the answer that explains why this happens

For this Wrap, your MaterialApp Widget inside Builder Class which will wait for the class to build first then call the Provider.of<T>(context) method.

Builder(
  builder: (context) {
    return MaterialApp(
      title: 'My App',
      debugShowCheckedModeBanner: false,
      theme: ThemeData.dark(),
      routes: {
        '/': (BuildContext context) {
          var state = Provider.of<LoginService>(context);
          if (state.isLoggedIn()) {
            return HomeScreen();
          } else {
            return LoginScreen();
          }
        },
        MentorScreen.id: (BuildContext context) => MentorScreen(),
      },
    );
  },
),

and for Two Providers in the same widget.

Use MultiProvider .

here's code from one of my app.

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
  return Provider(
    create: (_) => locator<FAuthService>(),
    builder: (context, _) {
      return MultiProvider(
        child: MaterialApp(
          onGenerateRoute: Router.onGenerateRoute,
          initialRoute: initialRoute,
          navigatorKey: locator<NavigationService>().globalKey,
          debugShowCheckedModeBanner: false,
          title: 'Demo',
          theme: ThemeData(
            primaryColor: Colors.black,
           ),
        ),
        providers: [
          ChangeNotifierProvider<HomeVM>(
            create: (_) => locator<HomeVM>(),
          ),
          ChangeNotifierProvider<LoginVM>(
            create: (context) => locator<LoginVM>(),
          ),
        ],
      );
    });
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM