Introduction: In this article, we will dive deep into the world of Flutter app theming using the ThemeData class and Theme widget. By the end of this article, you will be able to create visually appealing and cohesive app interfaces that adapt to various screen sizes and device capabilities.

Before we begin, it is important to note that the ThemeData class is the single most important class for styling and theming in Flutter. This class provides properties to customize colors, fonts, and sizes throughout the app.

Now, let’s begin our deep dive into the Flutter ThemeData class and Theme widget.

Understanding ThemeData: ThemeData is a class that contains a set of default values for visual properties that can be customized. These properties include:

  • Color scheme
  • Text theme
  • Icon theme
  • Target platform
  • Font families
  • and many more

The Flutter framework provides a default theme, which can be used as a starting point and customized as per the app requirements.

To use a ThemeData, we can either pass it directly to the Theme widget or set it as the MaterialApp theme. Here’s an example:

MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);

In this example, we have set the primary color of the app to blue using the primarySwatch property.

Customizing the Text Theme: The text theme is another crucial aspect of the ThemeData class. It provides properties to customize the text appearance of different widgets like AppBar, Button, and Text.

To customize the text theme, you can use the textTheme property of the ThemeData class. Here’s an example:

MaterialApp(
theme: ThemeData(
textTheme: TextTheme(
displayLarge: GoogleFonts.getFont(
'Outfit',
fontSize: 20,
fontWeight: FontWeight.bold,
color: AppColor.BLACK
),
displayMedium: GoogleFonts.getFont(
'Outfit',
fontSize: 18,
fontWeight: FontWeight.bold,
color: AppColor.BLACK
),
displaySmall: GoogleFonts.getFont(
'Outfit',
fontSize: 16,
fontWeight: FontWeight.bold,
color: AppColor.BLACK
),
titleLarge: GoogleFonts.getFont(
'Outfit',
fontSize: 18,
fontWeight: FontWeight.bold,
color: AppColor.BLACK
),
titleMedium: GoogleFonts.getFont(
'Outfit',
fontSize: 14,
fontWeight: FontWeight.bold,
color: AppColor.BLACK
),
titleSmall: GoogleFonts.getFont(
'Outfit',
fontSize: 12,
fontWeight: FontWeight.bold,
color: AppColor.BLACK
),
bodyLarge:GoogleFonts.getFont(
'Outfit',
fontSize: 16,
color: AppColor.BLACK
),
bodyMedium: GoogleFonts.getFont(
'Outfit',
fontSize: 14,
color: AppColor.BLACK
),
bodySmall: GoogleFonts.getFont(
'Outfit',
fontSize: 12,
color: AppColor.BLACK.withOpacity(0.4)
),
),
),
home: MyHomePage(),
);

In this example, we have customized the font sizes and colors for headline1, headline2, and bodyText1 text styles.

Customizing the Icon Theme: The icon theme allows you to customize the appearance of icons throughout the app.

To customize the icon theme, you can use the iconTheme property of the ThemeData class. Here’s an example:

MaterialApp(
theme: ThemeData(
iconTheme: IconThemeData(
color: Colors.orange,
size: 24,
),
),
home: MyHomePage(),
);

In this example, we have set the color of the icons to orange and their size to 24.

Advanced App Theming with ThemeData: Now that we have learned the basics of the ThemeData class, let’s explore some advanced features of the ThemeData class that can help us create visually appealing and cohesive app interfaces.

  • Customizing Color Schemes: You can use the colorScheme property of the ThemeData class to define custom color schemes for your app. Here’s an example:
MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSwatch(
primarySwatch: Colors.blue,
).copyWith(
secondary: Colors.yellow,
),
),
home: MyHomePage(),
);

In this example, we have defined a custom color scheme using the primary color as blue and the secondary color as yellow.

  • Customizing Typography: You can use the typography property of the ThemeData class to define custom typography styles for your app. Here’s an example:
MaterialApp(
theme: ThemeData(
typography: Typography.material2018(
platform: TargetPlatform.android,
).copyWith(
bodyLarge: TextStyle(fontSize: 18, color: Colors.black),
),
),
home: MyHomePage(),
);

Here’s an example of how you can create a different class for your ThemeData.

import 'package:flutter/material.dart';

import ‘package:flutter/material.dart’;
import ‘package:google_fonts/google_fonts.dart’;
import ‘package:seller_flutter/app/common/utils/res/app_color.dart’;

