Skip to main content

Change font

This guide explains how to customize the font family used throughout the ELMS (E-Learning Management System) Flutter application.

Overview

The ELMS app uses a centralized font management system where the font family is defined once and applied globally throughout the entire application. The current app uses the Geist font family.

Current Font Configuration

Current Font: Geist Font Weights Available: 100, 200, 300, 400, 500, 600, 700, 800, 900

File Locations

1. Theme Configuration File

lib/core/theme/app_theme.dart

This file contains the fontFamily constant that sets the global font for the entire app.

2. Font Assets Directory

assets/fonts/

This directory contains all the .ttf (TrueType Font) files for your custom fonts.

3. Font Registration File

pubspec.yaml

This file registers your fonts with Flutter so they can be used in the app.

Step-by-Step Guide to Change Fonts

Step 1: Obtain Your Font Files

Before you begin, you need to have your font files ready:

Supported Font Formats:

  • .ttf (TrueType Font) - Most common and recommended
  • .otf (OpenType Font) - Also supported

What You Need:

  • Font files for different weights (Regular, Bold, Light, etc.)
  • At minimum: Regular (400) and Bold (700) weights
  • Optionally: Multiple weights for better typography

Where to Get Fonts:

  1. Google Fonts (Free): https://fonts.google.com

    • Download any font family
    • Click "Download family" to get all weights
  2. Font Squirrel (Free): https://www.fontsquirrel.com

    • High-quality free fonts for commercial use
  3. Adobe Fonts (Paid): https://fonts.adobe.com

    • Premium fonts with Adobe subscription
  4. Custom Fonts: Use your own brand fonts

    • Get from your design team
    • Ensure you have proper licensing

Step 2: Add Font Files to Assets

  1. Navigate to the fonts directory:

    assets/fonts/
  2. Add your font files:

    • Copy all your .ttf or .otf files to this directory
    • Use clear naming convention: FontName-Weight.ttf

    Example:

    assets/fonts/
    ├── Roboto-Regular.ttf
    ├── Roboto-Bold.ttf
    ├── Roboto-Light.ttf
    ├── Roboto-Medium.ttf
    └── Roboto-Black.ttf
  3. Naming Best Practices:

    • Keep filenames consistent
    • Use hyphen or underscore between name and weight
    • Examples: Roboto-Bold.ttf, OpenSans-Regular.ttf, Poppins-SemiBold.ttf

Step 3: Register Fonts in pubspec.yaml

Open pubspec.yaml and update the fonts section:

Current Configuration (Geist font):

fonts:
- family: Geist
fonts:
- asset: assets/fonts/Geist-Black.ttf
weight: 900
- asset: assets/fonts/Geist-Bold.ttf
weight: 700
- asset: assets/fonts/Geist-ExtraBold.ttf
weight: 800
- asset: assets/fonts/Geist-ExtraLight.ttf
weight: 200
- asset: assets/fonts/Geist-Light.ttf
weight: 300
- asset: assets/fonts/Geist-Medium.ttf
weight: 500
- asset: assets/fonts/Geist-Regular.ttf
weight: 400
- asset: assets/fonts/Geist-SemiBold.ttf
weight: 600
- asset: assets/fonts/Geist-Thin.ttf
weight: 100

Example: Changing to Roboto font:

fonts:
- family: Roboto
fonts:
- asset: assets/fonts/Roboto-Thin.ttf
weight: 100
- asset: assets/fonts/Roboto-Light.ttf
weight: 300
- asset: assets/fonts/Roboto-Regular.ttf
weight: 400
- asset: assets/fonts/Roboto-Medium.ttf
weight: 500
- asset: assets/fonts/Roboto-Bold.ttf
weight: 700
- asset: assets/fonts/Roboto-Black.ttf
weight: 900

Font Weight Reference:

WeightCommon NameNumeric Value
ThinThin/Hairline100
Extra LightUltra Light200
LightLight300
RegularNormal/Book400
MediumMedium500
Semi BoldDemi Bold600
BoldBold700
Extra BoldUltra Bold800
BlackHeavy/Black900

Important Notes:

  • The family name is what you'll use in your code
  • Match weight numbers to the actual font weight
  • Indentation matters in YAML - use 2 spaces
  • Regular (400) weight is required for proper fallback

Step 4: Update Theme Configuration

Open lib/core/theme/app_theme.dart and update the fontFamily constant:

Current Code:

class AppTheme {
ThemeData theme;
AppTheme(this.theme);
bool isDarkMode = false;
static const String fontFamily = 'Geist'; // Current font

// ... rest of the code
}

