https://www.fluttericon.com/ 可以根据需求挑选合适的 icon 图标 , 生成 ttf 文件 ;
下图中 , 选中需要生成 ttf 字体文件的图标 , 这里选中了前
10 个图标 , 然后点击右上角的 DOWNLOAD 按钮 , 该网站会在后台将这
10 个图标的 SVG 文件打包到 ttf 文件中 ,
下载的文件是 flutter-icons-5b92b65c.zip , 后面一串是随机生成的数字 ;
该压缩包中主要有三个文件 ,
① ttf 字体文件 : MyFlutterApp.ttf , svg 格式的图标就封装在该文件中 ;
② dart 文件 : Flutter 中使用 ttf 图标的参考 ,
/// Flutter icons MyFlutterApp
/// Copyright (C) 2021 by original authors @ fluttericon.com, fontello.com
/// This font was generated by FlutterIcon.com, which is derived from Fontello.
///
/// To use this font, place it in your fonts/ directory and include the
/// following in your pubspec.yaml
///
/// flutter:
/// fonts:
/// - family: MyFlutterApp
/// fonts:
/// - asset: fonts/MyFlutterApp.ttf
///
///
/// * Material Design Icons, Copyright (C) Google, Inc
/// Author: Google
/// License: Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
/// Homepage: https://design.google.com/icons/
///
import 'package:flutter/widgets.dart';
class MyFlutterApp {
MyFlutterApp._();
static const _kFontFam = 'MyFlutterApp';
static const String? _kFontPkg = null;
static const IconData threedee_rotation = IconData(0xe855, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData ac_unit = IconData(0xe856, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData access_alarm = IconData(0xe857, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData access_alarms = IconData(0xe858, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData access_time = IconData(0xe859, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData accessibility = IconData(0xe85a, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData accessible = IconData(0xe85b, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData account_balance = IconData(0xe85c, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData account_box = IconData(0xe85d, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData account_balance_wallet = IconData(0xf008, fontFamily: _kFontFam, fontPackage: _kFontPkg);
}
③ json 配置文件 : 这个看起来是给前端开发使用的 ;
{
"name": "",
"css_prefix_text": "",
"css_use_suffix": false,
"hinting": true,
"units_per_em": 1000,
"ascent": 850,
"glyphs": [
{
"uid": "2cc10cdba83708a30142016d40519bb9",
"css": "threedee_rotation",
"code": 59477,
"src": "material"
},
{
"uid": "6a105ad156427b024b633a799e03af7b",
"css": "ac_unit",
"code": 59478,
"src": "material"
},
{
"uid": "9548f8adbc5e7b2dc94633be2821cd1f",
"css": "access_alarm",
"code": 59479,
"src": "material"
},
{
"uid": "2b1bcd8b15d35599f6828e4f5eadfa30",
"css": "access_alarms",
"code": 59480,
"src": "material"
},
{
"uid": "82f44f1094ffd1d78093e76c33cc08cc",
"css": "access_time",
"code": 59481,
"src": "material"
},
{
"uid": "ad65fa7f0f35e80fe1f1a5afadbc561f",
"css": "accessibility",
"code": 59482,
"src": "material"
},
{
"uid": "74bc3a2d72aec992ff1e08cfdd986b38",
"css": "accessible",
"code": 59483,
"src": "material"
},
{
"uid": "5da59f89dd294fa4475a7cdbe3cd3145",
"css": "account_balance",
"code": 59484,
"src": "material"
},
{
"uid": "cdd836ec082da15e51545f2ea1a37015",
"css": "account_balance_wallet",
"code": 61448,
"src": "material"
},
{
"uid": "58f376c8c60c911e8cd5a65becb0d932",
"css": "account_box",
"code": 59485,
"src": "material"
}
]
}
https://www.fluttericon.com/ 中 , 将 SVG 格式的图标拖动到该地址页面的 Custom Icons 区域 ,
拖动过程 :
拖动完成后 , 页面中的 Custom Icons 区域会显示这 20 个 SVG 图标 ;
选中这些图标 , 点击 DOWNLOAD 按钮 , 即可下载生成的 ttf 格式的文件 ;
将 MyFlutterApp.ttf 字体文件拷贝到 Flutter 源码根目录下的 fonts 目录下 ,
在 pubspec.yaml 配置文件中配置字体文件 ,
name: flutter_image_widget
description: A new Flutter application.
version: 1.0.0+1
environment:
sdk: ">=2.1.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.2
path_provider: ^2.0.1
transparent_image: ^2.0.0
cached_network_image: ^2.5.1
dev_dependencies:
flutter_test:
sdk: flutter
flutter:
uses-material-design: true
assets:
- images/sidalin.png
- images/sidalin2.png
- images/waiting.gif
fonts:
- family: MyFlutterApp
fonts:
- asset: fonts/MyFlutterApp.ttf
参考下载时给的示例代码 , 里面有每个图标对应的 16 进制的 Unicode 编码 , 3D 图标对应的编码是 0xe855 ;
import 'package:flutter/widgets.dart';
class MyFlutterApp {
MyFlutterApp._();
static const _kFontFam = 'MyFlutterApp';
static const String? _kFontPkg = null;
static const IconData threedee_rotation = IconData(0xe855, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData ac_unit = IconData(0xe856, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData access_alarm = IconData(0xe857, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData access_alarms = IconData(0xe858, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData access_time = IconData(0xe859, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData accessibility = IconData(0xe85a, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData accessible = IconData(0xe85b, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData account_balance = IconData(0xe85c, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData account_box = IconData(0xe85d, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData account_balance_wallet = IconData(0xf008, fontFamily: _kFontFam, fontPackage: _kFontPkg);
}
IconData 构造函数参数说明 :
代码中使用 IconData 加载自定义图标 , 3D图标对应的编码是 0xe855 ;
Center(
// 加载自定义图标
child: Icon(IconData(0xe855, fontFamily: "MyFlutterApp",), size: 200,),
),
运行效果 : 第一个图标就是加载的自定义图标 ;
完整代码示例 :
import 'package:flutter/material.dart';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:transparent_image/transparent_image.dart';
import 'package:cached_network_image/cached_network_image.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
/// SD 卡路径
String sdPath;
@override
void initState() {
// 获取 SD 卡路径
getSdPath();
}
void getSdPath() async {
String path = (await getExternalStorageDirectory()).path;
setState(() {
sdPath = path;
});
}
@override
Widget build(BuildContext context) {
print("sdPath : $sdPath");
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: ListView(
children: [
Center(
// 加载自定义图标
child: Icon(IconData(0xe855, fontFamily: "MyFlutterApp",), size: 150,),
),
Center(
// 加载 Flutter 内置图标
child: Icon(Icons.threed_rotation, size: 200,),
),
Stack(
children: [
Center(
// 网络加载时显示本地的资源图片
child: FadeInImage.assetNetwork(
// Placeholder
placeholder: "images/waiting.gif",
image: "https://img-blog.csdnimg.cn/20210324110914742.png",
),
)
],
),
Stack(
children: [
// 进度条
Center(child: CircularProgressIndicator(),),
Center(
// 网络加载时渐变出现
child: FadeInImage.memoryNetwork(
// Placeholder
placeholder: kTransparentImage,
image: "https://img-blog.csdnimg.cn/2021032321394771.png",
),
)
],
),
Center(
// 图片加载完成之前显示的是 placeholder , 加载完成后显示网络图片
child: CachedNetworkImage(
// 加载网络图片过程中显示的内容 , 这里显示进度条
placeholder: (context, url)=>CircularProgressIndicator(),
// 网络图片地址
imageUrl: "https://img-blog.csdnimg.cn/20210324100419204.png",
),
),
// 图片组件 , 从网络中加载一张图片
Image.network(
// 图片地址
"https://img-blog.csdnimg.cn/2021032313493741.png",
),
Image(
image: AssetImage("images/sidalin.png"),
),
//Image.asset('images/sidalin2.png', ),
/// 从 SD 卡加载图片
if(sdPath != null)
Image.file(
File('$sdPath/sidalin3.png'),
width: 200,
),
],
)
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
运行效果展示 :
参考资料 :
博客源码下载 :