{"id":33565,"date":"2023-02-08T10:53:33","date_gmt":"2023-02-08T10:53:33","guid":{"rendered":"https:\/\/www.bacancytechnology.com\/blog\/?p=33565"},"modified":"2024-12-27T08:39:07","modified_gmt":"2024-12-27T08:39:07","slug":"flutter-theming","status":"publish","type":"post","link":"https:\/\/www.bacancytechnology.com\/blog\/flutter-theming","title":{"rendered":"Flutter Theming: Light and Dark Theme with Custom Color"},"content":{"rendered":"<h2>What is Flutter Theming?<\/h2>\n<p>A theme is a generic styling element that represents the overall style, look, and feel of your application. When you wish to modify your Flutter app theme, say for eg. from Flutter Dark mode to Flutter Light mode or vice-versa, it is known as <b>Flutter theming<\/b>.<\/p>\n<p>There are many articles available on <i>Flutter theming<\/i>, showing how to implement Flutter theme Dark Light in projects using the default App Theme and their default Colors attribute. But in the live project, we are required to add our custom Color for our app branding.<\/p>\n<p>In this blog, we will be sharing how to create a flutter custom theme step by step<\/p>\n<div id=\"attachment_33597\" style=\"width: 660px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-33597\" src=\"https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2023\/02\/create-a-flutter-custom-theme.webp\" alt=\"create a flutter custom theme\" width=\"650\" height=\"354\" class=\"size-full wp-image-33597\" srcset=\"https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2023\/02\/create-a-flutter-custom-theme.webp 650w, https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2023\/02\/create-a-flutter-custom-theme-300x163.webp 300w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><p id=\"caption-attachment-33597\" class=\"wp-caption-text\">create a flutter custom theme<\/p><\/div>\n<h2>Step-by-Step Guide for Flutter Theming with Custom Color<\/h2>\n<p>To successfully implement Flutter theming, you will have to take care of the following prerequisites:<\/p>\n<ul class=\"bullets text-left\">\n<li>Create flutter project<\/li>\n<li>Add riverpod package in yaml (Note: You can use any state management packages base on your convenient)<\/li>\n<\/ul>\n<p>Once you are ready to go ahead, execute the following steps consecutively for enabling custom Flutter theming.<\/p>\n<p class=\"boxed bg--secondary\" style=\"border: 1px solid #c7c7c7; box-shadow: 0 0 40px rgba(0, 0, 0, 0.2);\"><strong><i><span style=\"font-size:22px; color:#000;\">Want to Implement a custom option to change the theme dynamically in your app?<\/span><br \/>\n<a href=\"https:\/\/www.bacancytechnology.com\/hire-flutter-developer\" target=\"_blank\" rel=\"noopener\">Hire Flutter Developers<\/a> from Bacancy to add or customize theme Color for your app branding<\/strong><\/i><\/p>\n<h3>Step 1: Create Light\/Dark Theme<\/h3>\n<p>For creating a theme for light and dark mode, we use ThemeData class and customize colors and other properties based on needs. We have created one method for getting ThemeDate based on selected light\/dark themes.<\/p>\n<p>We give different values for scaffoldBackgroundColor, bodyColor, thumbColor, listTileTheme, and appBarTheme based on the selected theme.<\/p>\n<pre>ThemeData getAppTheme(BuildContext context, bool isDarkTheme) {\r\n  return ThemeData(\r\n    scaffoldBackgroundColor: isDarkTheme ? Colors.black : Colors.white,\r\n    textTheme: Theme.of(context)\r\n        .textTheme\r\n        .copyWith(\r\n          titleSmall:\r\n              Theme.of(context).textTheme.titleSmall?.copyWith(fontSize: 11),\r\n        )\r\n        .apply(\r\n          bodyColor: isDarkTheme ? Colors.white : Colors.black,\r\n          displayColor: Colors.grey,\r\n        ),\r\n    switchTheme: SwitchThemeData(\r\n      thumbColor: MaterialStateProperty.all(\r\n          isDarkTheme ? Colors.orange : Colors.purple),\r\n    ),\r\n    listTileTheme: ListTileThemeData(\r\n        iconColor: isDarkTheme ? Colors.orange : Colors.purple),\r\n    appBarTheme: AppBarTheme(\r\n        backgroundColor: isDarkTheme ? Colors.black : Colors.white,\r\n        iconTheme:\r\n            IconThemeData(color: isDarkTheme ? Colors.white : Colors.black54)),\r\n  );\r\n}<\/pre>\n<h3>Step 2: Create Provider for Theme State Using River-pod<\/h3>\n<p>We will use river-pod to manage the app theme state. We only want to store bool value to manage light or dark themes so we will use StateProvider.<\/p>\n<div id=\"attachment_33591\" style=\"width: 660px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-33591\" src=\"https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2023\/02\/StateProvider.webp\" alt=\"StateProvider\" width=\"650\" height=\"113\" class=\"size-full wp-image-33591\" srcset=\"https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2023\/02\/StateProvider.webp 650w, https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2023\/02\/StateProvider-300x52.webp 300w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><p id=\"caption-attachment-33591\" class=\"wp-caption-text\">StateProvider<\/p><\/div>\n<h3>Step 3: Use Theme in App<\/h3>\n<p>We use river-pod in the project so we have to  wrap MyApp with ProviderScope to access all providers though-out app. MyApp extends ConsumerWidget so we can get the WidgetRef object in the build method and access any river-pod using the ref variable. <strong>getAppTheme(context, ref.watch(appThemeProvider))<\/strong> method listens to any change in the app theme and updates the app accordingly.<\/p>\n<pre>class MyApp extends ConsumerWidget {\r\n  const MyApp({super.key});\r\n\r\n  @override\r\n  Widget build(BuildContext context, WidgetRef ref) {\r\n    return MaterialApp(\r\n      title: 'Flutter Light\/Dark Theme',\r\n      debugShowCheckedModeBanner: false,\r\n      theme: getAppTheme(context, ref.watch(appThemeProvider)),\r\n      home: const MyHomePage(),\r\n    );\r\n  }\r\n}<\/pre>\n<p><strong>ref.read(appThemeProvider.notifier).state = value<\/strong>. We are updating the theme state in appThemeProvider when the switch state is changed from light\/dark mood.<\/p>\n<pre>Switch(\r\n  activeColor: Colors.orange,\r\n  onChanged: (value) {\r\n    ref.read(appThemeProvider.notifier).state = value;\r\n  },\r\n  value: isDarkMode )<\/pre>\n<h3>Step 4: Add Custom Color<\/h3>\n<p>It works fine as far as it will show the same color in all icons and texts. If we want to use different colors on icons, we have to create an extension for the Theme. Create a class and extend with ThemeExtension and add necessary fields that you want to customize.<\/p>\n<div id=\"attachment_33592\" style=\"width: 660px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-33592\" src=\"https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2023\/02\/Add-custom-color.webp\" alt=\"Add custom color\" width=\"650\" height=\"954\" class=\"size-full wp-image-33592\" srcset=\"https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2023\/02\/Add-custom-color.webp 650w, https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2023\/02\/Add-custom-color-204x300.webp 204w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><p id=\"caption-attachment-33592\" class=\"wp-caption-text\">Add custom color<\/p><\/div>\n<p>Now add this extension attribute in ThemeData in our create method getAppTheme and define the theme according to colors.<\/p>\n<div id=\"attachment_33593\" style=\"width: 660px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-33593\" src=\"https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2023\/02\/add-extension-attribute-in-ThemeData.webp\" alt=\"add extension attribute in ThemeData\" width=\"650\" height=\"239\" class=\"size-full wp-image-33593\" srcset=\"https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2023\/02\/add-extension-attribute-in-ThemeData.webp 650w, https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2023\/02\/add-extension-attribute-in-ThemeData-300x110.webp 300w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><p id=\"caption-attachment-33593\" class=\"wp-caption-text\">add extension attribute in ThemeData<\/p><\/div>\n<p>Create another extension function which we use to access custom color easily.<\/p>\n<div id=\"attachment_33594\" style=\"width: 660px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-33594\" src=\"https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2023\/02\/extension-function.webp\" alt=\"extension function\" width=\"650\" height=\"113\" class=\"size-full wp-image-33594\" srcset=\"https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2023\/02\/extension-function.webp 650w, https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2023\/02\/extension-function-300x52.webp 300w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><p id=\"caption-attachment-33594\" class=\"wp-caption-text\">extension function<\/p><\/div>\n<p>We can access these colors in the widget simply using <strong>colors(context).color1<\/strong>. If we do not specify the Icon color, it will fetch the color from listTileTheme.<\/p>\n<pre>ListTile(\r\n    leading: Icon(Icons.chat_outlined, color: colors(context).color3),\r\n    title: Text( \"Help Center\", style: Theme.of(context).textTheme.titleSmall),\r\n ),\r\nListTile(\r\n    leading: const Icon(Icons.notifications),\r\n    title: Text(\"Notification\", style: Theme.of(context).textTheme.titleSmall),\r\n),<\/pre>\n<h3>Step 5: Full Source Code<\/h3>\n<p>Here is the code for theme class:<\/p>\n<div id=\"attachment_33595\" style=\"width: 660px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-33595\" src=\"https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2023\/02\/Full-source-code.webp\" alt=\"Full source code\" width=\"650\" height=\"1873\" class=\"size-full wp-image-33595\" srcset=\"https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2023\/02\/Full-source-code.webp 650w, https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2023\/02\/Full-source-code-104x300.webp 104w, https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2023\/02\/Full-source-code-355x1024.webp 355w, https:\/\/www.bacancytechnology.com\/blog\/wp-content\/uploads\/2023\/02\/Full-source-code-533x1536.webp 533w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><p id=\"caption-attachment-33595\" class=\"wp-caption-text\">Full source code<\/p><\/div>\n<p>Here is code of our main screen:<\/p>\n<pre>import 'package:flutter\/material.dart';\r\nimport 'package:flutter_riverpod\/flutter_riverpod.dart';\r\nimport 'package:light_dark_mode\/provider%20\/app_theme_provider.dart';\r\nimport 'package:light_dark_mode\/utils\/app_theme.dart';\r\n\r\nvoid main() {\r\n  runApp(const ProviderScope(child: MyApp()));\r\n}\r\n\r\nclass MyApp extends ConsumerWidget {\r\n  const MyApp({super.key});\r\n\r\n  @override\r\n  Widget build(BuildContext context, WidgetRef ref) {\r\n    return MaterialApp(\r\n      title: 'Flutter Light\/Dark Theme',\r\n      debugShowCheckedModeBanner: false,\r\n      theme: getAppTheme(context, ref.watch(appThemeProvider)),\r\n      home: const MyHomePage(),\r\n    );\r\n  }\r\n}\r\n\r\nclass MyHomePage extends ConsumerWidget {\r\n  const MyHomePage({Key? key}) : super(key: key);\r\n\r\n  @override\r\n  Widget build(BuildContext context, WidgetRef ref) {\r\n    var isDarkMode = ref.watch(appThemeProvider);\r\n    return Scaffold(\r\n      appBar: AppBar(\r\n        elevation: 0,\r\n        leading: const Icon(Icons.arrow_back_ios_sharp),\r\n        actions: const [\r\n          Padding(\r\n            padding: EdgeInsets.symmetric(horizontal: 15.0),\r\n            child: Icon(Icons.add_circle_outline),\r\n          )\r\n        ],\r\n      ),\r\n      body: Padding(\r\n        padding: const EdgeInsets.symmetric(horizontal: 8.0),\r\n        child: ListView(\r\n          children: [\r\n            CircleAvatar(\r\n              radius: 60,\r\n              backgroundColor: Colors.grey,\r\n              child: Padding(\r\n                padding: const EdgeInsets.all(1), \/\/ Border radius\r\n                child: ClipRRect(\r\n                    borderRadius: BorderRadius.circular(60),\r\n                    child: Image.asset(\r\n                      \"assets\/ic_profile.jpeg\",\r\n                      fit: BoxFit.fill,\r\n                      width: 120,\r\n                      height: 120,\r\n                    )),\r\n              ),\r\n            ),\r\n            Container(\r\n              margin: const EdgeInsets.only(top: 10, bottom: 60),\r\n              alignment: Alignment.center,\r\n              child: Text(\r\n                \"Testing User\",\r\n                style: Theme.of(context).textTheme.titleLarge,\r\n              ),\r\n            ),\r\n            ListTile(\r\n              leading: Icon(isDarkMode ? Icons.brightness_3 : Icons.sunny),\r\n              title: Text(\r\n                isDarkMode ? \"Dark mode\" : \"Light mode\",\r\n                style: Theme.of(context).textTheme.titleSmall,\r\n              ),\r\n              trailing: Consumer(builder: (context, ref, child) {\r\n                return Transform.scale(\r\n                  scale: 0.7,\r\n                  child: Switch(\r\n                    activeColor: Colors.orange,\r\n                    onChanged: (value) {\r\n                      ref.read(appThemeProvider.notifier).state = value;\r\n                    },\r\n                    value: isDarkMode,\r\n                  ),\r\n                );\r\n              }),\r\n            ),\r\n            ListTile(\r\n              leading: Icon(Icons.grid_on_sharp, color: colors(context).color1,),\r\n              title: Text(\r\n                \"Story\",\r\n                style: Theme.of(context).textTheme.titleSmall,\r\n              ),\r\n            ),\r\n            ListTile(\r\n              leading: Icon(Icons.settings, color: colors(context).color2),\r\n              title: Text(\"Settings and Privacy\",\r\n                  style: Theme.of(context).textTheme.titleSmall),\r\n            ),\r\n            ListTile(\r\n              leading: Icon(Icons.chat_outlined, color: colors(context).color3),\r\n              title: Text(\r\n                \"Help Center\",\r\n                style: Theme.of(context).textTheme.titleSmall,\r\n              ),\r\n            ),\r\n            ListTile(\r\n              leading: const Icon(Icons.notifications),\r\n              title: Text(\r\n                \"Notification\",\r\n                style: Theme.of(context).textTheme.titleSmall,\r\n              ),\r\n            ),\r\n          ],\r\n        ),\r\n      ),\r\n    );\r\n  }\r\n}<\/pre>\n<p>You can find full code here: <a href=\"https:\/\/github.com\/KinjalDhamat312\/LightDarkThemeFlutter\" target=\"_blank\" rel=\"noopener\">GitHub Repository<\/a>.<\/p>\n<h2>Conclusion<\/h2>\n<p>I hope this blog will help to customize your Flutter app theme. In this blog we customized Colors in ThemeExtension; however, we can use any field to customize the value. Flutter theming is just one aspect, there are several other solutions that <a href=\"https:\/\/www.bacancytechnology.com\/flutter-app-development\" target=\"_blank\" rel=\"noopener\">Flutter app development company<\/a> like Bacancy can provide you. Contact us Now.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>What is Flutter Theming? A theme is a generic styling element that represents the overall style, look, and feel of your application. When you wish to modify your Flutter app theme, say for eg. from Flutter Dark mode to Flutter Light mode or vice-versa, it is known as Flutter theming. There are many articles available [&hellip;]<\/p>\n","protected":false},"author":34,"featured_media":33598,"comment_status":"open","ping_status":"open","sticky":false,"template":"blog-new-template.php","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"_lmt_disableupdate":"no","_lmt_disable":"","footnotes":""},"categories":[1200],"tags":[],"coauthors":[1568,2425],"class_list":["post-33565","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-flutter"],"acf":[],"modified_by":"Binal Prajapati","_links":{"self":[{"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/posts\/33565","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/users\/34"}],"replies":[{"embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/comments?post=33565"}],"version-history":[{"count":0,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/posts\/33565\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/media\/33598"}],"wp:attachment":[{"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/media?parent=33565"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/categories?post=33565"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/tags?post=33565"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/coauthors?post=33565"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}