HarmonyOS 校园应用系列之ArkTS 表单工程:打印文件创建页的受控组件与分组卡片实践

发布时间:2026/11/5 11:30:42

HarmonyOS 校园应用系列之ArkTS 表单工程:打印文件创建页的受控组件与分组卡片实践 HarmonyOS 校园应用系列之ArkTS 表单工程打印文件创建页的受控组件与分组卡片实践一、页面定位与功能概述文件创建页Func1Tab是校园打印 App 的数据录入中心——用户在此创建打印任务填写标题、描述、选择打印类型和优先级。页面标题为创建副标题填写信息快速创建明确了单一职责。本页是纯粹的数据录入型页面——包含 TextInput、TextArea、Toggle 等多种受控表单组件是学习 ArkUI 表单开发的最佳实战案例。页面采用Section 分组卡片布局每个功能区用白色圆角卡片包裹卡片间距 14vpColumn({ space: 14 })。1.1 页面状态定义State inputTitle: string // 文档标题 State inputDesc: string // 详细描述 State selectedType: number 0 // 选中的类型索引 State selectedPriority: number 1 // 优先级0低, 1中, 2高 State remindOn: boolean true // 提醒通知开关5 个State变量覆盖所有输入维度。selectedType和selectedPriority使用 number 类型作为数组索引比 string 类型更语义化。项目源码开源https://gitee.com/codenestFlow/HarmonyOSHub二、页面头部 —— 标题 操作按钮Builder Header() { Row({ space: 12 }) { Column({ space: 2 }) { Text(创建).fontSize(20).fontWeight(FontWeight.Bold).fontColor(C.text) Text(填写信息快速创建).fontSize(10).fontColor(C.textDim) }.alignItems(HorizontalAlign.Start) Blank() Row() { Text().fontSize(18) } .width(36).height(36).backgroundColor(C.cardSoft).borderRadius(D.rSm).justifyContent(FlexAlign.Center) } .width(100%).height(this.safeTop 60) .padding({ top: this.safeTop, left: D.pad, right: D.pad }) .backgroundColor(C.card).alignItems(VerticalAlign.Bottom) .border({ width: { bottom: 1 }, color: C.stroke }) }头部是主标题副标题双行结构左侧 20vp 加粗创建与 10vp 灰色副标题填写信息快速创建纵向排列明确页面单一职责。右侧是 emoji 图标放在C.cardSoft底、D.rSm圆角的 36×36 方块中暗示可从剪贴板粘贴文档信息这是降低输入成本的典型策略。头部高度safeTop 60配合alignItems(VerticalAlign.Bottom)让内容沉底对齐底部 1vpC.stroke分隔线与白底C.card构成通栏吸顶效果。三、FormCard —— 基本信息录入区Builder FormCard() { Column({ space: 12 }) { Row() { Text(基本信息).fontSize(15).fontWeight(FontWeight.Bold).fontColor(C.text) Blank() Text(✕).fontSize(16).fontColor(C.textDim) }.width(100%) Column({ space: 6 }) { Text(标题).fontSize(12).fontColor(C.textSub) TextInput({ placeholder: 请输入标题, text: this.inputTitle }) .onChange((v: string) { this.inputTitle v; }) .height(44).backgroundColor(C.cardSoft).borderRadius(D.rSm).placeholderColor(C.textDim) }.alignItems(HorizontalAlign.Start).width(100%) Column({ space: 6 }) { Text(描述).fontSize(12).fontColor(C.textSub) TextArea({ placeholder: 请输入详细描述..., text: this.inputDesc }) .onChange((v: string) { this.inputDesc v; }) .height(90).backgroundColor(C.cardSoft).borderRadius(D.rSm).placeholderColor(C.textDim) }.alignItems(HorizontalAlign.Start).width(100%) Row({ space: 8 }) { Text( 图片).fontSize(12).fontColor(C.textSub) .padding({ left: 10, right: 10, top: 6, bottom: 6 }) .backgroundColor(C.cardSoft).borderRadius(D.rSm) Text( 链接).fontSize(12).fontColor(C.textSub) .padding({ left: 10, right: 10, top: 6, bottom: 6 }) .backgroundColor(C.cardSoft).borderRadius(D.rSm) Blank() Text(${this.inputTitle.length}/50).fontSize(10).fontColor(C.textDim) }.width(100%) } .width(100%).padding(14).backgroundColor(C.card).borderRadius(D.rMd) .border({ width: 1, color: C.stroke }) }3.1 TextInput vs TextArea 对比特性TextInputTextArea适用场景单行短文本标题多行长文本描述默认行为Enter 不换行Enter 换行高度固定 44vp固定 90vp两者共享相同样式体系D.rSm圆角 10vp、C.cardSoft浅灰背景保持视觉一致性。3.2 受控组件双向绑定模式TextInput({ placeholder: 请输入标题, text: this.inputTitle }) // ① 外部传入当前值 .onChange((v: string) { // ② 用户输入时回调 this.inputTitle v // ③ 更新状态变量触发重渲染 })这是 ArkUI 标准的受控组件模式—— UI 显示完全由状态决定不存在显示值和存储值不一致的问题。在表单校验、重置、回填场景中尤为关键。3.3 实时字数统计${this.inputTitle.length}/50展示标题输入框的实时字数——即时反馈让用户每输入一个字符就看到变化分母 50 隐式传达上限。接近或超限时可将数字变为橙色/红色警告。3.4 附件按钮设计图片和链接按钮使用emoji 图标文字色块组合 图片、 链接浅灰背景C.cardSoft像可点击的标签Tag Button比纯文字或纯图标更醒目。四、TypeCard —— 图标化四选一类型选择器Builder TypeCard() { Column({ space: 12 }) { Text(选择类型).fontSize(15).fontWeight(FontWeight.Bold).fontColor(C.text).width(100%) Row() { ForEach(this.types, (item: OptionItem, idx: number) { Column({ space: 6 }) { Row() { Text(item.icon).fontSize(24) } .width(48).height(48).borderRadius(D.rMd).justifyContent(FlexAlign.Center) .backgroundColor(this.selectedType idx ? C.primarySoft : C.cardSoft) .border({ width: this.selectedType idx ? 2 : 0, color: C.primary }) Text(item.name).fontSize(10) .fontColor(this.selectedType idx ? C.primary : C.textDim) .fontWeight(this.selectedType idx ? FontWeight.Bold : FontWeight.Normal) }.layoutWeight(1) .onClick(() { this.selectedType idx; }) }, (item: OptionItem) item.name) }.width(100%) } .width(100%).padding(14).backgroundColor(C.card).borderRadius(D.rMd) .border({ width: 1, color: C.stroke }) }4.1 选中态的四重同步变化选中某类型时同时发生4 个视觉属性变化属性未选中选中图标背景色浅灰C.cardSoft浅绿C.primarySoft色块强调图标边框0vp2vp 绿色描边文字颜色灰C.textDim绿C.primary文字高亮文字字重NormalBold加粗强化图标是 emojiText 类型一 / 类型二 / ⭐ 类型三 / 类型四放在 48×48、D.rMd圆角的方块中。多重信号叠加的效果远超单一属性切换——即使不看文字仅凭色块边框就能识别选中项。4.2 为什么不用 Radio 组件标准 Radio 只能显示圆形选择器无法展示业务图标需要横向一行四列排列而非垂直列表选中态需要使用主题绿色。当标准组件无法满足需求时用基础组件组合自定义是合理的选择。五、PriorityCard —— 三档优先级Builder PriorityCard() { Column({ space: 12 }) { Row() { Text(优先级).fontSize(15).fontWeight(FontWeight.Bold).fontColor(C.text) Blank() Text(this.priorities[this.selectedPriority]).fontSize(13).fontColor(C.primary).fontWeight(FontWeight.Bold) }.width(100%) Row({ space: 6 }) { ForEach(this.priorities, (p: string, idx: number) { Text(p).fontSize(13) .fontColor(this.selectedPriority idx ? #FFFFFF : C.textSub) .backgroundColor(this.selectedPriority idx ? (idx 2 ? C.danger : idx 1 ? C.warn : C.ok) : C.cardSoft) .borderRadius(D.rSm).padding({ left: 16, right: 16, top: 8, bottom: 8 }) .onClick(() { this.selectedPriority idx; }) }, (p: string) p) }.width(100%) } .width(100%).padding(14).backgroundColor(C.card).borderRadius(D.rMd) .border({ width: 1, color: C.stroke }) }5.1 当前值回显卡片标题行右侧用Text(this.priorities[this.selectedPriority])实时回显当前选中的优先级绿色加粗用户无需扫视下方按钮即可确认当前状态。5.2 交通灯色彩语义优先级色值含义低C.ok#2BB673绿色冷静、不紧急中C.warn#FF9F1C琥珀注意、默认推荐高C.danger#FF5A6E红色紧急、立即关注选中项填充对应语义色 白字未选中项统一为C.cardSoft浅灰底 C.textSub灰字。默认值selectedPriority 1即中档大多数用户会接受默认选项以减少决策成本。六、SettingCard —— Toggle 开关与设置项Builder SettingCard() { Column({ space: 0 }) { Row({ space: 12 }) { Row() { Text().fontSize(16) } .width(32).height(32).backgroundColor(C.cardSoft).borderRadius(D.rSm).justifyContent(FlexAlign.Center) Column({ space: 2 }) { Text(提醒通知).fontSize(14).fontColor(C.text) Text(开启后将推送提醒).fontSize(11).fontColor(C.textDim) }.alignItems(HorizontalAlign.Start).layoutWeight(1) Toggle({ type: ToggleType.Switch, isOn: this.remindOn }) .selectedColor(C.primary) .onChange((on: boolean) { this.remindOn on; }) }.width(100%).padding({ top: 12, bottom: 12 }) Divider().color(C.stroke) Row({ space: 12 }) { Row() { Text().fontSize(16) } .width(32).height(32).backgroundColor(C.cardSoft).borderRadius(D.rSm).justifyContent(FlexAlign.Center) Column({ space: 2 }) { Text(隐私设置).fontSize(14).fontColor(C.text) Text(仅自己可见).fontSize(11).fontColor(C.textDim) }.alignItems(HorizontalAlign.Start).layoutWeight(1) Text(›).fontSize(22).fontColor(C.textDim) }.width(100%).padding({ top: 12, bottom: 12 }) } .width(100%).padding({ left: 14, right: 14 }).backgroundColor(C.card).borderRadius(D.rMd) .border({ width: 1, color: C.stroke }) }提醒开关使用系统Toggle组件ToggleType.Switch滑动开关isOn绑定remindOn状态.selectedColor(C.primary)让开启态轨道为主题绿。图标是 emojiText()放在 32×32 浅灰方块中。卡片下半部分是隐私设置跳转项 图标 ›箭头中间用Divider().color(C.stroke)分隔——开关项与跳转项合并在同一张卡片是设置页的经典分组手法。HarmonyOS 提供三种 Toggle 类型SwitchiOS 风格滑动开关、Checkbox复选框、Button独立切换按钮。开/关二态用 Toggle 更直观多选用 Checkbox 更语义准确。提醒通知明显是二态开关。七、TemplateCard 与 SubmitBtn —— 快捷模板与提交按钮Builder TemplateCard() { Column({ space: 10 }) { Text(快捷模板).fontSize(15).fontWeight(FontWeight.Bold).fontColor(C.text).width(100%) ForEach(this.templates, (item: QuickTemplate) { Row({ space: 10 }) { Row() { Text().fontSize(18) } .width(32).height(32).backgroundColor(C.primarySoft).borderRadius(D.rSm).justifyContent(FlexAlign.Center) Column({ space: 2 }) { Text(item.title).fontSize(13).fontWeight(FontWeight.Medium).fontColor(C.text) Text(item.desc).fontSize(10).fontColor(C.textDim) }.alignItems(HorizontalAlign.Start).layoutWeight(1) Text(›).fontSize(18).fontColor(C.textDim) }.width(100%) .onClick(() { promptAction.showToast({ message: item.title }); }) }, (item: QuickTemplate) item.title) } .width(100%).padding(14).backgroundColor(C.card).borderRadius(D.rMd) .border({ width: 1, color: C.stroke }) } Builder SubmitBtn() { Column({ space: 8 }) { Button(this.inputTitle.length 0 ? ✓ 提交创建 : 请填写标题) .width(100%).height(48) .backgroundColor(this.inputTitle.length 0 ? C.primary : C.cardSoft).fontColor(#FFFFFF) .fontSize(16).fontWeight(FontWeight.Bold).borderRadius(D.rMd) .onClick(() { if (this.inputTitle.length 0) { promptAction.showToast({ message: 请输入标题 }); return; } promptAction.showToast({ message: 创建成功 }); this.inputTitle ; this.inputDesc ; }) Text(提交即表示同意相关条款).fontSize(9).fontColor(C.textDim).width(100%).textAlign(TextAlign.Center) }.width(100%) }快捷模板提供三个预设快速创建/高级模式/批量导入点击弹出 toast。提交按钮是状态自适应按钮标题为空时显示请填写标题C.cardSoft灰底有输入时变为✓ 提交创建C.primary绿底——按钮文案与背景色随inputTitle.length联动无需额外校验提示。点击时若标题为空弹 toast 请输入标题并 return成功则弹创建成功并清空inputTitle、inputDesc两个状态完成表单重置。按钮下方 9vp 灰字提交即表示同意相关条款是合规提示。八、表单设计六大最佳实践视觉分组每个功能区用独立白色圆角卡片包裹降低认知负荷渐进式 disclosure核心信息 → 分类 → 优先级 → 辅助设置 → 模板 → 提交符合自然思维流程即时反馈字数实时更新、选中态即时切换、Toggle 即时响应、按钮文案随输入变化合理默认值类型默认第一项、优先级默认中、提醒默认开启清晰标签体系输入字段上方小号灰色标签 placeholder 补充上下文操作引导快捷模板降低输入成本、提交按钮文案引导补全标题九、表单校验与提交流程源码中的提交校验逻辑非常轻量——只校验标题.onClick(() { if (this.inputTitle.length 0) { promptAction.showToast({ message: 请输入标题 }); return; } promptAction.showToast({ message: 创建成功 }); this.inputTitle ; this.inputDesc ; })若要扩展为完整的生产级流程可在此基础上增加四步// 第一步前端校验 const canSubmit this.inputTitle.trim().length 0 this.inputDesc.trim().length 0; if (!canSubmit) { showToast(请填写完整信息); return; } // 第二步数据组装 const payload { title: this.inputTitle, content: this.inputDesc, type: this.types[this.selectedType].name, priority: [低,中,高][this.selectedPriority], reminder: this.remindOn }; // 第三步异步请求http 模块 POST // 第四步状态重置或路由跳转十、键盘适配方案真机上键盘弹出可能遮挡输入框。三种解决方案.expandSafeArea([SafeAreaType.KEYBOARD])— 自动避让Scroll 包裹输入区域推荐本页已采用— 最简单框架自动处理监听window.on(keyboardHeightChange)动态调整 padding本页主内容区已经包裹在Scroll中.layoutWeight(1).scrollBar(BarState.Off).align(Alignment.Top)键盘弹出时用户可滚动定位被遮挡的输入框。十一、总结文件创建页展示了 ArkUI 表单开发的完整模式Section 卡片分组布局保持视觉清晰受控组件双向绑定确保数据一致性图标化选择器提供超越标准组件的表现力状态自适应提交按钮引导用户补全关键信息。这些模式可直接复用到任何需要数据录入的场景。
延伸阅读

