从零开始开发纯血鸿蒙应用之实现起始页

从零开始开发纯血鸿蒙应用

  • 一、前言
  • 二、主要页面
  • 三、应用起始页
  • 四、MainPageContent 实现
    • 1、一级结构
    • 2、二级结构
      • 2.1、EmptyContent
      • 2.2、FileListContent
        • 2.2.1、ViewAction:
        • 2.2.2、EditAction
        • 2.2.3、DeleteAction
        • 2.2.4、ShareAction
  • 五、载入起始页的时机
  • 五、总结

一、前言

从本篇开始,将对 TxtEdit 的业务功能进行逐一实现,而业务功能是宿主在一个个具体的应用页面上的,所以,当务之急,便是将 TxtEdit 的主要页面、即用于编辑和浏览纯文本文件的页面进行实现。

目前,第一版实现中,主要页面有如下几个:
在这里插入图片描述
像那些用于说明app开发者信息,以及进行问题反馈等页面,个人认为属于非关键的主要页面,因此,在应用开发过程中,其优先级较低,可以放在最后去实现。

二、主要页面

TxtEdit 在版本 1.0.x 的主要页面,共有三套:

  • 应用起始页,由一个 page 文件组成
  • 内部文件处理页,由两个 page 文件组成,分别用于编辑和浏览应用的沙箱文件
  • 外部文件处理页,也是两个 page 文件组成,用于浏览和导入。

三、应用起始页

应用起始页,由 Index.ets 文件实现,页面路由为 pages/Index,它的代码内容结构如下:
在这里插入图片描述
根据 build 函数体,可知 TxtEdit 的起始页,和众多app的起始页一样,都是采用 Tabs 组件进行页面结构搭建,我这里,由于追求简洁和实用,Tabs 里面的 TabContent 也即所谓 Tab 页,只有两个。

在鸿蒙UI中,Tabs 组件具有横向纵向两种方向,并且 tabBar 也即 Tab 页标题栏,允许传入一个注解 @Builder 的 UI 构建函数,从而实现更美观或更个性化的应用起始页,由于本人美术天赋较差,设计不出让人眼前一亮的 UI 样式,只有如下的简简单单的:

@Builder
tabBuilder(title: string, targetIndex: number) {Column() {Text(title).fontColor(this.currentIndex === targetIndex ? '#ff0af10a' : '#fff5f6f5')}.width('100%').height(60).justifyContent(FlexAlign.Center)
}

只做了根据Tab页是否被选中进行Tab标题颜色的变更。

为了达到 Tabs 组件居底布局,页面标题居顶布局,我将 Tabs 套在一个使用了 BottomColumn 样式的 Column 文件中,再将这个 Column 放在一个使用 RootTopColumn 样式的 Column 文件中。

TxtEdit 的起始页中的第一个 Tab 页,即文件 Tab 页,顾名思义,用于展示文件列表,方便用户进行内部文件的操作和管理,这时候,涉及到无内部文件和有内部文件两种状态的页面内容,要以什么样的方式进行载入?

方案不外乎两种,一种是在 TabContent 里面直接做条件渲染,根据条件使用不同的Content ,另一种是TabContent 里面使用一个直接展示的 Content,将条件渲染下移到该Content里面

本人采取的就是第二种方案:

build() {Column(){PageTitleBar({ title: 'TxtEdit'})Column(){Tabs(){TabContent(){Column(){MainPageContent()}.attributeModifier(this.centerColumn)}.tabBar(this.tabBuilder('文件', 0))TabContent(){AboutPageContent()}.tabBar(this.tabBuilder('关于', 1))}.attributeModifier(this.blackTabs).onChange((index) => {this.currentIndex = index})}.attributeModifier(this.bottomColumn)}.attributeModifier(this.rootContainer)
}

四、MainPageContent 实现

在我尚未叙述具体实现时,屏幕前的你,对于 MainPageContent 的实现,心里有什么样的方案?是否认为,用一个类似 if-else 的语法结构,就能够实现无文件页面和有文件页面的载入显示?

如果是这样,那么你大概没有考虑到,用户场景存在着一种情况,就是从有文件到无文件的状态回退。此外,实时的 UI 刷新,比如用户创建第一个文件结束后,回到起始页,应当将用户创建的文件展示在文件列表中,而不是要用户杀掉app进程重新进入才能看到。

