Light / Dark Mode in flutter
When calling Provider.of
on a button, you should always pass listen: false
, like so:
onChanged: (value) {
Provider.of<ThemeState>(context, listen: false).theme =
value ? ThemeType.DARK : ThemeType.LIGHT;
setState(() {});
})
To be completely honest, I'm not sure if this will fix your code, however when I tried to replicate your error, I got the following error message:
════════ Exception caught by gesture ═══════════════════════════════════════════
Tried to listen to a value exposed with provider, from outside of the widget tree.
This is likely caused by an event handler (like a button's onPressed) that called
Provider.of without passing `listen: false`.
Here's my minimal example, which worked after adding listen: false
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(ChangeNotifierProvider<MyValue>(
create: (context) => MyValue(true),
child: MyApp(),
));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Checkbox(
value: Provider.of<MyValue>(context).value,
onChanged: (val) {
Provider.of<MyValue>(context, listen: false).value = val!;
setState(() {});
},
),
),
);
}
}
class MyValue extends ChangeNotifier {
MyValue(this.value);
bool value;
}
So I hope adding listen: false
will solve your problem
Berfin Gürz
Updated on January 01, 2023Comments
-
Berfin Gürz over 1 year
I want to put the light/dark mode switch inside the application. Switch is okay. But it isn't any changing in application. Just I see the light theme. And, when I clicked the switch, I get this error or warning (idk). : Another exception was thrown: Tried to listen to a value exposed with provider, from outside the widget tree.
This is the main.dart:
import 'package:provider/provider.dart'; import 'package:bankingapp/widget/themestate.dart'; void main() { runApp(ChangeNotifierProvider<ThemeState>( create: (context) => ThemeState(), child: MyApp(), )); } class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( theme: Provider.of<ThemeState>(context).theme == ThemeType.DARK ? ThemeData.dark() : ThemeData.light(), debugShowCheckedModeBanner: false, home: MySplash(), ); } }
This is the homescreen.dart:
Container( child: Switch( value: Provider.of<ThemeState>(context).theme == ThemeType.DARK, onChanged: (value) { Provider.of<ThemeState>(context).theme = value ? ThemeType.DARK : ThemeType.LIGHT; setState(() {}); }, ), ),
This is the themestate.dart:
import 'package:flutter/material.dart'; enum ThemeType { DARK, LIGHT } class ThemeState extends ChangeNotifier { bool _isDarkTheme = false; ThemeState() { getTheme().then((type) { _isDarkTheme = type == ThemeType.DARK; notifyListeners(); }); } ThemeType get theme => _isDarkTheme ? ThemeType.DARK : ThemeType.LIGHT; set theme(ThemeType type) => setTheme(type); void setTheme(ThemeType type) async { _isDarkTheme = type == ThemeType.DARK; notifyListeners(); } Future<ThemeType> getTheme() async { return _isDarkTheme ? ThemeType.DARK : ThemeType.LIGHT; } }
Note: This code snippet is the part of the project about ThemeS. Because code is consisted of very long line.
-
sh.seo over 2 years
-