NielsK
NielsK

Reputation: 1

Light and dark theme Flutter

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

Answers (1)

immadisairaj
immadisairaj

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?

  1. Comment out all color properties
  2. commented out shared prefs (you don't need to)
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;
  }
}

Working Demo: Working demo of above code

Upvotes: 2

Related Questions