从零开始开发纯血鸿蒙应用之UI封装

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

  • 一、题引
  • 二、UI 组成
  • 三、UI 封装原则
  • 四、实现 lib_comps
    • 1、封装 UI 样式
      • 1.1、attributeModifier 属性
      • 1.2、自定义`AttributeModifier<T>`类
    • 2、封装 UI 组件
  • 五、总结

一、题引

在开始正文前,为了大家能够从本篇博文中,汲取到代码外的东西,即编程思想,我想问问每一个屏幕前的读者,一个问题,那就是:所谓UI,在你看来,可以划分成哪些组成?

二、UI 组成

UI,即 User Interface,译为用户界面,是一个应用提供给用户直接进行查看和操作的内容。
虽然,还不知道大家脑海中对于UI组成,都有什么样的看法?但我这里需要说的是,我认为一个合格的UI,当是由结构样式响应有机组合成的,而合格的UI封装也应该就此进行。

UI 实际上就像大家日常生活中居住的房子,一个住起来感到惬意的房间,必然先后经历房壳子和装潢后的房间,这两个截然不同的阶段;在装潢阶段,房间的墙壁或被贴上墙纸、或被刷上墙漆,墙壁上的某些位置上出现的各种插座、开关面板,则是早在搭建房壳子的时候一并完成的,然而它们实际会控制什么样的电器,则是在装潢阶段进行的。

三、UI 封装原则

再问大家一个问题:进行UI公共组件的封装时,是习惯于将结构、样式和响应,杂糅在一起进行封装,还是采用粒度更细化的方式进行呢?

我进行UI封装时,会有一个很明确的行为准则:单一职能原则,一个封装实现体(class或struct),应该只承担粒度从小到大顺序中的某一个职能,比如只负责确定结构、或只负责确定样式。
当然了,前提是所使用的UI开发框架支持相应的粒度抽取。

就鸿蒙应用SDK来说,最新版本的API里,样式已经允许与结构、响应独立,封装在不同的ets文件中,具体如何实现,后文细说;而对于结构和响应,就像造房子一样,墙壁上开关面板的走线管道,只能在墙壁完整造出来前布置好,UI结构封装时必须预留响应的载入通道,通常就是允许传入一个函数

四、实现 lib_comps

现在,开始对工程里面的 lib_comps 模块进行实现,先看一下该模块下的目录结构:
lib_comps模块目录结构
在 ets 源码目录下,我细分出 componentsstyle两个子目录,前者负责UI结构和响应载入通道的封装,后者负责UI样式的封装。

1、封装 UI 样式

进行网页实现的时候,大家经常会用到类似如下的代码:

<div class="container"><p class="normal-text">文本</p>
</div>

html 标签的 class 属性,用于将提前封装在CSS文件中的各种样式进行载入的位置,只有这样,才可能进行样式的独立封装。现在,我可以明确地告诉大家,鸿蒙API 12 之后也能如此进行了:
在这里插入图片描述

1.1、attributeModifier 属性

在我看来,该属性是相当重要而有用的,它让鸿蒙 UI 实现的灵活度得到了进一步的增强。
在这里插入图片描述
虽然,官方将其解释为“动态设置组件的属性方法”,但我却更愿意将其看待成鸿蒙组件的class属性,因为,在鸿蒙UI实现中,组件样式也是通过属性方法进行设置的,比如下面:

Row(){Text(this.fileName.split(".")[0]).fontSize(25).fontWeight(FontWeight.Regular)Text(this.fileName.split(".")[1]).fontSize(20).fontWeight(FontWeight.Lighter)Text('操作').fontSize(25).fontWeight(FontWeight.Regular).bindMenu(this.OptionMenu())}.width("100%").height("10%").alignItems(VerticalAlign.Center).justifyContent(FlexAlign.SpaceBetween)

那么,传入 attributeModifier 属性里面的自定义AttributeModifier<T>类里面,只设置样式相关的属性,那么,实际上对应的自定义AttributeModifier<T>类就相当是一个css了。

1.2、自定义AttributeModifier<T>

实现时,要与目标组件的类型相一致,也就是说,如果是要为 column 组件的 attributeModifier 属性赋值,那么泛类型 T 对应的具体类型就是 ColumnAttribute。

