Reputation: 1
Hey guys I'm fairly new to Flutter and I'm trying to add a function that can switch the theme in my app from light to dark and visa versa, but I can't seem to get it right. I followed a tutorial from Aditya Thakur: https://www.youtube.com/watch?v=roCaIr2X5og. He works with the demo-code, I think that's where my problem comes in. Hope you can help!
This is my code:
main.dart
import 'package:flutter/material.dart';
import 'package:bachelorproef/pages/Home.dart';
import 'package:bachelorproef/pages/Loading.dart';
import 'package:bachelorproef/pages/Categorie.dart';
import 'package:bachelorproef/pages/Verwijderde_Items.dart';
import 'package:bachelorproef/pages/Email.dart';
import 'package:bachelorproef/pages/Kabels.dart';
import 'package:bachelorproef/pages/Bestanden_Openen.dart';
import 'package:provider/provider.dart';
import 'package:bachelorproef/theme_model.dart';
void main() => runApp(MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => Home(), //Loading() verwijst naar loadingpage
//'/Home': (context) => Home(),
'/Categorie': (context) => Categorie(),
'/Verwijderde_Items': (context) => Verwijderde_Items(),
'/Email': (context) => Email(),
'/Kabels': (context) => Kabels(),
'/Bestanden_Openen': (context) => Bestanden_Openen(),
},
//https://www.youtube.com/watch?v=roCaIr2X5og tutorial
));
void theme() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (_) => ThemeModel(),
child: Consumer(
builder:(context, ThemeModel themeNotifier, child){
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: themeNotifier.isDark ? ThemeData.dark() : ThemeData.light(),
home: Home(),
);
}
),
);
}
}
Home.dart
import 'package:bachelorproef/theme_model.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:bachelorproef/main.dart';
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
@override
Widget build(BuildContext context) {
return Consumer( builder: (context, ThemeModel themeNotifier, child) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.blue[300],
title: Text('EHBC - Eerste Hulp Bij Computers',
style: TextStyle(
color: Colors.black,
)),
centerTitle: true,
actions: [
IconButton(
onPressed: () {
themeNotifier.isDark
? themeNotifier.isDark = false
: themeNotifier.isDark = true;
},
icon: Icon(themeNotifier.isDark
? Icons.nightlight_round
: Icons.wb_sunny
)
)
],
),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: ListView( //was eerst Column
children: <Widget>[
FlatButton.icon(
onPressed: () {},
icon: Icon(
Icons.visibility_outlined,
color: Colors.grey[600],
),
label: Text(
'Lichte modus',
style: TextStyle(
color: Colors.black,
),
),
),
Card(
color: Colors.blue[300],
child: ListTile(
onTap: () {
Navigator.pushNamed(context, '/Verwijderde_Items');
},
title: Text('Verwijderde items'),
leading: CircleAvatar(
backgroundImage: AssetImage('assets/prullenbak.png'),
),
),
),
Card(
color: Colors.grey[350],
child: ListTile(
onTap: () {
Navigator.pushNamed(context, '/Email');
},
title: Text('E-mail problemen'),
leading: CircleAvatar(
backgroundImage: AssetImage('assets/email.jpg'),
),
),
),
Card(
color: Colors.grey[350],
child: ListTile(
onTap: () {
Navigator.pushNamed(context, '/Kabels');
},
title: Text('Kabels'),
leading: CircleAvatar(
backgroundImage: AssetImage('assets/kabels.jpg'),
),
),
),
Card(
color: Colors.grey[350],
child: ListTile(
onTap: () {
Navigator.pushNamed(context, '/Bestanden_Openen');
},
title: Text('Bestanden willen niet openen'),
leading: CircleAvatar(
backgroundImage: AssetImage('assets/folder.png'),
),
),
),
],
),
),
));
});
}
}
theme_model.dart
import 'package:flutter/cupertino.dart';
import 'package:bachelorproef/theme_preferences.dart';
class ThemeModel extends ChangeNotifier {
bool _isDark = false;
ThemePreferences _preferences = ThemePreferences ();
bool get isDark => _isDark;
ThemeModel() {
_isDark = false;
_preferences = ThemePreferences();
getPreferences();
}
getPreferences() async {
_isDark = await _preferences.getTheme();
notifyListeners();
}
set isDark(bool value) {
_isDark = value;
_preferences.setTheme(value);
notifyListeners();
}
}
theme_preferences.dart
import 'package:flutter/cupertino.dart';
import 'package:shared_preferences/shared_preferences.dart';
class ThemePreferences {
static const PREF_KEY = 'pref_key';
setTheme(bool value) async{
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
sharedPreferences.setBool(PREF_KEY, value);
}
getTheme() async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
return sharedPreferences.getBool(PREF_KEY) ?? false;
}
}
Upvotes: 0
Views: 3194
Reputation: 656
I had tried your code and understood why the colors doesn't change.
Let's consider a scenario. You have a Scaffold
and want its background color to change with theme. What are the things you do?
// first.dart
themeData: isDarkTheme ? ThemeData.dark() : ThemeData.light(),
...
Scaffold(
// don't put any background color
);
// second.dart
themeData: isDarkTheme ? ThemeData.dark() : ThemeData.light(),
...
Scaffold(
backgroundColor: isDarkTheme ? Colors.grey : Colors.white,
);
// third
themeData: isDarkTheme ? ThemeData.dark() : ThemeData.light(),
...
Scaffold(
backgroundColor: Colors.white, // this doesn't work
);
Consider the above three types. the first and second works. But, the third doesn't work. It is because the backgroundColor
is overriden to white always.
In your code also, you have a lot's of things similar to these which are overriding the color
given by ThemeData
or you are not handling the colors properly according to the theme.
So, your Answer is:
Change all the widget color properties either to default or handle it with your own colors using a variable (which you get from provider) -> themeNotifier.isDark
in your case
Bonus:
Below is something which I tried in dartpad (without shared prefs)
What I did?
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (_) => ThemeModel(),
child: Consumer(
builder:(context, ThemeModel themeNotifier, child){
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: themeNotifier.isDark ? ThemeData.dark() : ThemeData.light(),
home: Home(),
);
}
),
);
}
}
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
@override
Widget build(BuildContext context) {
return Consumer( builder: (context, ThemeModel themeNotifier, child) {
return Scaffold(
// backgroundColor: Colors.white,
appBar: AppBar(
// backgroundColor: Colors.blue[300],
title: Text('EHBC - Eerste Hulp Bij Computers',
style: TextStyle(
// color: Colors.black,
)),
centerTitle: true,
actions: [
IconButton(
onPressed: () {
themeNotifier.isDark
? themeNotifier.isDark = false
: themeNotifier.isDark = true;
},
icon: Icon(themeNotifier.isDark
? Icons.nightlight_round
: Icons.wb_sunny
)
)
],
),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: ListView( //was eerst Column
children: <Widget>[
FlatButton.icon(
onPressed: () {},
icon: Icon(
Icons.visibility_outlined,
// color: Colors.grey[600],
),
label: Text(
'Lichte modus',
style: TextStyle(
// color: Colors.black,
),
),
),
Card(
// color: Colors.blue[300],
child: ListTile(
onTap: () {
Navigator.pushNamed(context, '/Verwijderde_Items');
},
title: Text('Verwijderde items'),
leading: CircleAvatar(
backgroundImage: AssetImage('assets/prullenbak.png'),
),
),
),
Card(
// color: Colors.grey[350],
child: ListTile(
onTap: () {
Navigator.pushNamed(context, '/Email');
},
title: Text('E-mail problemen'),
leading: CircleAvatar(
backgroundImage: AssetImage('assets/email.jpg'),
),
),
),
Card(
// color: Colors.grey[350],
child: ListTile(
onTap: () {
Navigator.pushNamed(context, '/Kabels');
},
title: Text('Kabels'),
leading: CircleAvatar(
backgroundImage: AssetImage('assets/kabels.jpg'),
),
),
),
Card(
// color: Colors.grey[350],
child: ListTile(
onTap: () {
Navigator.pushNamed(context, '/Bestanden_Openen');
},
title: Text('Bestanden willen niet openen'),
leading: CircleAvatar(
backgroundImage: AssetImage('assets/folder.png'),
),
),
),
],
),
),
));
});
}
}
class ThemeModel extends ChangeNotifier {
bool _isDark = false;
ThemePreferences _preferences = ThemePreferences ();
bool get isDark => _isDark;
ThemeModel() {
_isDark = false;
_preferences = ThemePreferences();
getPreferences();
}
getPreferences() async {
_isDark = await _preferences.getTheme();
notifyListeners();
}
set isDark(bool value) {
_isDark = value;
_preferences.setTheme(value);
notifyListeners();
}
}
class ThemePreferences {
bool darkTheme = false;
// static const PREF_KEY = 'pref_key';
setTheme(bool value) {
darkTheme = value;
// SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
// sharedPreferences.setBool(PREF_KEY, value);
}
getTheme() {
return darkTheme;
// SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
// return sharedPreferences.getBool(PREF_KEY) ?? false;
}
}
Upvotes: 2