I'm new to Flutter. I have encountered the following problem where I have no idea how to add another changenotifierprovider to my app.dart. Before that I already have the EntryProvider(), Now I wish to add another provider called EnterProvider(). Below is my coding for app.dart:
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => EntryProvider(),
child: MaterialApp(
home: WelcomeBackPage(),
theme: ThemeData(
accentColor: Colors.orangeAccent,
primaryColor: Colors.black,
textTheme: GoogleFonts.openSansTextTheme(),
),
debugShowCheckedModeBanner: false,),
);
}
}
Could anyone help me out on this?
You can try MultiProvider .
MultiProvider(
providers: [
Provider<Something>(create: (_) => Something()),
Provider<SomethingElse>(create: (_) => SomethingElse()),
Provider<AnotherThing>(create: (_) => AnotherThing()),
],
child: someWidget,
)
Related
Does inserting all providers in main affect performance? Is it a better option to put individual providers in the middle of the tree where they are needed?
When injecting many values in big applications, Provider can rapidly become pretty nested:
Provider<Something>(
create: (_) => Something(),
child: Provider<SomethingElse>(
create: (_) => SomethingElse(),
child: Provider<AnotherThing>(
create: (_) => AnotherThing(),
child: someWidget,
),
),
),
To:
MultiProvider(
providers: [
Provider<Something>(create: (_) => Something()),
Provider<SomethingElse>(create: (_) => SomethingElse()),
Provider<AnotherThing>(create: (_) => AnotherThing()),
],
child: someWidget,
)
**
The behavior of both examples is strictly the same. MultiProvider only changes the appearance of the code.
**
Try importing 'package:provider/provider.dart' as statemanagement; and use multi provider as statemanagement.MultiProvider(...), and use Provider as statemanagement.Provider(....) worked on my code
import 'package:flutter/material.dart';
import 'package:provider/provider.dart' as statemanagement;
import 'models/model_provider.dart';
import 'modules/screen_root.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return statemanagement.MultiProvider(
providers: [
statemanagement.Provider<ModelProvider>(
create: ((_) => ModelProvider())),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Multi Provider',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const ScreenRoot(),
),
);
}
}
Bloc is good because it works without context. Internalization requires context. You can try to pass it to the block, but in my case, the bloc is initialized before the internalization. MultiProvider before MaterialApp, how to change the sequence and use internalization inside bloc?
class MyApp extends StatelessWidget {
final routes = <String, WidgetBuilder>{
StartPage.routeName: (BuildContext context) => new StartPage(),
EditorPage.routeName: (BuildContext context) => new EditorPage(),
};
#override
Widget build(BuildContext context) {
//localization always == null
var localization = S.of(context);
return MultiProvider(
providers: [
ChangeNotifierProvider.value(
value: ChannelModel(),
),
BlocProvider<InternetBloc>(
create: (context) => InternetBloc(localizations: localization),
),
BlocProvider<MultiBloc>(
create: (context) => MultiBloc(),
),
BlocProvider<DbBloc>(
create: (context) => DbBloc(),
),
BlocProvider<FileBloc>(
create: (context) => FileBloc(),
),
],
child: MaterialApp(
localizationsDelegates: [
S.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: S.delegate.supportedLocales,
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: StartPage(),
routes: routes,
));
}
}
I use providers in my app, below code is working but doesnt look right :)
Looking for some help how reformat the code to only use child once..
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (_) => AppProvider(),
),
ChangeNotifierProvider(
create: (_) => ThemeProvider(true),
),
],
child: Consumer<AppProvider>(
builder: (ctx, providerApp, _) => Container(
child: Consumer<ThemeProvider>(
builder: (ctx, providerTheme, _) => MaterialApp(
debugShowCheckedModeBanner: false,
theme: providerTheme.getTheme(),
home: Splash(),
),
),
),
),
);
}
}
I have started using PROVIDER to manage state in my app. I followed tutorials and wrapped my Material app with ChangeNotifierProvider.
Here's the code :
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (BuildContext context) => ListsProvider(),
child: MaterialApp(
title: 'WordsApp',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: StartingPage.id,
routes: {
StartingPage.id: (context) => StartingPage(),
RegistrationScreen.id: (context) => RegistrationScreen(),
},
),
);
}
}
This provider called "ListsProvider" takes care of "providing" lists that need to be displayed on different screens.
I have now created a second provider which I called "user_data_provider" and I now need to add it to my app too. It will take care of providing user data to many different screens.
How can I do that ?
To achive this you can use Multiprovider as shown below
Add this to the top of your app. If you need these obj everywhere.
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<user_data_provider>(
create: (_) => user_data_provider(),
),
ChangeNotifierProvider<ListsProvider>(
create: (_) => ListsProvider(),
),
],
child: Builder(
builder: (BuildContext context) {
return MaterialApp(
//YOur code goes here
);
},
),
);
If I only want a widget and its children have specific Provider but not in whole app, how do I achieve that ?
// not this
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => CartModel()),
Provider(create: (context) => SomeOtherClass()),
],
child: MyApp(),
),
);
}
You just need to wrap MultiProvider to the Widget you want.
Like this:
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MultiProvider(
providers: [Provider(create: (context) => TestModel(index: 1)),],
child: MyHomePage(title: 'Flutter Demo Home Page')
),
);
}
}
You can wrap this widget with the provider and can be used as
final _myProvider=Provider.of<MyProvider>(context, listen: false);
or using
Consumer<MyProvider>(
builder: (BuildContext context, MyProvider myProvider, Widget child) {
return child;
),