通常,应用里面使用的 column 样式不会只有一种,所以,不妨把所有适用于 column 的样式封装,都放在同一份 ets 文件中,从而就有了前面 lib_comps 工程目录结构图里面的 ColumnStyles.ets 文件。

下面,以 RootTopColumn 类为例,讲解如何进行自定义AttributeModifier<T>类的封装:

export class RootTopColumn implements AttributeModifier<ColumnAttribute> {private columnColor: ResourceColor;constructor(columnColor: ResourceColor) {this.columnColor = columnColor;}applyNormalAttribute(instance: ColumnAttribute): void {instance.width("100%").height("100%").backgroundColor(this.columnColor).alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Start)}applyPressedAttribute(instance: ColumnAttribute): void {}applyFocusedAttribute(instance: ColumnAttribute): void {}applyDisabledAttribute(instance: ColumnAttribute): void {}applySelectedAttribute(instance: ColumnAttribute): void {}}

首先,自定义AttributeModifier<T>类和普通类一样,可以定义字段并通过构造函数进行初始化或赋值;其次,可以一次性封装5种不同的样式,用以针对组件的普通状态、按下状态、获焦状态、不可用状态和选择状态,不同的状态样式由各自对应的 applyXXXXAttribute 方法实现,这些方法统一接受一个 T 类型参数,对于 Column 组件来说,就是 ColumnAttribute;最后,在具体渲染时调用哪一个 applyXXXXAttribute 方法,由 UI 渲染引擎自行判断,开发者无需关心。

实现每个具体的 applyXXXXAttribute 方法时,可以从样式的如下几方面进行:

  • 尺寸:width 属性和 height 属性
  • 颜色:背景色 backgroundColor 属性,前景色foregroundColor属性
  • 对齐方式:alignItem 属性和 justifyContent 属性
  • 边距:外边距 margin 属性和内边距 padding 属性
  • 边框:boder 属性

当然了,鸿蒙 UI 组件支持的样式属性绝不止这些,只不过上面这些是比较常用的,基本足够应付大多数UI实现所需的样式了。

当对应的 自定义AttributeModifier<T>类,需要用在最外层的容器上,那么尺寸就应该是与屏幕尺寸相同,这里的 RootTopColumn 就是这样的,所以,我才会在 applyNormalAttribute 函数中,将尺寸都设置为百分百;同时,因为预期布局方式是水平居中、垂直局始,所以,只剩下背景色需要通过类构造函数进行传入。

2、封装 UI 组件

由于,鸿蒙API中,UI 结构和响应,没办法彻底解耦,所以,结构和响应就没有按照彻底独立的方式进行封装,而是直接上升到组件维度进行封装。

在组件中,按钮和对话框应该算得上是使用频率很高的组件了,所以,有必要为此封装相应的公共组件,以黑色背景的按钮来说,可以用类似如下的代码进行封装:

@Component
export struct BlackBtn {private buttonWidth: Length = "75%"private buttonHeight: Length = 55@Prop @Require text: ResourceStr = ""private textSize: string | number | Resource = 20private action?: () => void = () => {}private btnStyle: BlackButton = new BlackButton(this.buttonWidth, this.buttonHeight)build() {Button() {Text(this.text).WhiteText(this.textSize)}.attributeModifier(this.btnStyle).onClick(this.action)}
}

在鸿蒙UI中,所有的组件都是用注解了 Component 的 struct 体承担实现,并且该 struct 体中必须实现 build 方法,具体的 UI 内容实现放在 build 方法里,build 方法里不允许使用非UI表达式,除了少数允许的条件表达式外的一切逻辑表达式,都不允许直接放在 build 方法体里面。

由于注解了 Component 的 struct 体,跟类一样,允许从外部传入参数,所以,具体的内容和样式参数,都可以从外部传入;当然了,也可以为它们都设置初始化值;如果某个属性值必须要外部传入,可以在相应的字段前用 Require 注解。

对话框的封装,也是差不多的形式:
在这里插入图片描述
从上面的代码可以看出,封装UI组件的时候,可以根据内容的多寡,决定是否继续划分出更小的组件。

五、总结

