Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to implement dark mode in flutter

I want to create a flutter app that has 2 light and dark mode themes that change by a switch in-app and the default theme is default android theme.
I need to pass some custom color to the fellow widget and I don't want to just config material theme.

  • how to detect the user device default theme?
  • the secend question is how to provide a theme to the whole app?
  • third is how change the theme with a simple switch in running time?
like image 221
javad bat Avatar asked Feb 14 '20 18:02

javad bat


People also ask

How do you implement Dark mode in apps?

Use the system setting (Settings -> Display -> Theme) to enable Dark theme. Use the Quick Settings tile to switch themes from the notification tray (once enabled). On Pixel devices, selecting the Battery Saver mode enables Dark theme at the same time.

How do I change my theme on flutter?

In Flutter, we can change the theme throughout the app with the help of ThemeData in MaterialApp constructor. The default theme will be shared throughout the app when no theme is provided. ); ThemeData is used to configure the appearance of the entire app.

How do you change the theme color on flutter?

Steps to change theme text color in Flutter You can change theme text color in Flutter, by defining the TextTheme (inside MaterialApp) and then adding headings type. For example, headline1 , headline2 , BodyText1 , and so on. After that, you can assign the TextStyle widget with the color of your choice.

How do you change dark mode to light mode in flutter?

Run the flutter packages get in the terminal inside your project and install the package. Now we will add a Switch Widget in the UI to switch between the Themes. Now we need to add a Listener to listen to the changes and update the theme. We have to go to our Top most widget and update the code like this.


2 Answers

The easiest way in my opinion is by using provider to manage the state of your app and shared_preferences to save your theme preference on file system. By following this procedure you can save your theme so the user doesn't have to switch theme every time.

Output enter image description here

You can easily store your theme preference in form of a string and then at the start of your app check if there is value stored on file system, if so apply that theme as shown below.

StorageManager.dart

import 'package:shared_preferences/shared_preferences.dart';  class StorageManager {   static void saveData(String key, dynamic value) async {     final prefs = await SharedPreferences.getInstance();     if (value is int) {       prefs.setInt(key, value);     } else if (value is String) {       prefs.setString(key, value);     } else if (value is bool) {       prefs.setBool(key, value);     } else {       print("Invalid Type");     }   }    static Future<dynamic> readData(String key) async {     final prefs = await SharedPreferences.getInstance();     dynamic obj = prefs.get(key);     return obj;   }    static Future<bool> deleteData(String key) async {     final prefs = await SharedPreferences.getInstance();     return prefs.remove(key);   } } 

Define your theme properties in a theme variable like below and initialize your _themedata variable on the basis of value inside storage.

ThemeManager.dart

import 'package:flutter/material.dart'; import '../services/storage_manager.dart';  class ThemeNotifier with ChangeNotifier {   final darkTheme = ThemeData(     primarySwatch: Colors.grey,     primaryColor: Colors.black,     brightness: Brightness.dark,     backgroundColor: const Color(0xFF212121),     accentColor: Colors.white,     accentIconTheme: IconThemeData(color: Colors.black),     dividerColor: Colors.black12,   );    final lightTheme = ThemeData(     primarySwatch: Colors.grey,     primaryColor: Colors.white,     brightness: Brightness.light,     backgroundColor: const Color(0xFFE5E5E5),     accentColor: Colors.black,     accentIconTheme: IconThemeData(color: Colors.white),     dividerColor: Colors.white54,   );    ThemeData _themeData;   ThemeData getTheme() => _themeData;    ThemeNotifier() {     StorageManager.readData('themeMode').then((value) {       print('value read from storage: ' + value.toString());       var themeMode = value ?? 'light';       if (themeMode == 'light') {         _themeData = lightTheme;       } else {         print('setting dark theme');         _themeData = darkTheme;       }       notifyListeners();     });   }    void setDarkMode() async {     _themeData = darkTheme;     StorageManager.saveData('themeMode', 'dark');     notifyListeners();   }    void setLightMode() async {     _themeData = lightTheme;     StorageManager.saveData('themeMode', 'light');     notifyListeners();   } } 

Wrap your app with themeProvider and then apply theme using consumer. By doing so whenever you change the value of theme and call notify listeners widgets rebuild to sync changes.

Main.dart

void main() {   return runApp(ChangeNotifierProvider<ThemeNotifier>(     create: (_) => new ThemeNotifier(),     child: MyApp(),   )); }  class MyApp extends StatelessWidget {   @override   Widget build(BuildContext context) {     return Consumer<ThemeNotifier>(       builder: (context, theme, _) => MaterialApp(         theme: theme.getTheme(),         home: Scaffold(           appBar: AppBar(             title: Text('Hybrid Theme'),           ),           body: Row(             children: [               Container(                 child: FlatButton(                   onPressed: () => {                     print('Set Light Theme'),                     theme.setLightMode(),                   },                   child: Text('Set Light Theme'),                 ),               ),               Container(                 child: FlatButton(                   onPressed: () => {                     print('Set Dark theme'),                     theme.setDarkMode(),                   },                   child: Text('Set Dark theme'),                 ),               ),             ],           ),         ),       ),     );   } } 

Here is the link to github repository.

like image 45
Mateen Kiani Avatar answered Sep 27 '22 02:09

Mateen Kiani


Using Material App

MaterialApp(       title: 'App Title',       theme: ThemeData(         brightness: Brightness.light,         /* light theme settings */       ),       darkTheme: ThemeData(         brightness: Brightness.dark,         /* dark theme settings */       ),       themeMode: ThemeMode.dark,        /* ThemeMode.system to follow system theme,           ThemeMode.light for light theme,           ThemeMode.dark for dark theme       */       debugShowCheckedModeBanner: false,       home: YourAppHomepage(),     ); 

Using CupertinoApp

  1. Detect the dark mode using, WidgetsBinding.instance?.window.platformBrightness

  2. You may also have to listen for the brightness changes from the system in order to update in real-time using WidgetsBindingObserver, and overriding, didChangePlatformBrightness();

CupertinoApp Example:

class MyApp extends StatefulWidget {   const MyApp({Key? key}) : super(key: key);    @override   State<MyApp> createState() => _MyAppState(); }  class _MyAppState extends State<MyApp> with WidgetsBindingObserver {   Brightness? _brightness;    @override   void initState() {     WidgetsBinding.instance?.addObserver(this);     _brightness = WidgetsBinding.instance?.window.platformBrightness;     super.initState();   }    @override   void dispose() {     WidgetsBinding.instance?.removeObserver(this);     super.dispose();   }    @override   void didChangePlatformBrightness() {     if (mounted) {       setState(() {         _brightness = WidgetsBinding.instance?.window.platformBrightness;       });     }      super.didChangePlatformBrightness();   }    CupertinoThemeData get _lightTheme =>       CupertinoThemeData(brightness: Brightness.light, /* light theme settings */);    CupertinoThemeData get _darkTheme => CupertinoThemeData(         brightness: Brightness.dark, /* dark theme settings */,       );    @override   Widget build(BuildContext context) {     return CupertinoApp(       title: 'Demo App',       theme: _brightness == Brightness.dark ? _darkTheme : _lightTheme,       home: MyHomePage(title: 'Demo Home Page'),     );   } } 

You can use scoped_model, provider, bloc or get for seamless experience.

like image 164
Raj Yadav Avatar answered Sep 26 '22 02:09

Raj Yadav