DEV Community

Jhin Lee
Jhin Lee

Posted on • Updated on

Material 3 theme recipe for the flutter app

Apply Color scheme

1. Create the color scheme and export it using the theme builder.

https://m3.material.io/theme-builder
Material3 theme builder

For collaborating with UI designers, it can be generated from Figma as well:
https://www.figma.com/community/plugin/1034969338659738588/Material-Theme-Builder
https://www.figma.com/community/file/1035203688168086460

The web version of the theme builder creates the color_schemes.g.dart file with an example(main.g.dart).
Copy the color_schemes.g.dart file into the project.

2. Set the theme with the MaterialApp()

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(useMaterial3: true, colorScheme: lightColorScheme),
      darkTheme: ThemeData(useMaterial3: true, colorScheme: darkColorScheme),
      themeMode: ThemeMode.light, // Default is system
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

The themeMode is the system by default. Change and verify if the colors are good.

Apply typography

1. Create a typography file

// Example typography.dart file
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';

final textTheme = TextTheme(
  displayLarge: GoogleFonts.inter(
    fontWeight: FontWeight.w400,
    fontSize: 57,
    height: 64 / 57,
    letterSpacing: -0.25,
  ),
  displayMedium: GoogleFonts.inter(
    fontWeight: FontWeight.w400,
    fontSize: 45,
    height: 52 / 45,
  ),
  displaySmall: GoogleFonts.inter(
    fontWeight: FontWeight.w400,
    fontSize: 36,
    height: 44 / 36,
  ),
  headlineLarge: GoogleFonts.inter(
    fontWeight: FontWeight.w400,
    fontSize: 32,
    height: 40 / 32,
  ),
  headlineMedium: GoogleFonts.inter(
    fontWeight: FontWeight.w400,
    fontSize: 28,
    height: 36 / 28,
  ),
  headlineSmall: GoogleFonts.inter(
    fontWeight: FontWeight.w400,
    fontSize: 24,
    height: 32 / 24,
  ),
  titleLarge: GoogleFonts.inter(
    fontWeight: FontWeight.w700,
    fontSize: 22,
    height: 28 / 22,
  ),
  titleMedium: GoogleFonts.inter(
    fontWeight: FontWeight.w600,
    fontSize: 16,
    height: 24 / 16,
    letterSpacing: 0.1,
  ),
  titleSmall: GoogleFonts.inter(
    fontWeight: FontWeight.w600,
    fontSize: 14,
    height: 20 / 14,
    letterSpacing: 0.1,
  ),
  labelLarge: GoogleFonts.inter(
    fontWeight: FontWeight.w700,
    fontSize: 14,
    height: 20 / 14,
  ),
  labelMedium: GoogleFonts.inter(
    fontWeight: FontWeight.w700,
    fontSize: 12,
    height: 16 / 12,
  ),
  labelSmall: GoogleFonts.inter(
    fontWeight: FontWeight.w700,
    fontSize: 11,
    height: 16 / 11,
  ),
  bodyLarge: GoogleFonts.inter(
    fontWeight: FontWeight.w400,
    fontSize: 16,
    height: 24 / 16,
  ),
  bodyMedium: GoogleFonts.inter(
    fontWeight: FontWeight.w400,
    fontSize: 14,
    height: 20 / 14,
  ),
  bodySmall: GoogleFonts.inter(
    fontWeight: FontWeight.w400,
    fontSize: 12,
    height: 16 / 12,
  ),
);
Enter fullscreen mode Exit fullscreen mode

In the example, I used GoogleFont. Should you wish to use the google font, add the package.

flutter pub add google_fonts
Enter fullscreen mode Exit fullscreen mode

Adjust the values according to the design.

2. Apply the typography to MaterialApp (textTheme)

      theme: ThemeData(
        useMaterial3: true,
        colorScheme: lightColorScheme,
        textTheme: textTheme,
      ),
      darkTheme: ThemeData(
        useMaterial3: true,
        colorScheme: darkColorScheme,
        textTheme: textTheme,
      ),
Enter fullscreen mode Exit fullscreen mode

How to use the theme in your widgets

By default, everything should be set with the theme we defined. You can use these methods if you need to override them for some widgets.

// Method 1 - Read from the context and apply
final color = Theme.of(context).colorScheme.primary;
Container(color: color);

// Method 2 - Wrap the widget with the Theme
Theme(
      data: Theme.of(context).copyWith(
        textTheme: Theme.of(context)
            .textTheme
            .apply(displayColor: Colors.white, bodyColor: Colors.white),
      ),
      child: Widget(),
)
Enter fullscreen mode Exit fullscreen mode

Never hard code colors or text styles.

The complete code can be found on github

Top comments (0)