受限于篇幅,我这里并没有将 lib_comps 模块的全部实现代码贴出来,大家不妨前往lib_comps仓库,查看具体的实现代码。

总而言之,在封装UI的时候,应当在遵循单一职能的基础上,按粒度从小到大的形式进行内容拆分和实现,一块砖一块砖地码,万里长城才能码得稳、码得好!

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

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

相关文章

使用ArcGIS Pro自带的Notebook计算多个遥感指数

在之前的分享中&#xff0c;我们介绍了如何使用ArcPy将GEE下载的遥感影像转为单波段文件。基于前面创建的单波段文件&#xff0c;我们可以一次性计算多种遥感指数&#xff0c;例如NDVI、EVI、NDSI等。我这里直接在ArcGIS Pro中自带的Notebook进行的运行。如下图所示&#xff0c…

超大规模分类(一):噪声对比估计(Noise Contrastive Estimation, NCE)

NCE损失对应的论文为《A fast and simple algorithm for training neural probabilistic language models》&#xff0c;发表于2012年的ICML会议。 背景 在2012年&#xff0c;语言模型一般采用n-gram的方法&#xff0c;统计单词/上下文间的共现关系&#xff0c;比神经概率语言…

275-增强型多功能数据采集卡PCIe-6251-EX

产品特点&#xff1a; 高速高精度数据采集&#xff0c;16bit10MSPS&#xff0c;32路单端/16路差分高速高精度任意波形发生&#xff0c;14bit165MHz&#xff0c;2路完全独立完全可编程的I/O端口&#xff0c;33个完全可编程的量程选择&#xff0c;0~5V/0~10V/5V/10VPCIe通信接口…

Llama 3 后训练(三)

目录 4. 后训练 4.1 建模 图表解读 4.1.1 聊天对话格式 4.1.2 奖励建模 4.1.3 监督微调&#xff08;Supervised Finetuning&#xff09; 4.1.4 直接偏好优化&#xff08;Direct Preference Optimization&#xff09; 4.1.5 模型平均&#xff08;Model Averaging&#x…

机器人C++开源库The Robotics Library (RL)使用手册(四)

建立自己的机器人3D模型和运动学模型 这里以国产机器人天机TR8为例,使用最普遍的DH运动学模型,结合RL所需的描述文件,进行生成。 最终,需要的有两个文件,一个是.wrl三维模型描述文件;一个是.xml运动学模型描述文件。 1、通过STEP/STP三维文件生成wrl三维文件 机器人的…

Go+chromedp实现Web UI自动化测试

1.为什么使用go进行UI自动化测试&#xff1f; 速度&#xff1a;Go速度很快&#xff0c;这在运行包含数百个UI测试的测试套件时是一个巨大的优势 并发性&#xff1a;可以利用Go的内置并发性(goroutines)来并行化测试执行 简单&#xff1a;Go的简约语法允许您编写可读且可维护…

【LLM综述】29种大模型Prompt Engineering技术

note 从零样本&#xff08;Zero-shot&#xff09;提示到最新进展的各种提示技术&#xff0c;包括推理和逻辑链&#xff08;Chain-of-Thought, CoT&#xff09;提示、自动链式思考&#xff08;Auto-CoT&#xff09;提示、自我一致性&#xff08;Self-Consistency&#xff09;提…

基于SpringBoot的实验室信息管理系统【源码+文档+部署讲解】

系统介绍 视频演示 基于SpringBootVue实现的实验室信息管理系统采用前后端分离的架构方式&#xff0c;系统分为管理员、老师、用户三种角色&#xff0c;实现了用户管理、设备管理、实验室查询、公告、课程、实验室耗材管理、我的等功能 技术选型 开发工具&#xff1a;idea2…

arcgis模版空库怎么用(一)

这里以某个项目的数据为例&#xff1a; 可以看到&#xff0c;属性表中全部只有列标题&#xff0c;无数据内容 可能有些人会认为空库是用来往里面加入信息的&#xff0c;其实不是&#xff0c;正确的用法如下&#xff1a; 一、下图是我演示用的数据&#xff0c;我们可以看到其中…

基于Spring Boot + Vue3实现的在线汽车保养维修预约管理系统源码+文档