总的来说,app页面的实现,并非是想当然而,需要将可能的动态刷新场景兜底住,才能给用户一个较好的UI体验和交互操作体验。

1、一级结构

本篇后续,以及后面的每一篇博文,为了控制篇幅,主要是内容字符数,源码会贴的比较少,更多以图片的形式展示,完整源码还请访问gitee仓库获取,当然了,gitCode仓库也是准备了的。

在这里插入图片描述
由简入繁,先看一下函数体都收起时的内容。整体上,在 MainPageContent 中,最开始的地方,定义了一组辅助 UI 刷新的私有字段或状态变量,其中,状态变量是触发 UI 刷新所不可或缺的。

在页面即将渲染时,也即生命周期函数 aboutToAppear 所对应的阶段,需要做一些初始化工作:
在这里插入图片描述
利用项目内部 API,即 FileUtil 去获取内部文件的文件名列表,并且根据列表的空与非空,决定最终渲染的内容是 EmptyContent 还是 FileListContent,我这里所采用的条件渲染控制,并非鸿蒙UI所支持的 if-else 语法,而是组件属性 visibility,如此做法,其考量就是让UI代码更纯粹些
在这里插入图片描述
为了满足实时刷新UI内容的需要,doRefresh 函数做了如下工作:
在这里插入图片描述
虽然,和 aboutToAppear 很像,却也是必不可少的,毕竟已经通过装饰器 @Watch 与 refresh 做了绑定,而 refresh 实际上是一个应用全局的UI状态存储 中的字段,利用应用全局的UI状态存储机制,可以做到在B页面控制A页面进行UI更新,具体用法后面会给出。

2、二级结构

MainPageContent 的二级结构,实际对应的就是 EmptyContent 和 FileListContent。鉴于 EmptyContent 的实现更为简单,所以分析顺序就从 EmptyContent 开始。
在这里插入图片描述

2.1、EmptyContent

在这里插入图片描述

如图所示,开始处也是一批字段的定义,其中的 dialog 字段实际是一个 自定义弹窗
在这里插入图片描述
通过代入 CustomDialogController 的参数 alignment,将弹窗设置为页面居中显示,这里需要提醒一下 DevEco Studio 的 UI 预览器和真机显示上,在自定义弹窗上的区别,预览器显示弹窗是默认居中的,但真机则不是如此;另一个带入 CustomDialogController 的参数,用于控制是否允许自动关闭弹窗,即点击弹窗外的区域时是否允许关闭弹窗,显然,我这里设置为不允许,因此,弹窗的关闭只能通过显示在弹窗上的两个按钮去进行:
在这里插入图片描述
这个弹窗的打开动作,我将它放在“新建或导入按钮”中。

2.2、FileListContent

在这里插入图片描述
FileListContent 的结构,与 EmptyContent 的结构很相似,只不过“新建或导入”按钮上方,变成了一个列表组件。列表组件的列表项,根据fileList也即内部文件名列表动态生成,每个列表项都是由 RecentFileItem 实现:
在这里插入图片描述
RecentFileItem 的实现如下:
在这里插入图片描述
其显示效果如图:
在这里插入图片描述
点击“操作”文本,会有弹出式菜单显示出来,该菜单提供四个操作:查看、编辑、分享和删除。弹出式菜单的使用,只需在鸿蒙UI组件的bindMenu传入菜单绘制方法即可,也就是这里的 OptionMenu 方法:
在这里插入图片描述
四个操作的响应逻辑,通过 RecentFileItem 的四个函数参数载入,每一个具体实现逻辑,下面一一介绍:

2.2.1、ViewAction:

在这里插入图片描述
该动作的含义,就是浏览当前列表项对应的沙箱文件,实现代码比较简单,就是将对应的沙箱文件名通过路由参数带入到 ViewFilePage 中。

2.2.2、EditAction

在这里插入图片描述
动作含义就是编辑当前列表项对应的沙箱文件,由于实现代码与 ViewAction 类似,便不过多赘述。

2.2.3、DeleteAction