更多相关文章

2026/11/4 19:35:56

STM32+ESP8266+Android数据传输链路排错指南

简介:本资源是一套面向嵌入式与物联网开发初学者及进阶者的完整通信系统例程,聚焦STM32单片机通过ESP8266 WiFi模块与Android APP实现双向TCP数据传输的实际工程实践。适用于智能家居、远程传感器监控、IoT设备控制等典型应用场景,帮助开发者…

2026/11/1 15:20:50

Python爬虫自学教程:从零基础到实战就业全攻略

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/29 1:46:30

我删掉了自己写的 300 行 Future,把整个 RPC 框架改成全链异步

Jaws 系列第 6 篇。前情提要:《删掉 gRPC 依赖后,我用 2400 行打通了 gRPC 生态》、《HTTP/2 传输进化史》。 本文代码全部出自 javahongxi/jaws,commit 可查。 一、一个让人不舒服的 join() 故事要从 wire 模块的一次重构说起。 8 月底我给…

2026/11/5 11:29:11

STM32串口DMA发送RGB565图片:分包协议与CRC校验实践

简介:一份围绕STM32串口传输彩色图像的嵌入式实践资料包,面向学习摄像头采集、串口通信与上位机图像还原的开发者,也可用于课程设计或项目原型验证。压缩包共499个文件、约10.92MB,包含C/H源码、Keil工程与配置、hex/axf/map等编译…