前言 基于Spring Boot Vue3实现的在线汽车保养维修预约管理系统是一种前后端分离架构的应用&#xff0c;它结合了Java后端开发框架Spring Boot和现代JavaScript前端框架Vue.js 3.0的优势。这样的系统可以为汽车服务站提供一个高效的平台来管理客户的预约请求 技术选型 系统…

论文研读:Text2Video-Zero 无需微调,仅改动<文生图模型>推理函数实现文生视频(Arxiv 2023-03-23)

论文名&#xff1a;Text2Video-Zero: Text-to-Image Diffusion Models are Zero-Shot Video Generators 1. 摘要 1.1 方法总结 通过潜空间插值, 实现动作连续帧。 以第一帧为锚定&#xff0c;替换原模型的self-attention&#xff0c;改为cross-attention 实现 保证图片整体场…

AI安全的挑战:如何让人工智能变得更加可信

引言 随着人工智能&#xff08;AI&#xff09;技术在各个领域的广泛应用&#xff0c;尤其是在医疗、金融、自动驾驶和智能制造等行业&#xff0c;AI正在重塑我们的工作和生活方式。从提高生产效率到实现个性化服务&#xff0c;AI带来了前所未有的便利。然而&#xff0c;在享受这…

去除el-tabs 下面的灰色横线,并修改每一项的左右间距,和字体颜色

HTML <el-tabs v-model"activeName" class"demo-tabs" tab-click"handleClick"><el-tab-pane label"全部" :name"null"></el-tab-pane><el-tab-pane label"问答陪练" name"general-t…

Selenium和WebDriver的安装与配置

1、Selenium的安装 直接黑窗口执行&#xff1a;pip install selenium3.141.0 可能遇到的问题&#xff1a; 解决方法配置环境变量&#xff1a; 找到目录&#xff1a;&#xff08;以自己电脑为准&#xff09; C:\Users\Administrator\AppData\Local\Programs\Python\Python38-…

HTML——45.单元格合并

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>表格</title></head><body><!--合并单元格&#xff1a;1.在代码中找到要合并的单元格2.在要合并的所有单元格中&#xff0c;保留要合并的第一个单元格…

APP项目测试 之 APP性能测试-- 性能测试工具(SoloPi工具)

1.SoloPi简介 &#xff08;1&#xff09;什么是SoloPi&#xff1f; SoloPi&#xff1a; 是一个无线化、非侵入式的 Android 自动化工具 &#xff0c;具备 录制回放、性能测试 等功能。 &#xff08;2&#xff09;SoloPi的作用是什么&#xff1f; 基础性能测试&#xff1a;能够…

IOS safari 播放 mp4 遇到的坎儿

起因 事情的起因是调试 IOS 手机下播放服务器接口返回的 mp4 文件流失败。对于没调试过移动端和 Safari 的我来说着实费了些功夫&#xff0c;网上和AI也没有讲明白。好在最终大概理清楚了&#xff0c;在这里整理出来供有缘人参考。 问题 因为直接用 IOS 手机的浏览器打开页面…

Mac 环境 VVenC 编译与编码命令行工具使用教程

VVenC VVenC 是一个开源的高效视频编码器&#xff0c;专门用于支持 H.266/VVC (Versatile Video Coding) 标准的编码。H.266/VVC 是继 HEVC (H.265) 之后的新一代视频编码标准&#xff0c;主要目的是提供比 HEVC 更高的压缩效率&#xff0c;同时保持或提高视频质量。H.266/VVC…

手搓一个ChatUI需要分几步

只关注项目代码的同学可以直接跳转目录中的正文部分&#xff0c;查看项目仓库和功能介绍。 引言 Chatbot的UI界面设计&#xff0c;是和传统软件不同的&#xff1a;都是当面一个简洁的对话框&#xff0c;框里预备着热乎的工具&#xff0c;可以随时更新。 像我这样做工的牛马&a…

018-spring-基于aop的事务控制

1 先配置平台事务管理器 2 在配置 spring提供的advice 3 事务增强的aop 总结&#xff1a; 事务就是要做2个配置&#xff1a; <!-- 1 开启事务管理器 不同的框架对应不同的事务管理器 --> <bean id"transactionManager" class"org.springframework.j…