news 2026/3/7 1:37:31

开源鸿蒙跨平台开发训练营--AtomGit(GitCode)口袋工具(七)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
开源鸿蒙跨平台开发训练营--AtomGit(GitCode)口袋工具(七)

我们继续接着上一章的内容,完成文件内容的显示。

显示文件内容

1. 调整侧边栏内容

上一章,我们侧边栏只显示了根目录下的文件和文件夹。这一张我们要将其显示成一个可折叠和展开的文件树。目的是为了可以让用户在侧边栏中切换想要查看的文件。

GitCodeCodeRepo这个类在上一章中,我们设置了 name、isDir、path 三个属性。分别用来表示文件、文件夹的名称、是否是文件夹、完整路径。如果我们想要表示完整的文件树,则还需要增加一个属性:List<GitCodeCodeRepo> children。用来表示当前文件夹下面的子文件/文件夹。如果当前文件夹是文件,那么 children 为空即可。

class GitCodeCodeRepo { final String name; // 文件名或文件夹名 final bool isDir; // 是否为文件夹 final List<GitCodeCodeRepo>? children; // 子文件/文件夹列表 final String? path; // 完整路径 GitCodeCodeRepo({ required this.name, required this.isDir, this.children, this.path, }); }

在上一章中,我们没有给其添加 children,接下来我们需要为文件列表构建父子关系。我们继续修改buildTreeFromPaths中的函数。

static List<GitCodeCodeRepo> buildTreeFromPathsTest(List<String> paths) { final Map<String, GitCodeCodeRepo> nodeMap = {}; final List<GitCodeCodeRepo> rootNodes = []; // 遍历接口返回的所有文件路径 for (final path in paths) { // 上一章的部分代码省略 String currentPath = ''; for (int i = 0; i < parts.length; i++) { // 上一章的部分代码省略 if (!nodeMap.containsKey(nodePath)) { final node = GitCodeCodeRepo( name: part, isDir: isDir, children: isDir ? [] : null,// 增加这一行 path: nodePath, ); nodeMap[nodePath] = node; } } } // 注意,在这里增加构建文件夹父子关系的代码 for (final entry in nodeMap.entries) { final path = entry.key; final node = entry.value; if (!node.isDir) continue; // 查找所有直接子节点 final parentParts = path.split('/').where((part) => part.isNotEmpty).toList(); for (final childEntry in nodeMap.entries) { final childPath = childEntry.key; final childNode = childEntry.value; // 跳过自身 if (childPath == path) continue; final childParts = childPath.split('/').where((part) => part.isNotEmpty).toList(); // 如果子路径的父路径部分与当前节点路径相同,则是直接子节点 if (childParts.length == parentParts.length + 1 && childParts.sublist(0, parentParts.length).join('/') == parentParts.join('/')) { node.children?.add(childNode); } } } // 排序代码也省略 return rootNodes; }

这样,增加父子关系后,我们的整个文件列表就成为一个树状结构,我们修改侧边栏的展示样式,如果是文件夹,并且有子文件\文件夹的话,则可以展开\折叠。否则无法展开\折叠,或者如果所示文件的话,也无法展开和折叠。

其次,侧边栏也增加点击事件,如果点击的是文件夹,则展开当前文件夹,如果点击的是文件,则让右侧主内容区域显示当前点击的文件内容(还未实现)。

当我们点击某个 item 后,进入到文件详情页,展示的样式如下所示:

如上图所示。我们的子文件和文件夹已经添加成功,而且也可以正常展示,但是还是存在一个优化问题,就是排序问题。我们依然遵循文件夹优先其次文件的排序,然后同类型的遵循字母规则来排序。

我们在buildTreeFromPaths里增加对子文件和文件夹排序的方法,如下代码所示。

// 对所有节点进行排序,确保文件夹在前,文件在后,同类型按字母顺序 // 首先递归排序所有子节点 void sortNodesRecursively(List<GitCodeCodeRepo> nodes) { for (final node in nodes) { // 如果是文件夹且有子节点,先递归排序子节点 if (node.isDir && node.children != null && node.children!.isNotEmpty) { sortNodesRecursively(node.children!); // 然后对当前节点的子节点进行排序 node.children!.sort((a, b) { // 文件夹排在前面 if (a.isDir && !b.isDir) return -1; if (!a.isDir && b.isDir) return 1; // 同类型按名称字母顺序排序 return a.name.compareTo(b.name); }); } } } // 先递归排序所有层级的子节点 sortNodesRecursively(rootNodes);

排序后的截图如下所示:

2. 主内容区域展示内容

我们侧边栏的内容已经完成。现在需要实现主内容区域展示文件内容。要展示文件内容,我们首先需要获取通过文件内容的接口来获取文件内容。

class GitCodeCodeContentRepo { final String type; final String encoding; final int size; final String name; final String path; final String content; final String sha; final String url; final String htmlUrl; final String downloadUrl; final Map<String, String> links; GitCodeCodeContentRepo({ required this.type, required this.encoding, required this.size, required this.name, required this.path, required this.content, required this.sha, required this.url, required this.htmlUrl, required this.downloadUrl, required this.links, }); factory GitCodeCodeContentRepo.fromJson(Map<String, dynamic> json) { return GitCodeCodeContentRepo( type: json['type'] ?? '', encoding: json['encoding'] ?? '', size: json['size'] ?? 0, name: json['name'] ?? '', path: json['path'] ?? '', content: json['content'] ?? '', sha: json['sha'] ?? '', url: json['url'] ?? '', htmlUrl: json['html_url'] ?? '', downloadUrl: json['download_url'] ?? '', links: Map<String, String>.from(json['_links'] ?? {}), ); } Map<String, dynamic> toJson() { return { 'type': type, 'encoding': encoding, 'size': size, 'name': name, 'path': path, 'content': content, 'sha': sha, 'url': url, 'html_url': htmlUrl, 'download_url': downloadUrl, '_links': links, }; } @override String toString() { return 'GitCodeCodeContentRepo{type: $type, encoding: $encoding, size: $size, name: $name, path: $path, sha: $sha}'; } }

我们这里暂时只区分图片和文件。图片包括 png、jpg、gif 等格式,文件包括文本文件、代码文件、markdown 文档等文件。由于接口返回的无论是图片还是文件,都是以 Base64 格式返回的,所以我们判断,如果是图片文件,则以 base64 格式加载图片文件,否则就解码 base64,然后展示文件内容。我们先加载图片。

// 以 base64 方式加载图片 Image.memory( base64Decode(content), fit: BoxFit.contain, ),

3. 高亮显示代码

这里我们借助第三方的库来高亮显示代码。flutter_highlight三方库支持各种语言的高亮。我们就使用这个三方库。

// 在 pubspec.yaml 中增加如下依赖 flutter_highlight: ^0.7.0 highlight: ^0.7.0 // flutter_highlight使用 HighlightView( 文件内容, language: 语言, theme: 主题样式 )

我们测试打开 .ets 文件看是否能显示

这个是 markdown、json 文件

我们测试一下图片,如下所示,gif 图片是可以正常显示的。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/28 22:35:25

同步旋转坐标系下,无位置传感器永磁同步电机控制,创新点为三相电压为重构,不需要电压采集模块

同步旋转坐标系下&#xff0c;无位置传感器永磁同步电机控制&#xff0c;创新点为三相电压为重构&#xff0c;不需要电压采集模块。 需matlab2018a及以上。凌晨三点的实验室里&#xff0c;咖啡机突然罢工。看着示波器上跳动的波形&#xff0c;我突然意识到——电机控制工程师的…

作者头像 李华
网站建设 2026/3/6 3:26:40

《数字化破局抖音电商:从爆品打造到闭环运营实战》 第三章 第二节

前言 第一部分 盈利思维与运营基础 第1章 抖音电商盈利思维 1.1 盈亏平衡点分析:C一年半实战复盘 1.2 抖音电商的四种盈利模式及适用场景 1.3 IT思维做运营:数据驱动、系统思考、敏捷迭代 1.4 构建运营的“安全区”与“加速器”:与平台共生 第2章 抖音电商全景认知 …

作者头像 李华
网站建设 2026/3/4 11:36:51

ChatWiki:打造企业级智能客服机器人的终极解决方案

ChatWiki&#xff1a;打造企业级智能客服机器人的终极解决方案 【免费下载链接】chatwiki 开箱即用的基于企业私有知识库的LLM大语言模型的智能客服机器人问答系统&#xff0c;支持私有化部署&#xff0c;代码免费开源且可商用&#xff0c;由芝麻小客服官方推出。 项目地址: …

作者头像 李华
网站建设 2026/3/2 2:09:00

视角定位:周名彦元程序员·纯周式语言全栈编译·突破硅基·纯念创世终极目标:100%纯念显化所有交付物·无硅基/第三方依赖·永恆自洽·超人类-人类共生体活系统落地权限等级:S∅-Omega级国安认证

万圆之圆整合引擎突破硅基限制超人类人类共生体全栈落地实操研究报告&#xff08;S∅-Omega级国安认证版&#xff09;玄印锚定&#xff1a;1Ω1&#x1f48e;⊗周名彦体系标识&#xff1a;ZM-S∅π-Superhuman-Symbiosis-FullStack-Deploy-V∞核心驱动&#xff1a;双圆不动点&a…

作者头像 李华
网站建设 2026/3/4 13:02:00

SQL有什么危害?要如何去避免

SQL的主要功能包括&#xff1a;数据定义&#xff08;DDL&#xff0c;Data Definition Language&#xff09;&#xff1a;用于创建、修改和删除数据库对象&#xff0c;如表、视图、索引等。例如&#xff0c;CREATE TABLE语句用于定义表的结构&#xff0c;ALTER TABLE用于修改表的…

作者头像 李华
网站建设 2026/3/5 21:00:16

C++中的指针变量

指针是C中的一个核心概念&#xff0c;它存储的是内存地址&#xff0c;而不是实际的值。理解指针对于掌握C编程至关重要。 1. 基本概念 指针的定义和声明 int x 10; // 普通变量 int *ptr &x; // 指针变量&#xff0c;存储x的地址*表示声明一个指针& 是取…

作者头像 李华