2026/11/5 11:24:07

Makefile自动化构建:从原理到实战技巧

1. 从零开始理解Makefile的本质 作为一个在Linux环境下摸爬滚打多年的老码农,我见过太多新手面对Makefile时露出的困惑表情。Makefile本质上是一个自动化构建脚本,但它更像是一种"构建逻辑的声明式表达"。想象你是个建筑工头,Makef…

2026/11/5 11:24:07

可跑通的ADS射频仿真实例:S参数、匹配与功放谐波平衡

简介:面向射频与微波电路设计学习者的 ADS 仿真实例合集,围绕阻抗匹配、滤波器、低噪放、功分器、功率放大器与耦合器等典型模块展开,适合希望从原理走向电路建模、仿真与优化的初中级工程师及电子类专业学生查练。压缩包为 rar 格式&#xf…

2026/11/5 11:24:07

存储过程参数过多错误分析与解决方案

1. 问题现象与背景分析 最近在排查一个生产环境数据库问题时,遇到了"CDataBaseEngineSink::OnRequsetInsertCreateRecord 数据库异常:为过程或函数 GSP_GR_InsertCreateRecord 指定了过多的参数"的错误。这个错误发生在调用存储过程GSP_GR_Ins…

2026/11/5 11:24:07

RabbitMQ消息投递可靠性保障与补偿机制实战

