首页 > 其他分享 >FlutterUnit 工具集录 | IconFont 类代码自动生成

FlutterUnit 工具集录 | IconFont 类代码自动生成

时间:2023-06-19 12:34:15浏览次数:35  
标签:FlutterUnit String family fonts IconFont 工具集 file 节点 图标


1. IconFont 类代码生成器的作用

首先介绍一下 FlutterUnit 中,代码生成菜单下的 IconFont 工具的作用。它主要解决Flutter 项目中自定义字体图标使用的问题:

  • 字体图标调用类代码的 自动生成
  • pubspec.yaml 中字体图标节点的 自动配置
  • 多个 自定义字体图标节点的支持。

FlutterUnit 工具集录 | IconFont 类代码自动生成_flutter

一键自动生成相关代码和配置,在项目中直接使用生成类调用:

FlutterUnit 工具集录 | IconFont 类代码自动生成_ico_02


2. 使用方式

如下是 FlutterUnit 中的交互界面,选择相关资源后,点击 生成代码 即可。该功能在新版的 FlutterUnit 桌面版: windows/macos 中可以使用。FlutterUnit 是一个 github 开源项目,可在主页中下载安装包。

FlutterUnit 工具集录 | IconFont 类代码自动生成_json_03


如果不想下载软件,也可以使用项目中的 icon_font_class_parser.dart 作为脚本,提供配置来使用。

FlutterUnit 工具集录 | IconFont 类代码自动生成_android_04


3. 使用步骤

  • [1]. 在 iconfont.cn 挑选图标,加入项目,下载压缩包。

FlutterUnit 工具集录 | IconFont 类代码自动生成_字体图标_05


  • [2]. 选择目标 Flutter 项目地址,配置资源、产物文件位置。

FlutterUnit 工具集录 | IconFont 类代码自动生成_android_06


  • [3]. 点击生成代码按钮

FlutterUnit 工具集录 | IconFont 类代码自动生成_flutter_07


二、工具实现过程中的技术点

这个工具虽小,但包含着很多的知识。下面来分享一下实现过程中使用的技术点,以及碰到的问题以及解决方式。

FlutterUnit 工具集录 | IconFont 类代码自动生成_ico_08


1. 文件的解压

本着尽可能减少使用者操作的原则,工具中直接读取压缩包,省去使用者自己解压的步骤。解压使用的是三方库: archive

FlutterUnit 工具集录 | IconFont 类代码自动生成_字体图标_09

解压过程中主要做的是两件事,其一:寻找 ttf 文件,将其拷贝到目标地址; 其二: 寻找 json 文件,将其读取出来,解析生成调用类代码,其中 tag1 处是解压过程中,获取文件数据,转化为字符串:

final inputStream = InputFileStream(config.srcZip);
// 将压缩包有用资源解压到目标文件
final archive = ZipDecoder().decodeBuffer(inputStream);
for (var file in archive.files) {
  if (file.isFile) {
    if (file.name.endsWith('.ttf')) {
      final outputStream = OutputFileStream(config.ttfDistPath);
      file.writeContent(outputStream);
      outputStream.close();
    }
    if (file.name.endsWith('.json')) {
      dynamic data = file.content; // tag1
      String jsonContent = utf8.decode(data);
      String resultCode = parser(jsonContent,config.fontFamily);
      File distFile = File(config.distFilePath);
      if(!distFile.existsSync()){
        distFile.createSync(recursive: true);
      }
      distFile.writeAsStringSync(resultCode);
      setYaml(config);
    }
  }
}

2. 文件选择器

文件选择器使用的是三方库: file_picker

FlutterUnit 工具集录 | IconFont 类代码自动生成_ico_10

该库支持选择文件夹 getDirectoryPath 和选择文件 pickFiles, 使用起来还是非常方便的。

void _showSelectFile() async {
  String? path;
  if (pickerDir) {
    path = await FilePicker.platform.getDirectoryPath();
  } else {
    FilePickerResult? result = await FilePicker.platform.pickFiles();
    if (result != null) {
      path = result.files.single.path;
    }
  }

}

3. json 文件的解析以及类代码的生成

这点是最核心的逻辑, 压缩包中的 iconfont.json 文件中记录了 名称Unicode 码的映射关系。这里要做的就是提取这些关键数据,生成 Dart 代码。

FlutterUnit 工具集录 | IconFont 类代码自动生成_json_11

逻辑也非常简单,就是字符串的拼接而已,根基映射关系生成一条条的静态常量字符串。不到 20 行代码就完成了最核心的代码生成逻辑。

FlutterUnit 工具集录 | IconFont 类代码自动生成_json_12

String parser(String input,String fontFamily){
    dynamic map = json.decode(input);
    List<dynamic> glyphs = map['glyphs'] as List<dynamic>;
    String code = '';
    for(int i=0;i<glyphs.length;i++){
      String fieldName = glyphs[i]['font_class'];
      String unicode = glyphs[i]['unicode'];
      String lineCode = """static const IconData $fieldName = IconData(0x$unicode, fontFamily: "$fontFamily");\n""";
      code+=lineCode;
    }

    String result =
"""
import 'package:flutter/widgets.dart';
// Power By 张风捷特烈--- Generated file. Do not edit.
// 欢迎支持: https://github.com/toly1994328/FlutterUnit
class $fontFamily {
    $fontFamily._();
    $code
}  
""";
    return result;
  }

4. pubspec.yaml 的自动配置

pubspec.yaml 自动配置图标字体对应的节点,这也是尽可能让使用者减少操作的步骤。 这个工具是在直播时写的,这个功能是耗费时间多的地方。

首先这是一个 yaml 文件,很自然会想到使用 yaml 解析器,修改节点。但使用这种方式存在一个问题: 所有的注释信息在重新生成时会被抹除。这就不得不寻求其他的出路。最终的方案是 正则匹配,如下所示 ^ +- family: +(\w+) 可以匹配到所有的 family 行:

FlutterUnit 工具集录 | IconFont 类代码自动生成_json_13


在配置过程中会有一些情况,比如初始项目中没有 fonts 节点,或者已经配置过了这个字体图标。需要分情况处理,流程图如下:

FlutterUnit 工具集录 | IconFont 类代码自动生成_字体图标_14

采取读行的方式读取文件,通过正则匹配使用存在 fonts 节点,如果没有在 flutter 所在行的下一行添加配置信息:

List<String> lines = pubspecFile.readAsLinesSync();
RegExp fontsRegex = RegExp(r'^  fonts:',multiLine: true);
bool hasFonts = fontsRegex.hasMatch(lines.join('\n'));
if(!hasFonts){
 // 当前没有 fonts 节点,需要添加到 flutter 节点下
 int index = lines.indexWhere((e) => e.startsWith('flutter:'));
 List<String> fonts = [
   '  fonts:',
   '    - family: $familyName',
   '      fonts:',
   '        - asset: $fontAssetsDist',
 ];
 lines.insertAll(index+1, fonts);
 pubspecFile.writeAsStringSync(lines.join('\n'));
 return;
}

当 fonts 节点存在,查询 family ,有没有当前字体图标, 如果没有在 fonts 节点下一行添加配置:

// 存在 fonts 节点,查询 family ,有没有当前字体图标
bool hasTargetFamily = false;
RegExp regExp = RegExp(r'^ +- family: +(\w+)');
for(int i=0;i<lines.length;i++){
  String line = lines[i];
  if(line.startsWith(regExp)){
    String family = regExp.allMatches(line).first.group(1)??'';
    if(family == familyName){
      hasTargetFamily = true;
      break;
    }
  }
}
if(!hasTargetFamily){
  int index = lines.indexWhere((e) => e.startsWith(fontsRegex));
  List<String> fonts = [
    '    - family: $familyName',
    '      fonts:',
    '        - asset: $fontAssetsDist',
  ];
  lines.insertAll(index+1, fonts);
  pubspecFile.writeAsStringSync(lines.join('\n'));
}

到这里就完成了核心功能,感兴趣的可以根据源码调试分析看看。最后,欢迎大家多多关注 FlutterUnit 项目。那本文就到这里,谢谢观看 ~

FlutterUnit 工具集录 | IconFont 类代码自动生成_android_15

作者:张风捷特烈

标签:FlutterUnit,String,family,fonts,IconFont,工具集,file,节点,图标
From: https://blog.51cto.com/u_16163442/6512390

相关文章

  • c# iconfont在后端添加前端显示
    publicstringUnicodeToStr(stringunicodeStr){stringoutStr="";if(!string.IsNullOrEmpty(unicodeStr)){string[]strlist=unicodeStr.Replace("&#","").Repl......
  • 2023-06-05 hexo 分页图标不显示,显示的是【<i class="iconfont icon-arrow-left"></i>
    问题描述:如题。注意:我使用的主题为next。解决方案:全局搜索:navclass="pagination"或者找到路径:你的博客\themes\hexo-theme-next\layout\_partials里的【pagination.swig】文件,对其进行修改;修改前:{%ifpage.prevorpage.next%}<navclass="pagination">{{p......
  • 学术工具集合
    文献部落网址:http://459.org/文献部落是一个免费下载文献的学术导航网站,汇总最新免费下载国内外文献的网站,为广大研究生提供最便捷的文献下载方法。英文文献下载网站应有尽有。也提供超多中文文献下载方法。百度学术、文库、知网等网站文献都免费下载!除此之外,广西图书馆和浙江......
  • vue中离线使用阿里巴巴图标库iconfont
    1.打开iconfont阿里巴巴官网https://www.iconfont.cn2.新建项目(这样方便后期维护图标库) image.png3.把需要的图标添加到购物车 image.png4.打开购物车并选择添加至项目,然后确定 image.png5.这时候可以在项目中看到你选中的svg图标,这时候可以点击下载至本地 image.png6.打开下......
  • STM32 开发工具集 All In One
    STM32开发工具集AllInOneSTM32F103C8T6STM32的3种启动模式自举加载程序Bootloader从程序闪存存储器自举从系统存储器自举从内部SRAM自举https://cdn.xgqfrms.xyz/STM32/STM32F103x8B_DS_CH_V10.pdfhttps://www.st.com/resource/en/application_note/cd001......
  • Linux内核调试的方式以及工具集锦
    原文链接 https://blog.csdn.net/gatieme/article/details/68948080  ......
  • 基于MBD的控制系统建模与仿真软件工具集
    随着新能源汽车和自动驾驶技术的快速发展,汽车电子电气架构的发展已成为汽车行业推陈出新的主要动力:车内电控系统变得越来越复杂、软件迭代周期越来越短,汽车电子软件开发和测试的质量与效率要求也越来越高。汽车电控系统的设计开发已然成为复杂的系统工程。近年来,“基于模型的电子......
  • cnblogs iconfont.js?v=unknown bug All In One
    cnblogsiconfont.js?v=unknownbugAllInOneUncaughtSyntaxError:Unexpectedtoken'<'(aticonfont.js?v=unknown:1:1)demoshttps://i.cnblogs.com/posts/edit;postId=4687706https://www.cnblogs.com/xgqfrms/p/4687706.html#5170738(......
  • 工具集
    Linux连接与文件传输工具MobaXtermportableedition免安装;installeredition安装版FileZilla文件较大时,下载较慢,因此推荐使用FileZilla下载大文件Tabby-跨越堡垒机的SSH利器-基础篇 内存消耗大,支持SSH的JumpHost跳板连接。......
  • 测试工具集
    chrome插件CheckMyLinksNetcat查看网络信息数据库SmartSqlT数据库文档查询、导出工具......