Flutter 组件集录 | 组件案例是怎么展示的?

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站账号。

相关推荐
JustHappy6 小时前
古法编程秘籍(二):什么是代码模块化?别背概念,把房间收拾明白就够了
前端·后端
小江的记录本6 小时前
【JVM虚拟机】堆内存分代模型:年轻代(Eden+Survivor)、老年代、元空间Metaspace(附《思维导图》+《面试高频考点清单》)
java·前端·jvm·后端·python·spring·面试
IT_陈寒9 小时前
Python闭包里藏的这个坑,差点让我加班到凌晨
前端·人工智能·后端
IT_陈寒9 小时前
Java注解空指针?这个坑我踩得莫名其妙
前端·人工智能·后端
土狗TuGou10 小时前
SQL内功笔记 · 第8篇:事务的四大特性与隔离级别
数据库·笔记·后端·sql·mysql·oracle
ZengLiangYi10 小时前
React Query + REST API 最佳实践
javascript·后端·react.js
星浩AI10 小时前
项目实战:合同智能审批 · LangGraph + HITL 人机协同方案 [有源码]
后端·langchain·agent
JavaGuide10 小时前
Codex 接入第三方模型 DeepSeek、GLM、Kimi 教程:CC-Switch 和 Codex++ 两种方案对比
后端·ai编程
ZengLiangYi10 小时前
Fastify 加 Electron:把 Web 服务嵌进桌面应用
前端·javascript·后端
李白你好11 小时前
页面资产梳理 · 技术指纹识别 · Spring 端点探测
java·后端·spring