dynamic_fonts 2.2.1 dynamic_fonts: ^2.2.1 copied to clipboard
A package to include dynamic web-hosted fonts in your Flutter app.
dynamic_fonts #
The dynamic_fonts
package for Flutter allows you to (relatively) easily add
dynamically loaded web-hosted fonts to your appーjust like the
google_fonts package, but for any
arbitrary fonts hosted anywhere.
dynamic_fonts
is a fork of google_fonts
with more of the API exposed so that
you can specify your own fonts.
Why would you use this? #
If there is a font that you know you're going to use in your app, just bundle it normally. Don't bother with this package.
But if your app e.g. offers users multiple choices of fonts, and
- Some fonts may not be used at all, depending on user preferences
- Bundling all of the fonts would bloat your app too much
then this package gives you a convenient way to load your fonts dynamically and keep your initial download slim.
Getting Started #
With the dynamic_fonts
package, .ttf
or .otf
files do not need to be
stored in your assets folder and mapped in the pubspec. Instead, they can be
fetched once via http at runtime, and cached in the app's file system. This is
ideal for development, and can be the preferred behavior for production apps
that are looking to reduce the app bundle size. Still, you may at any time
choose to include the font file in the assets, and the Dynamic Fonts package
will prioritize pre-bundled files over http fetching. Because of this, the
Dynamic Fonts package allows developers to choose between pre-bundling the fonts
and loading them over http, while using the same API.
For example, say you want to use the FiraGO font (not in Google Fonts) in your Flutter app.
First, add the dynamic_fonts
package to your pubspec
dependencies.
To import DynamicFonts
:
import 'package:dynamic_fonts/dynamic_fonts.dart';
Registering a font #
To register your font with DynamicFonts
, you will need to supply the family
name and a map of DynamicFontsVariant
to DynamicFontsFile
.
DynamicFontsVariant
merely indicates font weight and font style (normal vs italic)DynamicFontsFile
stores checksum info and provides the URL for the file
If we want to download FiraGO from the repo hosted on GitHub (don't do this in a production app!), the URL depends on the variant, so we need to do something like this:
class FiraGoFile extends DynamicFontsFile {
FiraGoFile(this.variant, String expectedFileHash, int expectedLength)
: super(expectedFileHash, expectedLength);
final DynamicFontsVariant variant;
String get _dir {
switch (variant.fontStyle) {
case FontStyle.normal:
return 'Roman';
case FontStyle.italic:
return 'Italic';
}
throw Exception('Unknown style: ${variant.fontStyle}');
}
@override
String get url =>
'https://raw.githubusercontent.com/bBoxType/FiraGO/9882ba0851f88ab904dc237f250db1d45641f45d/Fonts/FiraGO_TTF_1001/$_dir/FiraGO-${variant.toApiFilenamePart()}.ttf';
}
Now we can register the font like so, supplying the SHA256 and file sizes for security. (Actual SHA256 values not shown!)
DynamicFonts.register(
'FiraGO',
[
FiraGoFile(
const DynamicFontsVariant(
fontWeight: FontWeight.w400,
fontStyle: FontStyle.normal,
),
'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef',
804888,
),
FiraGoFile(
const DynamicFontsVariant(
fontWeight: FontWeight.w700,
fontStyle: FontStyle.normal,
),
'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef',
807140,
),
FiraGoFile(
const DynamicFontsVariant(
fontWeight: FontWeight.w400,
fontStyle: FontStyle.italic,
),
'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef',
813116,
),
].fold<Map<DynamicFontsVariant, DynamicFontsFile>>(
{},
(acc, file) => acc..[file.variant] = file,
),
);
Using a font #
To use DynamicFonts
with the default TextStyle:
Text(
'This is Dynamic Fonts',
style: DynamicFonts.getFont('FiraGO'),
),
To use DynamicFonts
with an existing TextStyle
:
Text(
'This is Dynamic Fonts',
style: DynamicFonts.getFont(
'FiraGO', textStyle: TextStyle(color: Colors.blue, letterSpacing: .5),
),
),
or
Text(
'This is Dynamic Fonts',
style: DynamicFonts.getFont('FiraGO', textStyle: Theme.of(context).textTheme.headline4),
),
To override the fontSize
, fontWeight
, or fontStyle
:
Text(
'This is Dynamic Fonts',
style: DynamicFonts.getFont(
'FiraGO',
textStyle: Theme.of(context).textTheme.headline4,
fontSize: 48,
fontWeight: FontWeight.w700,
fontStyle: FontStyle.italic,
),
),
You can also use DynamicFonts.getTextTheme()
to make or modify an entire text
theme to use the "FiraGO" font.
MaterialApp(
theme: ThemeData(
textTheme: DynamicFonts.getTextTheme(
'FiraGO',
Theme.of(context).textTheme,
),
),
);
Or, if you want a TextTheme
where a couple of styles should use a different
font:
final textTheme = Theme.of(context).textTheme;
MaterialApp(
theme: ThemeData(
textTheme: DynamicFonts.getTextTheme('FiraGO', textTheme).copyWith(
body1: DynamicFonts.getFont('OtherFont', textStyle: textTheme.body1),
),
),
);
Bundling font files in your application's assets #
The dynamic_fonts
package will automatically use matching font files in your
pubspec.yaml
's assets
(rather than fetching them at runtime via HTTP). Once
you've settled on the fonts you want to use:
- Download the font files from wherever. You only need to download the weights
and styles you are using for any given family. Italic styles will include
Italic
in the filename. Font weights map to file names as follows:
{
FontWeight.w100: 'Thin',
FontWeight.w200: 'ExtraLight',
FontWeight.w300: 'Light',
FontWeight.w400: 'Regular',
FontWeight.w500: 'Medium',
FontWeight.w600: 'SemiBold',
FontWeight.w700: 'Bold',
FontWeight.w800: 'ExtraBold',
FontWeight.w900: 'Black',
}
-
Move those fonts to a top-level app directory (e.g.
dynamic_fonts
). -
Ensure that you have listed the folder (e.g.
dynamic_fonts/
) in yourpubspec.yaml
underassets
.
Note: If your fonts' names do not match up with the Google Font naming
conventions, you will either have to register them in the fonts
section of
pubspec.yaml
, or rename them.
Licensing Fonts #
Be sure to check the licenses of your fonts. For instance FiraGO comes with an
OFL.txt
file.
Once you've decided on the fonts you want in your published app, you should add the appropriate licenses to your flutter app's LicenseRegistry.
For example:
void main() {
LicenseRegistry.addLicense(() async* {
final license = await rootBundle.loadString('dynamic_fonts/OFL.txt');
yield LicenseEntryWithLineBreaks(['dynamic_fonts'], license);
});
runApp(...);
}