Update to your new font:

class AppTheme {
ThemeData theme;
AppTheme(this.theme);
bool isDarkMode = false;
static const String fontFamily = 'Roboto'; // Your new font name

// ... rest of the code
}

Important: The fontFamily string must exactly match the family name you used in pubspec.yaml.

Step 5: Clean and Rebuild

After making changes, you need to rebuild your app:

  1. Stop the running app (if any)

  2. Clean the build:

    flutter clean
  3. Get dependencies:

    flutter pub get
  4. Rebuild and run:

    flutter run

Why Clean Build is Required:

  • Font assets are compiled into the app during build
  • Changes to pubspec.yaml require a fresh build
  • Hot reload/restart won't apply font changes

Complete Example: Changing to Poppins Font

Let's walk through a complete example of changing from Geist to Poppins:

1. Download Poppins from Google Fonts

2. Copy Font Files

# Copy the font files you need
cp ~/Downloads/Poppins/Poppins-Regular.ttf assets/fonts/
cp ~/Downloads/Poppins/Poppins-Bold.ttf assets/fonts/
cp ~/Downloads/Poppins/Poppins-Light.ttf assets/fonts/
cp ~/Downloads/Poppins/Poppins-Medium.ttf assets/fonts/
cp ~/Downloads/Poppins/Poppins-SemiBold.ttf assets/fonts/

3. Update pubspec.yaml

fonts:
- family: Poppins
fonts:
- asset: assets/fonts/Poppins-Light.ttf
weight: 300
- asset: assets/fonts/Poppins-Regular.ttf
weight: 400
- asset: assets/fonts/Poppins-Medium.ttf
weight: 500
- asset: assets/fonts/Poppins-SemiBold.ttf
weight: 600
- asset: assets/fonts/Poppins-Bold.ttf
weight: 700

4. Update app_theme.dart

static const String fontFamily = 'Poppins';

5. Rebuild

flutter clean
flutter pub get
flutter run

Using Multiple Font Families

You can register multiple font families in your app and use them selectively:

In pubspec.yaml:

fonts:
- family: Poppins
fonts:
- asset: assets/fonts/Poppins-Regular.ttf
weight: 400
- asset: assets/fonts/Poppins-Bold.ttf
weight: 700

- family: RobotoMono
fonts:
- asset: assets/fonts/RobotoMono-Regular.ttf
weight: 400
- asset: assets/fonts/RobotoMono-Bold.ttf
weight: 700

Using in Code:

// Main app font (defined in AppTheme.fontFamily)
Text('Regular text') // Uses default Poppins

// Use specific font for code blocks
Text(
'Code snippet',
style: TextStyle(fontFamily: 'RobotoMono'),
)

Font Weight Usage in Code

Once your fonts are configured, you can use different weights:

// Regular (400)
Text('Regular text')

// Bold (700)
Text('Bold text', style: TextStyle(fontWeight: FontWeight.bold))

// Specific weights
Text('Light text', style: TextStyle(fontWeight: FontWeight.w300))
Text('Medium text', style: TextStyle(fontWeight: FontWeight.w500))
Text('SemiBold text', style: TextStyle(fontWeight: FontWeight.w600))

// Available FontWeight constants
FontWeight.w100 // Thin
FontWeight.w200 // Extra Light
FontWeight.w300 // Light
FontWeight.w400 // Regular/Normal
FontWeight.w500 // Medium
FontWeight.w600 // Semi Bold
FontWeight.w700 // Bold
FontWeight.w800 // Extra Bold
FontWeight.w900 // Black

Troubleshooting

Problem: Font not showing after changes

Solution 1: Clean build required

flutter clean
flutter pub get
flutter run

Solution 2: Check pubspec.yaml indentation

  • YAML is indent-sensitive
  • Use 2 spaces for indentation
  • No tabs allowed

Solution 3: Verify font family name

  • Must match exactly between pubspec.yaml and app_theme.dart
  • Case-sensitive (e.g., "Roboto" ≠ "roboto")

Problem: Some text still shows old font

Possible causes:

  • Some widgets might have hardcoded font family
  • Need to do a clean rebuild
  • Cache not cleared

Solution:

# On iOS
flutter clean
cd ios
rm -rf Pods Podfile.lock
pod install
cd ..
flutter run

# On Android
flutter clean
cd android
./gradlew clean
cd ..
flutter run

Problem: Font looks different than expected

Check:

  1. Correct weight files are added
  2. Weight numbers match the actual font weight
  3. Font files are not corrupted (re-download if needed)

Problem: App crashes after font change

Common issues:

  • Missing Regular (400) weight font file
  • Incorrect file path in pubspec.yaml
  • Corrupted font file

Solution:

  • Ensure Regular weight is always included
  • Verify all paths are correct
  • Re-download font files

Problem: YAML parsing error

Common mistakes:

# ❌ Wrong - using tabs
fonts:
- family: Roboto

# ❌ Wrong - incorrect indentation
fonts:
- family: Roboto
fonts:
- asset: assets/fonts/Roboto-Regular.ttf

# ✅ Correct - 2 spaces, consistent indentation
fonts:
- family: Roboto
fonts:
- asset: assets/fonts/Roboto-Regular.ttf
weight: 400

Best Practices

1. Font Selection

  • Choose readable fonts for body text
  • Ensure good support for numbers and special characters
  • Test on both iOS and Android devices
  • Consider accessibility for users with dyslexia (fonts like OpenDyslexic)

2. Font Weights

  • Always include Regular (400) and Bold (700) at minimum
  • Add additional weights for better typography
  • Don't add unnecessary weights to reduce app size

3. Font File Size

  • Multiple font files increase app size
  • Each weight file can be 50-200KB
  • Consider app size when adding many weights
  • Remove unused weights after testing

4. Testing

  • Test on multiple screen sizes
  • Test both light and dark themes
  • Verify special characters display correctly
  • Check RTL (Right-to-Left) language support if applicable

5. Performance

  • Fonts are loaded at app startup
  • More font files = slightly longer startup time
  • Generally negligible impact for 5-10 font files

Font Licensing

Important: Always verify you have the legal right to use a font in your app.

License Types:

  1. Open Source (OFL - Open Font License)

    • Free for commercial use
    • Example: Google Fonts, Font Squirrel
    • No attribution required (but appreciated)
  2. Commercial License

    • Purchase required for commercial apps
    • Check license terms for mobile app usage
    • May require per-app or per-developer license
  3. Personal Use Only

    • Cannot be used in commercial/published apps
    • Only for personal projects and learning

Checking License:

# Most fonts include a LICENSE.txt or OFL.txt file
ls assets/fonts/
# Look for: LICENSE.txt, OFL.txt, or README.txt

Here are some popular, free, high-quality fonts for mobile apps:

Sans-Serif (Modern, Clean)

  • Roboto - Google's Android system font
  • Open Sans - Highly readable, versatile
  • Lato - Professional, friendly
  • Poppins - Modern, geometric
  • Montserrat - Elegant, urban
  • Inter - Optimized for screens
  • Nunito - Rounded, friendly

Serif (Traditional, Formal)

  • Merriweather - Readable, elegant
  • Lora - Modern serif, readable
  • Playfair Display - Elegant headlines

Monospace (Code, Technical)

  • Roboto Mono - Clean, professional
  • Fira Code - Developer favorite
  • JetBrains Mono - Excellent for code

Download These Fonts:

Advanced: Using Google Fonts Package

Instead of manually adding fonts, you can use the google_fonts package:

1. Add dependency to pubspec.yaml:

dependencies:
google_fonts: ^6.2.0

2. Use in code:

import 'package:google_fonts/google_fonts.dart';

// In app_theme.dart
static TextStyle get textTheme => GoogleFonts.robotoTextTheme();

// Or in individual widgets
Text(
'Hello World',
style: GoogleFonts.poppins(
fontSize: 16,
fontWeight: FontWeight.bold,
),
)

Pros:

  • No need to download font files
  • Easy to switch fonts
  • Automatic caching

Cons:

  • Requires internet on first load
  • Slightly larger app size
  • Less control over exact weights

Additional Resources

Font Resources:

Font Tools:

Flutter Documentation:

Testing Fonts:

Quick Reference Checklist

Use this checklist when changing fonts:

  • Downloaded font files (.ttf or .otf)
  • Verified font license allows commercial use
  • Copied font files to assets/fonts/ directory
  • Updated pubspec.yaml with font family and weights
  • Updated fontFamily in lib/core/theme/app_theme.dart
  • Verified family name matches exactly (case-sensitive)
  • Included at least Regular (400) weight
  • Ran flutter clean
  • Ran flutter pub get
  • Rebuilt and ran the app
  • Tested on both light and dark themes
  • Verified text is readable on different screens
  • Checked all font weights display correctly

Note: Font changes require a complete rebuild (not just hot reload) to take effect. Always test thoroughly on actual devices after changing fonts, as fonts may render differently than on simulators/emulators.