在这里插入图片描述
动作含义就是删除当前列表项对应的沙箱文件,在实现方面,主要用项目内部 API FileUtil.deleteFile(this.ctx, item) 实现文件的删除,而在删除成功的回调处理中,会对 TxtEdit 的起始页进行 UI 更新,即当最后一个内部文件被删除时,起始页重新显示无文件对应的页面内容;否则仍旧显示文件列表

2.2.4、ShareAction

在这里插入图片描述
该动作的含义,就是分享当前列表项对应的沙箱文件,在具体实现方面,也是用了一个项目内部 API,其都对应的具体代码如下:
在这里插入图片描述
主要就是利用鸿蒙系统提供的系统分享面板进行文件的分享:
在这里插入图片描述
要呼出如上的系统分享面板,需要做以下几方面的工作:
1)判断要分享的文件是否存在,避免引起其他应用出现异常
2)获取待分享文件对应的 utdTypeId
3)借助 systemShare.SharedData 包装分享内容,因为系统分享面板只接受 systemShare.SharedData 的数据
4)创建并持有 systemShare.ShareController,即系统分享面板控制器
5)借助系统分享面板控制器拉起系统分享面板,并对是否成功拉起面板进行回调处理

五、载入起始页的时机

在鸿蒙应用开发框架中,应用起始页的载入时机为,应用声明周期函数 onWindowStageCreate
在这里插入图片描述
在该函数中,会通过系统 API windowStage.loadContent 去加载某个 Page 作为起始页,而这里就是 'pages/Index'

五、总结

正所谓台上一分钟台下十年功,看起来很简单的应用起始页,实现起来往往需要对多种动态刷新和操作交互进行处理,更需要保证页面间的数据流透传方向不出错、以及应用全局范围的信号起作用等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/503746.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Pytorch初学

创建虚拟环境 python控制台,jupyter notebook,python文件运行的差异,后续结合使用三者。 jupter主要可以对代码进行分割单独运行,主要做一些探索性工作。 数据集的常见存储模式 1、以标签命名图像。 2、单独存储图像的地址。 加载数据集…

Anthropic 的人工智能 Claude 表现优于 ChatGPT

在人工智能领域,竞争一直激烈,尤其是在自然语言处理(NLP)技术的发展中,多个公司都在争夺市场的主导地位。OpenAI的ChatGPT和Anthropic的Claude是目前最具影响力的两款对话型AI产品,它们都能够理解并生成自然…

【Linux系列】并发与顺序执行:在 Linux 脚本中的应用与选择

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

更换WordPress主题的基础知识及注意事项

更换WordPress主题是优化和升级网站的重要步骤,不仅能够增强网站的视觉效果,还能改进用户体验并提高网站性能。然而,在进行该操作时,必须格外谨慎,避免数据丢失或功能失调的风险。本文将介绍在更换主题前需要采取的基本…

conda指定路径安装虚拟python环境

DataBall 助力快速掌握数据集的信息和使用方式,会员享有 百种数据集,持续增加中。 需要更多数据资源和技术解决方案,知识星球: “DataBall - X 数据球(free)” -------------------------------------------------------------…

HTML 迷宫游戏

HTML 迷宫游戏 相关资源文件已经打包成压缩文件,可双击index.html直接运行程序,且文章末尾已附上相关源码,以供大家学习交流,博主主页还有更多Python相关程序案例,秉着开源精神的想法,望大家喜欢&#xff0…

PDFMathTranslate: Star13.8k,一款基于AI的PDF文档全文双语翻译PDF文档全文双语翻译,保留格式神器,你应该需要它

嗨,大家好,我是小华同学,关注我们获得“最新、最全、最优质”开源项目和高效工作学习方法 PDFMathTranslate是一个开源项目,旨在为用户提供便捷的PDF科学论文翻译解决方案。它不仅能够翻译文本,还能保留公式、图表、目…

调整Python+Pytest+Allure+Yaml+Pymysql框架中需要执行的用例顺序

当pytest框架中有时时候会因为用例的前后关联关系需要调整用例执行顺序时则可以跟进具体的要求调整pytest.ini配置文件中执行用例文件夹的前后顺序 当如果是需要调整某个文件夹中用例的执行顺序时,则跟进具体的文件调整对应testcases中test_*.py文件中的执行顺序

