Open In App

Flutter – Dark Theme

Last Updated : 17 Feb, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

Nowadays almost all the mobile application uses a dark theme, for example, Instagram, Whatsapp, Youtube, etc. It’s easy to implement in Flutter, Just a few lines of code require to achieve this. But before doing that let’s explore some important concept in flutter which are used to achieve the dark theme

ThemeData Class :

ThemeData class defines the theme for App. It’s used inside MaterialApp, It helps to configure the appearance of the entire app. We can override it as per our requirement and make changes.

Now let’s dig into the code and explore the new things in the ThemeData class.

Example Code:

Dart




MaterialApp(
 theme: ThemeData(
   primaryColor: Colors.blue,
   accentColor: Colors.yellow,
   textTheme: TextTheme(bodyText2: TextStyle(color: Colors.purple)),
 ),
  
 home: Scaffold(
   appBar: AppBar(
     title: const Text('ThemeData Example'),
   ),
  
   floatingActionButton: FloatingActionButton(
     child: const Icon(Icons.add),
     onPressed: () {},
   ),
  
   body: Center(
     child: Text(
       'Geeks For Geeks',
     ),
   ),
 ),
)


Important parameters in ThemeData class:

1. Brightness :  

Describes the contrast of a theme or color palette.

Example:

Dart




ThemeData(
   brightness:Brightness.light,
 ),
  
ThemeData(
   brightness:Brightness.light,
 )


2. visualDensity :  

Visual density is the vertical and horizontal “compactness” of the components in the UI. Note: horizontal and vertical density must be less than or equal to max Horizontal or MaximumVeriticalDensity i.e.  4.0

Example:

Dart




ThemeData(
 brightness: Brightness.light,
 visualDensity: VisualDensity(
   horizontal: 2.0,
   vertical: 2.0
 )
),


3. primaryColor : 

Defines the primary color for the app, similarly, we can define the primary color for a light theme and a dark theme.

Example:

Dart




ThemeData(
 primaryColor: Colors.blue,
),


Similarly, we can define the accentColor, accentColorLight, accentColorDark, feel free to use them in your app.

4. IconThemeData: 

Defines the color, opacity, and size of icons.

Example:

Dart




ThemeData(
 iconTheme: IconThemeData(
   color: Colors.amber,
   size: 15.0,
   opacity: 10
 )
),


Similarly, you can have other properties in flutter official docs. I personally recommend visiting at least once in Flutter official docs.

Now we get enough knowledge to accomplish our goal, let’s get started. We are going to use the Provider package, this is not mandatory we can do the dark theme implementation without Provider But for better architecture, we are using it. Add provider package into pubspec.yaml file.

main.dart

This is our main class the execution starts from this class. Just take a look at the theme properties of the MaterialApp(), all the things we have discussed above are written here, I guess you get some clarity here.

Dart




import 'package:dark_theme_app/Button_tap_listener.dart';
import 'package:dark_theme_app/dark_theme_screen.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
  
  
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
    
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<ButtonTapListenerClass>(
      create: (context) => ButtonTapListenerClass(),
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Flutter Demo',
          
        // Themes
        darkTheme: ThemeData.dark(),
        home: DarkThemeExample(),
        theme: ThemeData(
            brightness: Brightness.dark,
            visualDensity: VisualDensity(horizontal: 2.0, vertical: 2.0),
            primaryColorLight: Color(0xff03203C),
            primaryColorDark: Color(0xff242B2E),
            
            // Icon Theme
            iconTheme:
                IconThemeData(color: Colors.amber, size: 15.0, opacity: 10),
            accentColor: Colors.amber,
            accentColorBrightness: Brightness.light),
      ),
    );
  }
}


 DarkThemeExample Class :

This class contains our UI part of the app, when we tap on the bulb image it will call the clickEvent() which is defined in our business class. Here we just toggle one boolean variable to get a dark theme and light theme. 

Dart




import 'package:dark_theme_app/Button_tap_listener.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
  
class DarkThemeExample extends StatefulWidget {
  @override
  _DarkThemeExampleState createState() => _DarkThemeExampleState();
}
  
class _DarkThemeExampleState extends State<DarkThemeExample> {
  @override
  Widget build(BuildContext context) {
      
    // initialise the provider class
    final object = Provider.of<ButtonTapListenerClass>(context);
    return Scaffold(
      backgroundColor: object.isClicked
          ? Theme.of(context).primaryColorDark
          : Theme.of(context).primaryColorLight,
        
      // appbar
      appBar: AppBar(
        backgroundColor: Colors.green,
        title: Text("Geeks For Geeks"),
        centerTitle: true,
      ),
      body: Container(
        margin: EdgeInsets.symmetric(horizontal: 150.0),
        child:  GestureDetector(
          child: object.isClicked
              ? Image.asset(
            "assets/light.png",
            height: 450.0,
          )
              : Image.asset(
            "assets/dark.png",
            height: 450.0,
          ),
          onTap: () {
            object.clickEvent();
          },
        ),
      ),
    );
  }
}


ButtonTapListener Class :

This class is the business class that is we do all the business logic or operation here. For our example, the functionality of this class is less, But this is the right approach to separate our UI and business logic & follow good architecture to build an app.

In this class, we extend the ChangeNotifier class which is in the provider package. Just notice the clickEvent() , there we are using notifyListner(). When we call this function we just tell the listeners to rebuild it to get updated value or new value. In our case, we just toggle the boolean value. By looking at it, you can think in this way this is a mess, why we do all these things for this small app. But believe me, we need to follow at least one architecture pattern. If you do not want to use it feel free to use a simple approach.

Dart




import 'package:flutter/material.dart';
  
class ButtonTapListenerClass extends ChangeNotifier {
  bool isClicked = false;
  
  void clickEvent() {
    isClicked = !isClicked;
    notifyListeners();
  }
}


Output:

dark theme(tap on the bulb)

light theme(Tap on the bulb)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads