FlutterUnit 组件管理与展示机制解析
本文将从 FlutterUnit 如何展示一个组件信息为线索,展开介绍 FlutterUnit 对组件管理的处理方式。
1. 案例组件模块
FlutterUnit 按照需求划分功能模块,其中 组件集录 展示的内容盛放在 widget_system/widgets
模块下。按照不同的类别,盛放在对应的文件夹下:
拿 Text 组件为例,其中盛放的 desc_zh-CN.json
是该组件展示信息的中文描述数据;其余的 node 文件表示 Text 组件需要展示的节点内容,这些文件都是可以 独立展示 的组件,这也是 FlutterUnit 中的组件示例直接复制就可以用的原因。
比如文字应用的案例,通过 TextDemo2 组件展示:
dart
class TextDemo2 extends StatelessWidget {
const TextDemo2({super.key});
@override
Widget build(BuildContext context) {
const TextStyle style = TextStyle(
fontSize: 50,
color: Colors.white,
backgroundColor: Colors.black,
shadows: [
Shadow(color: Colors.cyanAccent, offset: Offset(1, 1), blurRadius: 10),
Shadow(color: Colors.blue, offset: Offset(-0.1, 0.1), blurRadius: 10),
]);
return const Text("张风捷特烈", style: style);
}
}
对于iOS开发者来说,类似appuploader这样的iOS开发助手工具也能帮助快速构建和测试UI组件,虽然它主要专注于应用打包和上架流程。
2. 从数据库数据到界面展示
组件信息记录在 widget 表中:
一个组件对应若干个展示节点,每个节点信息记录在 node
表中,通过 widget_id
和组件表关联:
这样查询组件对应的展示节点,根据 widget_id 列表查询即可。应用程序中组件数据相关的处理放在 widget_repository ,表示数据仓储层。
其中 database 文件夹维护数据库的增删改查,比如负责查询节点列表的类是 NodeDbRepository
,它依赖 NodeDao
操作数据库,得到 data 数据后,映射为 NodeModel
列表,以供视图层使用:
NodeDao 中通过 sql 语句从数据库中查询节点信息:
dart
//根据 id 查询组件 node
Future<List<Map<String, dynamic>>> queryById(int id) async {
return await database.rawQuery(
"SELECT name,subtitle,code,priority "
"FROM node "
"WHERE widgetId = ? ORDER BY priority",
[id]);
}
3. 处理案例组件映射关系
在之前的版本中,我通过一个 WidgetsMap#map
静态方法,根据组件名称返回对应的案例节点组件列表,以此实现组件的映射关系。这种方式虽然有效,但是维护起来比较繁琐,新增案例时需要找到对应的组件名,加入相关案例:
在新版本中,我实现了一种更为简单、有效、易于管理的方式。通过 代码自动生成 来创建组件和展示节点间的映射关系。每个案例可以通过 组件id + 第几个
唯一确定,可以创建下的映射函数,
desc_zh-CN.json
中已经存在 组件id , 节点对应的序列可以通过解析时的索引得到。最后对于 mapNodeDisplay
来说,就剩下一个问题:
如何获取对应案例的组件名?
组件名虽然可以在 desc_zh-CN.json
中手动给出,但这么做多了一道工序,而且如果更新组件名,还需要同步修改。其实一个文件中的第一个组件叫什么名字,可以通过正则表达式来匹配:
对应的 dart 测试代码如下所示:
dart
void main() async{
String code = '...';
RegExp repClassName = RegExp(r'(?<=class) (\w+) extends .*(Widget \{)',multiLine: true);
Match? match = repClassName.firstMatch(code);
print(match?.group(1));
}
此时在 FlutterUnitTool 的数据分析中,可以创建一个 Node 节点的数据展示。映射关系中的键与值就准备就绪,最后只需要一点点小魔法,遍历当前的节点数据,生成 mapNodeDisplay
对应的源代码即可:
处理代码如下所示,这样 FlutterUnitTool 就可以在 FlutterUnit 组件集录数据方面,从解析数据入库,到自动生成映射文件,达到一站式辅助的功能。让组件案例节点的维护变得非常轻松 ~
dart
void createNodeMap() async {
String savePath = '...';
String content = '';
for(NodePo po in state.nodes){
content +=" '${po.widgetId}#${po.priority}' => const ${po.className}(),\n";
}
String template = '''import 'package:flutter/cupertino.dart';
import 'exp/other_unit.dart';
import 'exp/proxy_unit.dart';
import 'exp/render_object_unit.dart';
import 'exp/sliver_unit.dart';
import 'exp/stateful_unit.dart';
import 'exp/stateless_unit.dart';
Widget mapNodeDisplay(int widgetId, int nodePriority) {
String name = '\$widgetId#\$nodePriority';
return switch (name) {
$content
_ => const SizedBox(),
};
}''';
File(savePath).writeAsString(template);
}
4. 案例展示组件 NodeDisplay
新版的 FlutterUnit 对案例展示的布局效果进行了优化,如下是一个案例节点,它包括 标题
、案例组件
、操作工具
、 介绍信息
四个部分。
其中点击代码按钮,可以展开对应代码。新版的代码展示在女友的帮助下,区支持了局部选择复制; 另外可收叠的面板区域,封装为 CodeDisplay 组件。使用 tolyui 中的 TolyCollapse 组件实现收叠的功能:
这样就从描述信息到数据库,再到解析映射组件,介绍了 FlutterUnit 中一个组件的案例是如何展示的。那本文就到这里,后期还会盘点一些 FlutterUnit 实现过程中的一些有趣的知识。敬请期待~
更多文章和视频知识资讯,大家可以关注我的掘金和B站账号。