I have a project I'm working on and I want to switch it to the three modes, light, dark, and according to the system.
I want an add-on code to do this in addition to saving the mode to be selected, away from any state management, I have put a simple code with three buttons for each case.
Material app
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(scaffoldBackgroundColor: Colors.white),
darkTheme: ThemeData(scaffoldBackgroundColor: Colors.black),
themeMode: ThemeMode.system,
home: const HomePage(),
);
}
}
HomePage
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(onPressed: (){}, child: const Text('Dark mode')),
ElevatedButton(onPressed: (){}, child: const Text('Light mode')),
ElevatedButton(onPressed: (){}, child: const Text('System mode')),
],
)
);
}
}
CodePudding user response:
here is the code to do it
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
ThemeMode mode = ThemeMode.dark;
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(scaffoldBackgroundColor: Colors.white),
darkTheme: ThemeData(scaffoldBackgroundColor: Colors.black),
themeMode: mode,
home: Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
setState(() {
mode = ThemeMode.dark;
});
},
child: const Text('Dark mode')),
ElevatedButton(
onPressed: () {
setState(() {
mode = ThemeMode.light;
});
},
child: const Text('Light mode'),
),
ElevatedButton(
onPressed: () {
setState(() {
mode = ThemeMode.system;
});
},
child: const Text('System mode'),
),
],
),
),
);
}
}
Edit: if you don't want to merge these classes you can use it separate as well like this
Material App
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
ThemeMode mode = ThemeMode.dark;
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(scaffoldBackgroundColor: Colors.white),
darkTheme: ThemeData(scaffoldBackgroundColor: Colors.black),
themeMode: mode,
home: HomePage(
changeThemeToDark: () {
setState(() {
mode = ThemeMode.dark;
});
},
changeThemeToLight: () {
setState(() {
mode = ThemeMode.light;
});
print("changes=d");
},
changeThemeToSystem: () {
mode = ThemeMode.system;
},
),
);
}
}
HomePage
class HomePage extends StatelessWidget {
const HomePage(
{Key? key,
required this.changeThemeToDark,
required this.changeThemeToSystem,
required this.changeThemeToLight})
: super(key: key);
final VoidCallback changeThemeToDark;
final VoidCallback changeThemeToSystem;
final VoidCallback changeThemeToLight;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
changeThemeToDark();
},
child: const Text('Dark mode')),
ElevatedButton(
onPressed: () {
changeThemeToLight();
},
child: const Text('Light mode')),
ElevatedButton(
onPressed: () {
changeThemeToSystem();
},
child: const Text('System mode')),
],
));
}
}
CodePudding user response:
Here's an example of how you an add functionality to your existing code to switch between the three modes and save the selected mode:
- Create a new file called theme_manager.dart and add the following code:
import 'package:shared_preferences/shared_preferences.dart';
class ThemeManager {
static const _themeModeKey = 'themeMode';
static const _lightModeValue = 'light';
static const _darkModeValue = 'dark';
static const _systemModeValue = 'system';
static Future<ThemeMode> getSavedThemeMode() async {
final prefs = await SharedPreferences.getInstance();
final themeModeString = prefs.getString(_themeModeKey);
if (themeModeString == _lightModeValue) {
return ThemeMode.light;
} else if (themeModeString == _darkModeValue) {
return ThemeMode.dark;
} else {
return ThemeMode.system;
}
}
static Future<void> saveThemeMode(ThemeMode themeMode) async {
final prefs = await SharedPreferences.getInstance();
if (themeMode == ThemeMode.light) {
prefs.setString(_themeModeKey, _lightModeValue);
} else if (themeMode == ThemeMode.dark) {
prefs.setString(_themeModeKey, _darkModeValue);
} else {
prefs.setString(_themeModeKey, _systemModeValue);
}
}
}
- In your MyApp widget, change the themeMode property to use the getSavedThemeMode() method:
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(scaffoldBackgroundColor: Colors.white),
darkTheme: ThemeData(scaffoldBackgroundColor: Colors.black),
themeMode: ThemeManager.getSavedThemeMode(),
home: const HomePage(),
);
}
}
- In your HomePage widget, add the following code to handle the button presses and call the saveThemeMode() method:
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
ThemeManager.saveThemeMode(ThemeMode.dark);
setState(() {});
},
child: const Text('Dark mode')
),
ElevatedButton(
onPressed: () {
ThemeManager.saveThemeMode(ThemeMode.light);
setState(() {});
},
child: const Text('Light mode')
),
ElevatedButton(
onPressed: () {
ThemeManager.saveThemeMode(ThemeMode.system);
},
child: const Text('Light mode')
)