乐趣区

在Flutter中使用自定义Icon

1. 前言

Flutter作为时下最流行的技术之一,凭借其出色的性能以及抹平多端的差异优势,早已引起大批技术爱好者的关注,甚至一些 闲鱼 美团 腾讯 等大公司均已投入生产使用。虽然目前其生态还没有完全成熟,但身靠背后的 Google 加持,其发展速度已经足够惊人,可以预见将来对 Flutter 开发人员的需求也会随之增长。

无论是为了技术尝鲜还是以后可能的工作机会,都 9102 年了,作为一个前端开发者,似乎没有理由不去尝试它。正是带着这样的心理,笔者也开始学习Flutter,同时建了一个用于练习的仓库,后续所有代码都会托管在上面,欢迎 star,一起学习。

今天要分享的内容其实非常简单,我们都知道 Flutter 内置了一套 Material Design 风格的Icon 图标,但对于一个成熟的 App 而言,通常情况下还是远远不够的。为此,我们需要在项目中引入自定义的Icon 图标

本文就将以 Ant Design 图标库为例,介绍如何在 Flutter 中引入自定义图标。

2. 准备工作:字体文件

正所谓“巧妇难为无米之炊”,要想引入自定义图标,首先我们得准备好图标字体文件(.ttf后缀)。对于大公司而言,找视觉同学切就可以了。但如果是自己做的业余项目或者没有资源的时候,我们可以上阿里巴巴矢量图标库 pick 自己心仪的图标。

这里就以 Ant Design 官方图标库为例(一共有 600 个图标),通过以下操作,我们将图标字体文件加入到项目中:

添加购物车 –> 点击购物车 –> 下载代码 –> 解压 –> 拷贝至项目(可重命名)

3. 声明自定义字体

仅仅将字体文件复制到项目中还不够,我们需要通过 声明 的方式来告诉 Flutter 有新字体可用。打开项目根目录下的 pubspec.yaml 文件,找到 fonts 这一段:

To add custom fonts to your application, add a fonts section here, in this “flutter” section. Each entry in this list should have a “family” key with the font family name, and a “fonts” key with a list giving the asset and other descriptors for the font.

注释就是让我们在该段文字下方添加自定义字体的声明,结合其注释掉的例子和当前的项目目录,我们可以这样配置:

项目工程目录结构
.
├── README.md
├── android
│   └── app
├── assets
│   └── fonts
│       └── AntdIcons.ttf
├── flutter_training_app.iml
├── ios
│   └── Flutter
├── lib
│   └── main.dart
├── pubspec.lock
└── pubspec.yaml

字体声明
fonts:
  - family: AntdIcons
    fonts:
      - asset: assets/fonts/AntdIcons.ttf

注意: 配置完之后,一定要执行 flutter packages get 命令以及重新编译项目,否则字体文件无法使用。

4. 编写自定义的 IconData

其实到目前为止,我们已经可以使用刚刚下载的图标了,就像下面代码这样:

Icon(IconData(0xe77d, fontFamily: 'AntdIcons'),
  size: 20,
  color: Colors.black
)

其中 fontFamily 的值 'AntdIcons' 就是我们刚才声明的新字体,但是代码中的 0xe77d 数值是哪来的呢?再次打开之前下载解压之后的文件夹,其中有一个 demo_index.html 文件,在浏览器中打开它我们可以看到下面的画面:

Unicode 这个 Tab 下,我们可以看到它贴心地给出了所有图标的 TypeUnicode 码 对照关系。所以理论上来说,我们想用哪个图标,只要 copy 其 Unicode 码到代码中就可以了。

不过,这种做法显然不是很友好。首先,我们每次使用 Icon 之前都要从这张关系表中查找;其次,你确定下次代码中看到这串数字是对应什么图标吗(更不用说其他人了)?所以,我们需要更优雅的方法来管理自定义图标。

其实做法也简单,我们可以创建一个自定义图标的类:

class AntdIcons {static const IconData checkCircle = IconData(0xe77d, fontFamily: 'AntdIcons');
  static const IconData CI = IconData(0xe77e, fontFamily: 'AntdIcons');
  static const IconData Dollar = IconData(0xe77f, fontFamily: 'AntdIcons');
  ...
}

然后使用方法就变成了:

Icon(
  AntdIcons.checkCircle,
  size: 20,
  color: Colors.black
)

以上代码完全等同于前面直接使用 Unicode 码 的效果。不过要想用上所有的图标,我们还得丰富 AntdIcons 这个类。为此,可以写上一段小脚本,在 demo_index.html 浏览器窗口的控制台中运行就能得到定义 IconData 的代码:

function camelCase(str) {return str.replace(/[ -]+(\w)/g, (match, char) => char.toUpperCase());
}

function makeCode({name, code}) {return `static const IconData ${camelCase(name)} = IconData(0${code.substr(2, 5)}, fontFamily: 'antd-icons');\n`;
}

Array
  .from(document.querySelectorAll('.unicode .dib'))
  .map(element => {
    return {name: element.querySelector('.name').innerText,
      code: element.querySelector('.code-name').innerText
    };
  })
  .map(makeCode)
  .join('\n');

PS:输出结果中可能由于图标作者自己命名不规范而导致个别的小错误,手动修改即可,完整文件可以看这里。

接下来,就是愉快玩耍的时候啦~~~

5. 总结

本文通过一个实际的 Ant Design 图标例子,详细地介绍了如何在 Flutter 中引入自定义图标,希望可以帮助到你哦~

本文所有代码托管在这儿,也可以关注我的 Blog,欢迎一起学习~

退出移动版