class AppTheme {
static ThemeData getAppTheme() {
return ThemeData(
appBarTheme: AppBarTheme(
titleTextStyle: GoogleFonts.getFont(
‘Outfit’,
fontSize: 18,
fontWeight: FontWeight.bold,
color: AppColor.BLACK
),
actionsIconTheme: const IconThemeData(
color: AppColor.PRIMARY),
iconTheme: const IconThemeData(
color :AppColor.PRIMARY),
backgroundColor: AppColor.WHITE,
),
cardTheme: const CardTheme(
color: AppColor.WHITE
),
primaryColor: AppColor.PRIMARY,
highlightColor: AppColor.PRIMARY,
scaffoldBackgroundColor: AppColor.BG_COLOR,
textTheme: TextTheme(
displayLarge: GoogleFonts.getFont(
‘Outfit’,
fontSize: 20,
fontWeight: FontWeight.bold,
color: AppColor.BLACK
),
displayMedium: GoogleFonts.getFont(
‘Outfit’,
fontSize: 18,
fontWeight: FontWeight.bold,
color: AppColor.BLACK
),
displaySmall: GoogleFonts.getFont(
‘Outfit’,
fontSize: 16,
fontWeight: FontWeight.bold,
color: AppColor.BLACK
),
titleLarge: GoogleFonts.getFont(
‘Outfit’,
fontSize: 18,
fontWeight: FontWeight.bold,
color: AppColor.BLACK
),
titleMedium: GoogleFonts.getFont(
‘Outfit’,
fontSize: 14,
fontWeight: FontWeight.bold,
color: AppColor.BLACK
),
titleSmall: GoogleFonts.getFont(
‘Outfit’,
fontSize: 12,
fontWeight: FontWeight.bold,
color: AppColor.BLACK
),
bodyLarge:GoogleFonts.getFont(
‘Outfit’,
fontSize: 16,
color: AppColor.BLACK
),
bodyMedium: GoogleFonts.getFont(
‘Outfit’,
fontSize: 14,
color: AppColor.BLACK
), bodySmall: GoogleFonts.getFont(
‘Outfit’,
fontSize: 12,
color: AppColor.BLACK.withOpacity(0.4)
),
),
iconTheme: const IconThemeData(color: AppColor.PRIMARY),
textButtonTheme: TextButtonThemeData(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(AppColor.BODY_COLOR),
foregroundColor: MaterialStateProperty.all<Color>(AppColor.WHITE),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(5))
)
)
)
),
toggleButtonsTheme: ToggleButtonsThemeData(
selectedColor: AppColor.BODY_COLOR,
fillColor: AppColor.BODY_COLOR.withOpacity(0.1),
textStyle: const TextStyle(color: AppColor.WHITE),
selectedBorderColor: AppColor.BODY_COLOR,
borderRadius: BorderRadius.circular(8.0),
),
colorScheme: ColorScheme.fromSwatch().copyWith(
primary: AppColor.PRIMARY,
onPrimary: AppColor.PRIMARY,
secondary: AppColor.SECONDARY,
onSecondary: AppColor.SECONDARY,
surface: AppColor.BG_COLOR,
onSurface: AppColor.BG_COLOR,
error: Colors.red,
onError: Colors.red,
background: AppColor.BG_COLOR,
onBackground: AppColor.BG_COLOR,
brightness: Brightness.light,
),
);
}
}

void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: ‘Flutter Theme Demo’,
theme: AppTheme.getThemeData(),
home: MyHomePage(title: ‘Flutter Theme Demo Home Page’),
);
}
}

 

We can make a separate class for color also :

import 'dart:ui';

class AppColor {
static const BG_COLOR = Color(0xFFf2f2f5);
static const PRIMARY = Color(0xFF4764cd);
static const SECONDARY = Color(0xFFeff2fa);

static const TEXT_COLOR = Color(0xFF3a3f49);
static const BODY_COLOR = Color(0xFF4764cd);
}

 

Here the excerpts for deprecated properties:

@Deprecated(
'This is the term used in the 2014 version of material design. The modern term is headline1. '
'This feature was deprecated after v1.13.8.',
)
TextStyle? display4,
@Deprecated(
'This is the term used in the 2014 version of material design. The modern term is headline2. '
'This feature was deprecated after v1.13.8.',
)
TextStyle? display3,
@Deprecated(
'This is the term used in the 2014 version of material design. The modern term is headline3. '
'This feature was deprecated after v1.13.8.',
)
TextStyle? display2,
@Deprecated(
'This is the term used in the 2014 version of material design. The modern term is headline4. '
'This feature was deprecated after v1.13.8.',
)
TextStyle? display1,
@Deprecated(
'This is the term used in the 2014 version of material design. The modern term is headline5. '
'This feature was deprecated after v1.13.8.',
)
TextStyle? headline,
@Deprecated(
'This is the term used in the 2014 version of material design. The modern term is headline6. '
'This feature was deprecated after v1.13.8.',
)
TextStyle? title,
@Deprecated(
'This is the term used in the 2014 version of material design. The modern term is subtitle1. '
'This feature was deprecated after v1.13.8.',
)
TextStyle? subhead,
@Deprecated(
'This is the term used in the 2014 version of material design. The modern term is subtitle2. '
'This feature was deprecated after v1.13.8.',
)
TextStyle? subtitle,
@Deprecated(
'This is the term used in the 2014 version of material design. The modern term is bodyText1. '
'This feature was deprecated after v1.13.8.',
)
TextStyle? body2,
@Deprecated(
'This is the term used in the 2014 version of material design. The modern term is bodyText2. '
'This feature was deprecated after v1.13.8.',
)

Now you can use the ThemeData class and Theme widget to create visually appealing and cohesive app interfaces that adapt to various screen sizes and device capabilities. By learning the basics of ThemeData, such as customizing colors, fonts, and sizes, and diving into advanced features like customizing color schemes and typography, you have a solid foundation for building themeable and visually stunning Flutter apps.

#Mastering #Flutter #ThemeData #Theme #Widget #Advanced #App #Theming