1. 消息队列中的投递可靠性难题 在分布式系统架构中,RabbitMQ作为经典的消息中间件,其消息投递的可靠性直接影响着业务系统的稳定性。我经历过一个电商订单系统案例:促销高峰期每秒3000订单消息通过RabbitMQ流转,有0.3%的消息神秘…

2026/11/5 11:24:06

SIL2认证的本质:从IEC 61508到ControlLogix硬件诊断的确定性实现

简介:本资源为罗克韦尔自动化(Rockwell Automation)ControlLogix系列PLC于2021年通过IEC 61508:2010标准SIL2功能安全认证的官方技术文档,面向工业自动化工程师、安全系统设计人员及PLC应用开发者,解决安全回路设计中对…

2026/11/4 12:38:23

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 0:02:07

多智能体协作系统架构设计与实践优化

1. 多智能体协作系统的时代背景2017年Transformer架构的诞生彻底改变了人工智能的发展轨迹。当行业还沉浸在单一大模型带来的性能突破时,Anthropic的研究团队已经将目光投向了更前沿的领域——如何让多个智能体通过协作产生超越单体能力的系统智能。这就像交响乐团中…

2026/11/5 0:02:07

大模型系统性入门实战指南:从原理到部署微调的全链路路线

提到大模型的系统性入门,我先说个结论:这事真不难,难的是资料太散、路线太多,今天这个框架明天那个工具,新人很容易在“收藏夹吃灰”和“教程看到一半放弃”之间反复横跳。市面上关于大模型的内容少说有几十万篇&#…

2026/11/5 0:02:07

鸿蒙文件系统沙箱机制解析与开发实践

1. 鸿蒙文件系统沙箱机制深度解析作为一名从Android转向鸿蒙开发的工程师,我深刻体会到文件系统访问是迁移过程中最先遇到的"拦路虎"。在Android上运行良好的文件读写代码,在鸿蒙真机环境却频频出现文件写入后神秘消失或直接抛出权限拒绝错误的…

2026/11/4 12:38:23

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