I'm facing an annoying problem about the Provider package. I want to implement the night mode switch. I've tried to use the Provider in a separate screen and it works, but obv where I would need him, it doesn't :)
My theme class
class MyTheme {
static ThemeData lightTheme = ThemeData(
//something very nice
);
static ThemeData nightTheme = ThemeData(
//something very nice
);
}
My root page
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => ThemeProvider(),
builder: (context, child) {
final provider = Provider.of<ThemeProvider>(context);
return MaterialApp(
debugShowCheckedModeBanner: true,
initialRoute: LoginScreen.id,
onGenerateRoute: RouteGenerator.generateRoute,
theme: provider.themeData,
home: const HomeScreen(),
);
});
}
}
My homePage (where there is the button used for changing the mode)
class _HomeScreenState extends State<HomeScreen> {
final GlobalKey<ScaffoldState> _globalKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
double width = MediaQuery.of(context).size.width;
return Scaffold(
key: _globalKey,
drawer: MyAppDrawer(
height: height,
width: width,
colore: MyTheme.coloreTesto,
),
body:
The MyAppDrawer widget
class MyAppDrawer extends StatelessWidget {
const MyAppDrawer(
{super.key,
required this.height,
required this.width,
required this.colore});
final double height;
final double width;
final Color colore;
@override
Widget build(BuildContext context) {
final provider = Provider.of<ThemeProvider>(context);
return Drawer(
width: width * 0.7,
child: Container(
padding: EdgeInsets.only(
top: height * 0.1, left: width * 0.08, right: width * 0.08),
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: EdgeInsets.symmetric(vertical: height * 0.01),
child: Row(
children: [
Container(
child: ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.white),
elevation: MaterialStateProperty.all(0.0),
padding: MaterialStateProperty.all(EdgeInsets.zero),
shape:
MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(width * 0.015))))),
onPressed: () {
debugPrint('nightModePremuto');
provider.toggleTheme;
},
child: Icon(
size: width * 0.06,
Icons.dark_mode,
color: colore,
),
),
),
Text(
'Night Mode',
style: TextStyle(
color: colore,
fontSize: width * 0.04,
),
),
],
),
),
The Provider Class
class ThemeProvider extends ChangeNotifier {
ThemeData _themeData = MyTheme.lightTheme;
ThemeData get themeData => _themeData;
void toggleTheme() {
debugPrint('Siamo entrati nel toggle');
final isLight = _themeData == MyTheme.lightTheme;
isLight ? _themeData = MyTheme.nightTheme : _themeData = MyTheme.lightTheme;
notifyListeners();
}
}
I've tried the debugging mode and got that it doesn't even enter the toggleTheme() method (the one in the Provider class). I really don't know why.
The main issue seems to be in the MyAppDrawer widget
where you are referencing the method without actuall calling it provider.toggleTheme
instead it should be provider.toggleTheme();