Flutter Custom Icons – Automatic & Manual Way (Icon Font or SVG)

3  comments

Icons are Flutter's first class citizen. Even right out of the box, you get access to all the official material icons from Google. Many times though, just these official icons are not enough. For example, if you want to show an icon of particular social media, you'll have to reach for other than the official icons.

Adding icons could not be simpler - you just have to know the right tools to use. Or you don't even have to use any tools... Alright, let's just jump into the tutorial and see it for yourself.

Two Ways of Adding Icons

In the old days of Flutter development, you had to jump through hoops, write a lot of totally repetitive code, and add all the custom icons manually. However, because of Flutter's huge (and well deserved) popularity, you don't have to write a single line of boilerplate - no matter which option of adding icons you choose, there are tools and packages for everything.

Most of the big icon packs like Font Awesome or the community-driven Material Design Icons have pre-made packages which you can simply add to your pubspec.yaml file and use them immediately.

If you want to add a more obscure icon pack, or you have icons which your client/company/whoever wants you to use, don't worry! There are tools which make adding custom icon packs a breeze.

The "pub.dev" Way

I know, adding packages is obvious, but I still want to quickly show you the process. Let's say we want to show the Material Design Icons, which are extended by community. Well, there's a package for that!

pubspec.yaml

dependencies:
  flutter:
    sdk: flutter
  material_design_icons_flutter: ^3.2.3895

Using icons added this way is as simple as importing a class.

main.dart

import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
...
Icon(MdiIcons.badminton, size: 200),
...

Custom Icon Packs

Let's say that you want to use social media icons from Socicon. As of now, there isn't any pre-made package on pub.dev, so you'll have to add them yourself. The following process works for any icon pack which has a SVG icon font, so basically any pack you like.

Converting for Use in Flutter

The first step is to obviously download the icon pack. If you're following along with Socicon, get it from this download page.

Get the "raw" icon font

Once you extract the downloaded ZIP file, the SVG font file we're after is located inside the fonts subfolder. The problem is, you cannot just plop this SVG into your Flutter app. Thankfully, there's a handy open-source tool fluttericon.com which can do the conversion for you.

  1. Drag the SVG font file to the webpage.
  2. Select all the icons you want.
  3. Give your custom Flutter icon pack a name (it will also be used as the class name).
  4. Download and you're half way there.

Get the converted font for use in Flutter

Using It in Flutter

Displaying icons generated by FlutterIcon is as straightforward as it gets. After extracting the ZIP file, you want to get the ttf file located under the fonts folder into your Flutter project.

While it is in fact a font, I like to create a folder called icons, just so that regular fonts won't get mixed up with icon fonts. Then just drag the Socicon.ttf file into this new folder.

All the icon fonts go here

This is a regular font file, so you want to add it as a font asset in the pubspec.yaml all the way down under "flutter".

pubspec.yaml

...
flutter:
  ...
  fonts:
    - family: Socicon
      fonts:
        - asset: icons/Socicon.ttf

With that, drag the socicon_icons.dart extracted from the ZIP file into the lib folder. It contains a Socicon class which provides mappings for every single icon from the font.

This Dart file contains mappings for all the icons

But... this class is full of errors! Actually, the number of real errors in this file is blown out of proportion. It all stems from the fact that certain field names are prohibited in Dart. Obviously, keywords like async or return are out of the game, but so are names starting with a number. Surely, there are two such names in this class - 500px and 8tracks. Just prefix them with a letter and all the errors will be gone.

Always rename icon mappings conflicting with Dart's keywords and naming rules. If you can, suffix the name with "icon" for easier intellisense suggestions.

If suffixing is not possible (name starting with a number), you'll have to prefix it.

socicon_icons.dart

class Socicon {
  Socicon._();

  static const _kFontFam = 'Socicon';

  // Prefixed with "i"
  static const IconData i500px = const IconData(0xe800, fontFamily: _kFontFam);
  static const IconData i8tracks = const IconData(0xe801, fontFamily: _kFontFam);
  ...
}

Using these icons is again as simple as importing the socicon_icons.dart file.

main.dart

import 'socicon_icons.dart';
...
Icon(Socicon.youtube, size: 200),
...

What You Learned...

Whether you must use custom icons because of your work/client's demands or you just cannot find the right icon in the official pack from Google, adding them to your app is not hard at all.

Many times, you can use pre-configured packages from pub.dev, if those are not available though, you can always jump to fluttericon.com and generate all the files you need from an SVG font file.

About the author 

Matt Rešetár

Matt is an app developer with a knack for teaching others. Working as a freelancer and most importantly developer educator, he is set on helping other people succeed in their Flutter app development career.

You may also like

  • Thanks great tutorial, the only problem than I have now is with the web page to convert at .ttf it doesn’t support a big package of custom icons

  • for more than one icon use more than one family.

    class QuotationAddIcon {
    QuotationAddIcon._();

    static const _kFontFam = ‘Quotation_saugat_add_icon’;
    static const _kFontFam1 = ‘CategoryIcon’;
    // static const String _kFontPkg = “icons/CategoryIcon”;

    static const IconData iUe800 = const IconData(0xe800, fontFamily: _kFontFam);
    static const IconData categoryIcon =
    const IconData(0xe800, fontFamily: _kFontFam1);
    }

  • {"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}
    >