Project Structure
Here’s the updated file structure:
lib/
├── core/
│ ├── themes/
│ │ ├── app_color.dart
│ │ ├── app_typography.dart
│ │ ├── app_theme.dart
├── features/
│ ├── themes/
│ │ └── screen/
│ │ ├── typography_page.dart
│ │ └── color_page.dart
└── main.dart
Take Note: Flutter Default TextTheme Table
TextTheme Property | Font Size | Font Weight | Description |
---|---|---|---|
| 96 | Light (w300) | Largest display text |
| 60 | Light (w300) | Large display text |
| 48 | Regular (w400) | Medium display text |
| 34 | Regular (w400) | Large section headings |
| 24 | Regular (w400) | Medium section headings |
| 20 | Medium (w500) | Small section headings |
| 16 | Regular (w400) | Standard title text |
| 14 | Medium (w500) | Smaller, emphasized subtitles |
| 16 | Regular (w400) | Standard body text |
| 14 | Regular (w400) | Smaller body text |
| 14 | Medium (w500) | Text for buttons |
| 12 | Regular (w400) | Small body text or captions |
| 10 | Regular (w400) | Smallest text (e.g., overline) |
Our Custom Color
Step 1: Define Color Variables
Create the app_color.dart
file to store reusable colors.
app_color.dart
import 'package:flutter/material.dart';
class AppColors {
static const Color primary = Color(0xFF0A192F);
static const Color secondary = Color(0xFF62FFB9);
static const Color warning = Color(0xFFFFC107);
static const Color danger = Color(0xFFDC3545);
static const Color info = Color(0xFF2F3A49);
static const Color light = Color(0xFF0DCAF0);
static const Color dark = Color(0xFF212529);
}
Step 2: Define Typography Variables
Create the app_typography.dart
file for text styles.
app_typography.dart
import 'package:flutter/material.dart';
class AppTypography {
static const TextTheme textTheme = TextTheme(
displayLarge: TextStyle(fontSize: 96, fontWeight: FontWeight.w300, color: Colors.black),
displayMedium: TextStyle(fontSize: 60, fontWeight: FontWeight.w300, color: Colors.black),
displaySmall: TextStyle(fontSize: 48, fontWeight: FontWeight.w400, color: Colors.black),
headlineLarge: TextStyle(fontSize: 34, fontWeight: FontWeight.w400, color: Colors.black),
headlineMedium: TextStyle(fontSize: 24, fontWeight: FontWeight.w400, color: Colors.black),
headlineSmall: TextStyle(fontSize: 20, fontWeight: FontWeight.w500, color: Colors.black),
titleLarge: TextStyle(fontSize: 16, fontWeight: FontWeight.w400, color: Colors.black),
titleMedium: TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: Colors.black),
bodyLarge: TextStyle(fontSize: 16, fontWeight: FontWeight.w400, color: Colors.black),
bodyMedium: TextStyle(fontSize: 14, fontWeight: FontWeight.w400, color: Colors.black),
bodySmall: TextStyle(fontSize: 12, fontWeight: FontWeight.w400, color: Colors.grey),
labelLarge: TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: Colors.white),
labelSmall: TextStyle(fontSize: 10, fontWeight: FontWeight.w400, color: Colors.grey),
);
}
Step 3: Combine Theme Data
Create app_theme.dart
to combine colors and typography into the theme.
app_theme.dart
import 'package:flutter/material.dart';
import 'app_color.dart';
import 'app_typography.dart';
class AppTheme {
static ThemeData lightTheme = ThemeData(
colorScheme: ColorScheme.light(
primary: AppColors.primary,
secondary: AppColors.secondary,
error: AppColors.danger,
),
textTheme: AppTypography.textTheme,
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.primary,
foregroundColor: AppColors.light,
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
),
),
appBarTheme: AppBarTheme(
backgroundColor: AppColors.primary,
titleTextStyle: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, color: AppColors.light),
),
);
}
Step 4: Typography Page
Create a screen to display all text styles.
typography_page.dart
import 'package:flutter/material.dart';
import '../../../core/themes/app_color.dart';
class TypographyPage extends StatelessWidget {
const TypographyPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Typography Page")),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("displayLarge", style: Theme.of(context).textTheme.displayLarge?.copyWith(color: AppColors.primary)),
Text("displayMedium", style: Theme.of(context).textTheme.displayMedium),
Text("displaySmall", style: Theme.of(context).textTheme.displaySmall),
Text("headlineLarge", style: Theme.of(context).textTheme.headlineLarge),
Text("headlineMedium", style: Theme.of(context).textTheme.headlineMedium),
Text("headlineSmall", style: Theme.of(context).textTheme.headlineSmall),
Text("titleLarge", style: Theme.of(context).textTheme.titleLarge),
Text("titleMedium", style: Theme.of(context).textTheme.titleMedium),
Text("bodyLarge", style: Theme.of(context).textTheme.bodyLarge),
Text("bodyMedium", style: Theme.of(context).textTheme.bodyMedium),
Text("bodySmall", style: Theme.of(context).textTheme.bodySmall),
Text("labelLarge", style: Theme.of(context).textTheme.labelLarge),
Text("labelSmall", style: Theme.of(context).textTheme.labelSmall),
],
),
),
);
}
}
Step 5: Color Page
Create a screen to display all colors in boxes.
color_page.dart
import 'package:flutter/material.dart';
import '../../../core/themes/app_color.dart';
class ColorPage extends StatelessWidget {
const ColorPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Color Page")),
body: GridView.count(
crossAxisCount: 2,
padding: const EdgeInsets.all(16),
crossAxisSpacing: 16,
mainAxisSpacing: 16,
childAspectRatio: 2.5,
children: const [
_ColorBox(color: AppColors.primary, name: "Primary", hex: "#0A192F"),
_ColorBox(color: AppColors.secondary, name: "Secondary", hex: "#62FFB9"),
_ColorBox(color: AppColors.warning, name: "Warning", hex: "#FFC107"),
_ColorBox(color: AppColors.danger, name: "Danger", hex: "#DC3545"),
_ColorBox(color: AppColors.info, name: "Info", hex: "#2F3A49"),
_ColorBox(color: AppColors.light, name: "Light", hex: "#0DCAF0"),
_ColorBox(color: AppColors.dark, name: "Dark", hex: "#212529"),
],
),
);
}
}
class _ColorBox extends StatelessWidget {
final Color color;
final String name;
final String hex;
const _ColorBox({
Key? key,
required this.color,
required this.name,
required this.hex,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(8),
),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(name, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: Colors.white)),
Text(hex, style: const TextStyle(fontSize: 12, color: Colors.white)),
],
),
),
);
}
}
Step 6: Update main.dart
Add navigation to both screens.
main.dart
import 'package:flutter/material.dart';
import 'core/themes/app_theme.dart';
import 'features/themes/screen/typography_page.dart';
import 'features/themes/screen/color_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Typography & Colors Demo',
theme: AppTheme.lightTheme,
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Home")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (context) => const TypographyPage())),
child: const Text("Typography Page"),
),
ElevatedButton(
onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (context) => const ColorPage())),
child: const Text("Color Page"),
),
],
),
),
);
}
}
Output