毕业项目推荐:基于yolov8/yolov5/yolo11的动物检测识别系统(python+卷积神经网络)

文章目录 概要一、整体资源介绍技术要点功能展示:功能1 支持单张图片识别功能2 支持遍历文件夹识别功能3 支持识别视频文件功能4 支持摄像头识别功能5 支持结果文件导出(xls格式)功能6 支持切换检测到的目标查看 二、数据集三、算法介绍1. YO…

BloombergGPT: A Large Language Model for Finance——面向金融领域的大语言模型

这篇文章介绍了BloombergGPT,一个专门为金融领域设计的大语言模型(LLM)。以下是文章的主要内容总结: 背景与动机: 大语言模型(如GPT-3)在多个任务上表现出色,但尚未有针对金融领域的…

CS·GO搬砖流程详细版

说简单点,就是Steam买了然后BUFF上卖,或许大家都知道这点,但就是一些操作和细节问题没那么明白。我相信,你看完这篇文章以后,至少会有新的认知。 好吧,废话少说,直接上实操! 首先准…

(六)CAN总线通讯

文章目录 CAN总线回环测试第一种基于板载CAN测试第一步确认板载是否支持第二步关闭 CAN 接口将 CAN 接口置于非活动状态第三步 配置 CAN 接口第一步 设置 CAN 接口比特率第二步 设置 CAN 启用回环模式第三步 启用 CAN 接口 第四步 测试CAN总线回环捕获 CAN 消息发送 CAN 消息 第…

【微服务】4、服务保护

微服务架构与组件介绍 单体架构拆分:黑马商城早期为单体架构,后拆分为微服务架构。跨服务调用与组件使用 服务拆分后存在跨服务远程调用,如下单需查询商品信息,使用openfeign组件解决。服务间调用关系复杂,需维护服务…

SQL从入门到实战

学前须知 sqlzoo数据介绍 world nobel covid ge game、goal、eteam teacher、dept movie、casting、actor 基础语句 select&from SELECT from WORLD Tutorial - SQLZoo 基础查询select单列&多列&所有列&别名应用 例题一 SELECT name, continent, population …

QML学习(八) Quick中的基础组件:Item,Rectangle,MouseArea说明及使用场景和使用方法

上一篇中我们从设计器里可以看到Qt Quick-Base中有几大基础组件,如下图,这篇文章先介绍下Item,Rectangle,MouseArea这三个的说明及使用场景和使用方法 Item Item 是 QML 中所有可视元素的基类,是一个非常基础和通用的…

设计模式(1)——面向对象和面向过程,封装、继承和多态

文章目录 一、day11. 什么是面向对象2. 面向对象的三要素:继承、封装和多态2.1 封装**2.1.1 封装的概念****2.1.2 如何实现封装****2.1.3 封装的底层实现**2.1.4 为什么使用封装?(好处)**2.1.5 封装只有类能做吗?结构体…

Java到底是值传递还是引用传递????

在搞懂这个问题之前, 我们要首先了解什么是值传递, 什么是引用传递? 值传递: 传递的是数据的副本,修改副本不会影响原始数据。引用传递: 传递的是数据的引用(地址),修改引用会直接影响原始数据. 也就是说,值传递和引…

VLMs之Agent之CogAgent:《CogAgent: A Visual Language Model for GUI Agents》翻译与解读

VLMs之Agent之CogAgent:《CogAgent: A Visual Language Model for GUI Agents》翻译与解读 导读:这篇论文介绍了CogAgent,一个专注于图形用户界面 (GUI) 理解和导航的视觉语言模型 (VLM)。这篇论文提出了一种新的视觉语言模型 CogAgent&#…

23.行号没有了怎么办 滚动条没有了怎么办 C#例子

新建了一个C#项目,发现行号没有了。 想把行号调出来,打开项目,选择工具>选项> 如下图,在文本编辑器的C#里有一个行号,打开就可以了 滚动条在这里:

Element-plus表单总结

表单包含输入框,单选框,下拉选择,多选框等用户输入的组件。输入表单,您可以收集、验证和提交数据。 经典表单 最基础的表单包括各种输入表单项,比如input、select、radio、checkbox等。 在每一个form组件中&#xff0…