What I did was with a button you can change the theme from light to dark, and I did it like this:
In a file called share_preferences I made my declaration of which variables I wanted to use:
class Preferences {
static late SharedPreferences _prefs;
static String _user = '';
static String _password = '';
static String _employeeName = '';
static String _department = '';
static String _employeeNumber = '';
static int _unlockPreference = 0;
static bool _isDarkmode = false;
static Future init() async {
_prefs = await SharedPreferences.getInstance();
}
static String get user {
return _prefs.getString('user') ?? _user;
}
static set user(String user) {
_user = user;
_prefs.setString('user', user);
}
// algunas otras propiedades....
static bool get isDarkmode {
return _prefs.getBool('isDarkmode') ?? _isDarkmode;
}
static set isDarkmode(bool value) {
_isDarkmode = value;
_prefs.setBool('isDarkmode', value);
}
}
Then send to call it in the following way with the button:
final darkNotifier = ValueNotifier < bool > (true); // Declaado despues del extends
bool isDark = darkNotifier.value; // Declarado despues del widget build , antes del scaffold
//.....
IconButton(
icon: toggle ?
const Icon(Icons.dark_mode): const Icon(
Icons.light_mode,
),
onPressed: () {
Preferences.isDarkmode = darkNotifier.value;
final themeProvider =
Provider.of < ThemeProvider > (context, listen: false);
setState(() {
isDark
?
themeProvider.setDarktMode() :
themeProvider.setLightMode();
toggle = !toggle;
isDark = !isDark;
darkNotifier.value = isDark;
});
}),
For my ThemeProvider, which is the one with the structure where the configuration of the theme and others are chosen, I did it like this:
import 'package:flutter/material.dart';
class ThemeProvider extends ChangeNotifier {
ThemeData currentTheme;
ThemeProvider({required bool isDarkmode})
: currentTheme = isDarkmode ? ThemeData.dark() : ThemeData.light();
setLightMode() {
currentTheme = ThemeData.light().copyWith(
appBarTheme: AppBarTheme(elevation: 3, color: Color(0xFF4F9A94)),
);
notifyListeners();
}
setDarktMode() {
currentTheme = ThemeData.dark();
notifyListeners();
}
}
Right there, declare that for the light theme, it would have a different color, which is teal with a gradient. And to declare it in the main and apply the changes to the ejidos I did it like this:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Preferences.init();
runApp(MultiProvider(
providers: [
ChangeNotifierProvider(
create: (_) => ThemeProvider(isDarkmode: Preferences.isDarkmode)),
],
child: const MyApp(),
));
}
class MyApp extends StatelessWidget {
const MyApp({
Key ? key
}): super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
initialRoute: 'login',
routes: {
//Rutas.....
},
theme: Provider.of < ThemeProvider > (context).currentTheme,
);
}
}
The inconvenience comes like this when starting,
when applying the theme with the button if you change it to black :
then I press the button again and it changes it to the defined color
In the application when I compile it, it comes out as the first image even though I defined a specific color, when I change the theme to dark mode it is applied, I restart my application and it keeps it the inconvenience is that if I define the light theme even though it has defined a specific color the appbar, it appears like this:
What happens is that what you save in the preference is only the flag if it is dark or not, but you are not saving the theme, so you have to change the value that you use when the theme is not dark, here:
You could do this:
You would also change here to reuse the value: