I have searched far and wide, i have studied the provider package but i still can't figure out why the children of the Material app dont have access to it's provider.
I have created a class to pass retreive the user preferences and create a ThemeData object. Then i create the MaterialApp using a ChangeNotifierProvider and the children don't have access to the ThemeViewModel class.
main.dart
void main() {
runApp(MyApp());
}
class MainBuilder extends StatelessWidget {
const MainBuilder({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<ThemeViewModel>(
create: (_) {
return ThemeViewModel();
},
child: Consumer<ThemeViewModel>(
builder: (context, ThemeViewModel themeNotifier, child) {
themeViewModel = themeNotifier.;
return MaterialApp(
title: StringConstants.appTitle,
theme: themeNotifier.themeData,
home: Login(user: UserModel(username: 'user', password: 'mona')),
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const [
Locale('en', ''),
Locale('it', ''),
],
localeListResolutionCallback: (locales, supportedLocales) {
for (Locale locale in locales!) {
for (Locale local in supportedLocales) {
if (locale.languageCode == local.languageCode) return locale;
}
}
return const Locale('en', '');
},
);
},
),
);
}
}
Login class
class Login extends StatefulWidget {
final UserModel user;
const Login({ required this.user, Key? key}) : super(key: key);
@override
State<Login> createState() => _LoginState();
}
class _LoginState extends State<Login> with SingleTickerProviderStateMixin {
final _formKey = GlobalKey<FormState>();
late TextEditingController _userNameController;
late TextEditingController _passwordController;
late Animation<Offset> _animation;
late Tween<Offset> _tween;
late AnimationController _animationController;
@override
void initState() {
super.initState();
_animationController = AnimationController(vsync: this, duration: const Duration(milliseconds: 1200))..repeat(reverse: true);
_tween = Tween(begin: Offset.zero, end: Offset(0, 0.08));
_animation = _tween.animate(CurvedAnimation(parent: _animationController, curve: Curves.easeInOut))..addListener(() {setState(() {});});
}
@override
void dispose() {
_userNameController.dispose();
_passwordController.dispose();
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
margin: const EdgeInsets.all(10),
child: SingleChildScrollView (
child: Column(
children: [
_animationWidget(),
_loginForm(),
Consumer<ThemeViewModel>(
builder: (context, ThemeViewModel theme, child) {
return Text(theme.themeData.toString());
},
)
],
),
),
),
);
}
}
If you need anything else ill gladly provide it because i banged my head long enough on this problem.
CodePudding user response:
I had the same issue yesterday and I solved modifying my main this way:
void main() => runApp(ChangeNotifierProvider(
create: (BuildContext context) => YourProvider(),
child: MyApp()));
CodePudding user response:
Use the MultiProvider
in main.dart
to make the scope of the provider for the entire app. It will solve your problem.
main.dart
:
void main() {
runApp(MyApp());
}
class MainBuilder extends StatelessWidget {
const MainBuilder({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<ThemeViewModel>(create: (_) => ThemeViewModel()),
],
child:
Consumer<ThemeViewModel>(
builder: (context, themeNotifier, child) {
themeViewModel = themeNotifier.;
return MaterialApp(
title: StringConstants.appTitle,
theme: themeNotifier.themeData,
home: Login(user: UserModel(username: 'user', password: 'mona')),
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const [
Locale('en', ''),
Locale('it', ''),
],
localeListResolutionCallback: (locales, supportedLocales) {
for (Locale locale in locales!) {
for (Locale local in supportedLocales) {
if (locale.languageCode == local.languageCode) return locale;
}
}
return const Locale('en', '');
},
);
},
),
);
}
}