鸿蒙原生应用 ArkTS 表单工程:资料上传页的虚线上传区与标题校验

App 34「校园打印资料共享」上传(Func2Tab),主题色 #27AE60 草绿。上传页采用"Header + 上传区 + 表单 + 发布"四区布局——白色 Header("上传资料"标题) + UploadZone 虚线上传区(📤 48 号 / ✅ 状态切换、"点击上传文件" / "已选择: 复习提纲.pdf"、草绿虚线边框、"支持 PDF / Word / 图片,最大 20MB"提示) + FormCard 表单卡(资料标题 TextInput + 所属课程 5 胶囊 Flex 换行 + 资料说明 TextArea) + "发布资料"按钮(48 高草绿,点击按 title 判断 Toast"发布成功"/"请填写标题")。本篇基于 34-print-share/entry/src/main/ets/pages/Func2Tab.ets(约 87 行)逐段拆解,附 4 张实机截图。

课程胶囊切换 · 点击"数据结构"课程胶囊后选中态从"高等数学"切换为草绿底白字,Flex 换行布局中 5 胶囊保持显示

一、整体结构:四区"Header + 上传 + 表单 + 发布"布局

App 34 上传页是"标题 + 上传区 + 表单 + 提交"的内容生产页——4 个 @Builder 块:

build() {
  Column() {
    this.Header()
    Scroll() {
      Column({ space: 16 }) {
        this.UploadZone()
        this.FormCard()
        Button('发布资料').fontSize(15).fontColor('#FFFFFF').backgroundColor(C.primary)
          .width('100%').height(48).borderRadius(D.rMd)
          .onClick(() => { promptAction.showToast({ message: this.title.length > 0 ? '发布成功' : '请填写标题' }); })
      }
      .width('100%')
      .padding({ left: D.pad, right: D.pad, top: 16, bottom: D.pad + this.safeBottom + 20 })
    }
    .layoutWeight(1).scrollBar(BarState.Off).align(Alignment.Top)
  }
  .width('100%').height('100%').backgroundColor(C.bg)
}

4 块结构

  1. Header — 白色背景 + "上传资料"标题
  2. UploadZone — 虚线上传区(状态切换)
  3. FormCard — 表单卡(标题/课程/说明)
  4. 发布按钮 — 48 高草绿提交

与 App 34 首页/资料对比

  • 首页:展示(价格 + 热门)
  • 资料:浏览(课程 + 文档)
  • 上传:生产(上传 + 发布)

"上传页 = 生产"——"首页看、资料找、上传传"——"内容生产闭环"——"用户从消费者到生产者"——"共享平台的 UGC"——"上传 = 贡献资料"——"34 的业务完整"

与 App 26 AI PPT 创建页对比:App 26 是"文字 + 选项"创建、App 34 是"上传 + 表单"——"两种创建"——"26 生成内容、34 上传内容"——"创建页的多样"

主题色 #27AE60 草绿——同首页/资料——"品牌色贯穿全 App"

校园打印资料共享上传首屏 · 草绿Header(上传资料)+虚线上传区(📤48号+点击上传文件+支持PDF/Word/图片最大20MB+草绿虚线边框)+表单卡(资料标题TextInput/所属课程5胶囊高数选中/资料说明TextArea)+发布资料48高草绿按钮

项目源码开源:https://gitee.com/codenestFlow/HarmonyOSHub

二、Header:白色 + "上传资料"

Header 是 **白色 + "上传资料"**的极简标题头:

@Builder
Header() {
  Row() { Text('上传资料').fontSize(20).fontWeight(FontWeight.Bold).fontColor(C.text) }
  .width('100%').height(this.safeTop + 56).padding({ top: this.safeTop, left: D.pad, right: D.pad })
  .backgroundColor(C.card).alignItems(VerticalAlign.Bottom)
}

Header 结构白色背景 + 20 号加粗黑色"上传资料" + 56 高 + safeTop + 底部对齐——"同系列标准 Header"

"上传资料" 的命名——"上传 + 资料"——"动词 + 名词"——"上传动作"——"上传 = 生产入口"——"命名的动作性"——"上传资料 = 贡献内容"

height(this.safeTop + 56) 固定高度——"56 + safeTop = 标准 Header 高"——"系列统一"

alignItems(VerticalAlign.Bottom) 底部对齐——"避开状态栏"——"标准适配"

三、UploadZone:虚线上传区(本页核心)

UploadZone 是 草绿虚线边框 + @State fileUploaded 状态切换的上传区:

@Builder
UploadZone() {
  Column({ space: 10 }) {
    Text(this.fileUploaded ? '✅' : '📤').fontSize(48)
    Text(this.fileUploaded ? '已选择: 复习提纲.pdf' : '点击上传文件').fontSize(14).fontColor(this.fileUploaded ? C.ok : C.primary)
    Text('支持 PDF / Word / 图片,最大 20MB').fontSize(11).fontColor(C.textDim)
  }
  .width('100%').padding({ top: 30, bottom: 30 }).backgroundColor(C.card).borderRadius(D.rLg)
  .border({ width: 1, color: C.primary, style: BorderStyle.Dashed })
  .onClick(() => { this.fileUploaded = true; promptAction.showToast({ message: '已选择文件' }); })
}

UploadZone 结构Column(10 间距)+ 3 行文字 + 30 padding 上下 + 白底 + 20 圆角 + 草绿虚线边框 + 整区可点——"上传占位区"

3.1 状态一:未上传(📤 点击上传文件)

默认状态this.fileUploaded = false):

  • 📤 48 号上传 emoji
  • "点击上传文件" 14 号草绿
  • "支持 PDF / Word / 图片,最大 20MB" 11 号灰

Text(this.fileUploaded ? '✅' : '📤') 状态 emoji——"📤 = 未上传、✅ = 已上传"——"条件渲染 emoji"——"48 号大图标"——"状态的视觉"

Text(this.fileUploaded ? '已选择: 复习提纲.pdf' : '点击上传文件') 状态文字——"点击上传文件"(提示)/ "已选择: 复习提纲.pdf"(结果)——"三目切换"——"动态文案"——"状态驱动"——"文案的状态化"

fontColor(this.fileUploaded ? C.ok : C.primary) 状态颜色——"未上传草绿、已上传绿"——"颜色 = 状态"——"双绿色"

Text('支持 PDF / Word / 图片,最大 20MB') 格式提示——"支持的格式"——"PDF/Word/图片"——"最大 20MB"——"限制说明"——"11 号灰"——"上传规则的透明"

border({ width: 1, color: C.primary, style: BorderStyle.Dashed }) 草绿虚线边框——"虚线 = 上传区"——"虚线 = 待交互"——"草绿色虚线"——"同 33 骑行页 ScanCard 虚线"——"虚线边框的系列复用"——"上传区的视觉"

onClick(() => { this.fileUploaded = true; promptAction.showToast({ message: '已选择文件' }); }) 点击上传——"点击切换状态"——"fileUploaded = true"——"Toast 反馈"——"占位选择文件"——"真实产品调起文件选择器"——"状态 + 反馈"

3.2 状态二:已上传(✅ 已选择文件)

已上传状态this.fileUploaded = true):

  • ✅ 48 号对勾 emoji
  • "已选择: 复习提纲.pdf" 14 号绿
  • "支持 PDF / Word / 图片,最大 20MB" 保持

"已选择: 复习提纲.pdf"——"文件名"——"复习提纲.pdf"——"具体文件"——"demo 的示例文件名"——"真实文件名的展示"

"✅" 对勾——"上传成功"——"完成的视觉"——"状态确认"——"用户知道选好了"

@State fileUploaded: boolean = false 布尔状态——"两态"——"true/false"——"同 33 骑行 riding"——"布尔状态的两态设计"——"状态管理"

与 App 33 骑行 RideCard 对比

  • App 33:@State riding 切换"扫码/计时"两态
  • App 34:@State fileUploaded 切换"📤/✅"两态

"两种布尔状态"——"33 骑行中、34 已选文件"——"布尔状态的两页应用"——"状态切换的系列范式"——"两态设计"

padding({ top: 30, bottom: 30 }) 30 padding 上下——"上传区的宽敞"——"大点击区"——"30 = 较多留白"——"上传区的舒适"

borderRadius(D.rLg) 20 大圆角——"上传区的大圆角"——"系列标准"

"虚线 + 大圆角" 的上传区——"标准上传 UI"——"主流 App 的上传区"——"虚线的通用"——"上传交互的惯例"

上传区再次点击交互 · 已选择文件状态再次点击虚线上传区后屏幕底部弹出"已选择文件"Toast,✅ 与"已选择: 复习提纲.pdf"保持显示

四、FormCard:表单卡

FormCard 是 标题 + 课程 + 说明的表单卡:

@Builder
FormCard() {
  Column({ space: 14 }) {
    Column({ space: 6 }) {
      Text('资料标题').fontSize(13).fontColor(C.textSub).width('100%')
      TextInput({ placeholder: '例如:高数第一章复习提纲' })
        .backgroundColor(C.cardSoft).borderRadius(D.rSm).height(44)
        .onChange((v: string) => { this.title = v; })
    }
    Column({ space: 6 }) {
      Text('所属课程').fontSize(13).fontColor(C.textSub).width('100%')
      Flex({ wrap: FlexWrap.Wrap }) {
        ForEach(this.courses, (c: string, idx: number) => {
          Text(c).fontSize(12)
            .fontColor(this.activeCourse === idx ? '#FFFFFF' : C.textSub)
            .padding({ left: 14, right: 14, top: 7, bottom: 7 })
            .backgroundColor(this.activeCourse === idx ? C.primary : C.cardSoft).borderRadius(14)
            .margin({ right: 10, bottom: 10 })
            .onClick(() => { this.activeCourse = idx; })
        }, (c: string) => c)
      }.width('100%')
    }
    Column({ space: 6 }) {
      Text('资料说明').fontSize(13).fontColor(C.textSub).width('100%')
      TextArea({ placeholder: '简要描述资料内容...' })
        .backgroundColor(C.cardSoft).borderRadius(D.rSm).height(90)
        .onChange((v: string) => { this.desc = v; })
    }
  }
  .width('100%').padding(16).backgroundColor(C.card).borderRadius(D.rLg).border({ width: 1, color: C.stroke })
}

FormCard 结构Column(14 间距)+ 3 个字段区(标签 + 输入控件)+ 16 padding + 白底 + 20 圆角 + 1px 边框——"标准表单卡"

4.1 资料标题(TextInput)

Text('资料标题') 13 号灰标签——"字段名"——"13 号灰 = 标签标准"

TextInput({ placeholder: '例如:高数第一章复习提纲' }) 输入框——"占位示例"——"44 高"——"浅灰底"——"10 圆角"——"文本输入"

onChange((v: string) => { this.title = v; }) 值绑定——"title 状态"——"输入即更新"——"@State 双向"——"表单状态"

4.2 所属课程(5 胶囊)

Flex({ wrap: FlexWrap.Wrap }) 换行布局——"自动换行"——"5 胶囊多行"——"Flex 换行"——"标签云布局"

5 课程:高等数学/大学英语/数据结构/线性代数/其他——"4 课程 + 其他"——"其他 = 兜底"——"分类的完整"

Text(c).fontColor(this.activeCourse === idx ? '#FFFFFF' : C.textSub) 选中白字——"选中白字、未选灰字"——"颜色 = 选中"

backgroundColor(this.activeCourse === idx ? C.primary : C.cardSoft) 选中绿底——"选中草绿底、未选浅灰底"——"胶囊选中态"

borderRadius(14) 14 圆角胶囊——"胶囊形"——"柔和"

margin({ right: 10, bottom: 10 }) 胶囊间距——"10 间距"——"换行间距"——"标签布局"

onClick(() => { this.activeCourse = idx; }) 点击选课——"单选"——"同资料页课程栏"——"课程选择一致"——"跨页一致"

与资料页 CourseSide 对比

  • 资料页:纵向 5 课程栏(96 宽)
  • 上传页:横向 5 胶囊(Flex 换行)

"同课程两种形态"——"资料页导航、上传页选择"——"场景适配"——"课程数据的复用"——"跨页数据一致"

4.3 资料说明(TextArea)

TextArea({ placeholder: '简要描述资料内容...' }) 多行输入——"90 高"——"多行文本"——"资料描述"——"简要说明"——"TextArea vs TextInput"——"多行 vs 单行"

onChange((v: string) => { this.desc = v; }) 值绑定——"desc 状态"——"输入即更新"

4.4 三个字段的状态

@State title / @State desc / @State activeCourse——"3 个表单状态"——"标题 + 课程 + 说明"——"完整表单"——"@State 表单管理"

FormCard 结构——"标签 + 控件"——"字段 6 间距"——"字段间 14 间距"——"表单间距体系"

文件选择状态切换 · 点击虚线上传区后 📤 emoji 切换为 ✅、文字从"点击上传文件"切换为绿色"已选择: 复习提纲.pdf",演示 @State fileUploaded 条件渲染

五、发布按钮

发布按钮是 48 高草绿提交按钮

Button('发布资料').fontSize(15).fontColor('#FFFFFF').backgroundColor(C.primary)
  .width('100%').height(48).borderRadius(D.rMd)
  .onClick(() => { promptAction.showToast({ message: this.title.length > 0 ? '发布成功' : '请填写标题' }); })

Button 结构"发布资料"白字草绿 15 号 + 48 高 + 14 圆角 + 满宽——"主提交按钮"

this.title.length > 0 ? '发布成功' : '请填写标题' 标题校验——"三目校验"——"title 非空 = 发布成功"——"title 空 = 请填写标题"——"表单校验"——"简单校验逻辑"——"demo 的校验演示"

fontColor('#FFFFFF').backgroundColor(C.primary) 白字草绿——"主按钮配色"——"品牌色按钮"——"高对比"

height(48) 48 高——"大按钮"——"拇指友好"——"主操作"——"48 = 标准按钮高"

校验的合理性——"未填标题提示"——"填了成功"——"demo 的简单校验"——"真实产品校验 + 上传 + 数据库"——"扩展点"

六、上传页的交互细节与可用性分析

6.1 状态切换的"核心交互"

📤 → ✅——"未传 → 已传"——"点击切换"——"状态机"——"两态循环"——"同 33 骑行"——"状态切换的演示"

6.2 虚线上传区的"惯例"

虚线 + 📤 + 提示——"标准上传区"——"主流 App 惯例"——"用户熟悉"——"零学习成本"——"虚线的通用语义"

6.3 表单的"3 字段"

标题 + 课程 + 说明——"完整资料信息"——"发布所需"——"表单完整"——"字段的选择"

6.4 发布校验的"反馈"

"请填写标题"——"校验反馈"——"未填提示"——"引导用户"——"校验的价值"——"表单的可用性"

6.5 上传页的"色彩心理学"

草绿(#27AE60)——"绿色 = 上传/成功"——"✅ 对勾 + 草绿按钮"——"成功的绿色"——"上传的安心"

6.6 上传页的"信息层级"

L1 标题(Header)→ L2 上传(UploadZone)→ L3 表单(FormCard)→ L4 发布(按钮)——"4 层信息"——"从上传到发布"——"渐进式"

6.7 上传页的"决策路径"

上传文件 → 填标题 → 选课程 → 写说明 → 点发布——"5 步发布"——"完整发布流程"——"从文件到发布"——"UGC 流程"

6.8 上传页的"对比与统一"

统一:3 字段同结构(标签 + 控件)——"表单项的统一"对比:3 字段类型不同(输入框/胶囊/多行)——"控件的差异"

6.9 上传页的"demo 完整性"

上传 + 表单 + 校验 = 完整上传页——"功能完整"——"可发布"——"demo 的完成度"

6.10 上传页的"系列创新"

表单 + 校验是系列亮点——"34 上传页的创新"——"TextInput/TextArea 的引入"——"表单页面的演示"——"系列表单范式"

6.11 上传页的"设计哲学"

上传页的 3 个设计哲学

  1. 上传优先——UploadZone 顶部最大
  2. 表单完整——3 字段齐全
  3. 校验反馈——发布校验

"上传 + 表单 + 校验的上传页"——"内容生产页的设计原则"——"从哲学看设计"

6.12 上传页的"终评"

上传区 + 表单 + 发布 = 完整上传页——"上传页的完成度"——"可上线级"——"系列表单页面的标杆"

6.13 上传区的"格式提示"

PDF / Word / 图片 + 20MB——"支持的格式"——"限制透明"——"用户预知"——"减少失败"——"提示的价值"

6.14 上传页的"课程胶囊"

5 胶囊 Flex 换行——"标签云"——"课程选择"——"与资料页一致"——"跨页统一"——"数据复用"

6.15 上传页的"demo 数据"

复习提纲.pdf——"示例文件名"——"高数场景"——"与首页热门资料呼应"——"数据一致性"

6.16 上传页的"虚线语义"

草绿虚线 = 上传区——"虚线 = 可交互占位"——"实线 = 已确定"——"虚线的待操作感"——"上传区的视觉语言"——"同 33 扫码卡虚线"——"系列虚线的复用"

6.18 上传页的"TextInput 占位"

"例如:高数第一章复习提纲"——"占位示例"——"引导输入格式"——"占位 = 示例"——"输入的引导"——"占位文案的价值"

6.19 上传页的"表单状态绑定"

onChange → @State——"输入即更新"——"双向绑定"——"声明式 UI 表单"——"状态驱动"——"表单的状态管理"

6.20 上传页的"校验逻辑"

title.length > 0 三目——"简单校验"——"非空判断"——"发布成功/请填写"——"校验的反馈"——"表单可用性"——"真实产品多字段校验"

6.21 上传页的"课程一致性"

5 课程与资料页一致——"高等数学/大学英语/数据结构/线性代数 + 其他"——"跨页数据一致"——"课程体系统一"——"上传归类"——"分类的一致性"

6.22 上传页的"场景价值"

学生上传笔记/讲义——"分享学习资料"——"UGC 场景"——"知识共享"——"上传的价值"——"共享平台的生态"

6.23 上传页的"颜色层级"

草绿(上传/选中/按钮)+ 浅灰(标签/占位)——"双色层级"——"绿 = 操作、灰 = 辅助"——"颜色的分工"——"表单的视觉"

6.24 上传页的"demo 价值"

上传 + 表单 + 校验 = 完整上传页——"可发布"——"UGC 演示"——"表单模板"——"后续 UGC App 可复用"——"模板沉淀"

6.25 上传页的"交互反馈体系"

上传 Toast + 校验 Toast——"两种反馈"——"已选择文件 + 请填写标题/发布成功"——"反馈的完整"——"操作的确定性"——"表单反馈链"

6.27 上传页的"首屏信息"

首屏:上传区 + 标题字段 + 课程胶囊——"核心操作在前"——"先传文件后填表"——"操作顺序"——"表单的引导"——"上传优先"

6.28 上传页的"可滚动"

Scroll 容器——"表单可滚动"——"内容超出可滚"——"小屏适配"——"表单的完整性"——"滚动浏览"

6.29 上传页的"用户心智"

"上传 = 分享"——"学生分享资料"——"贡献价值"——"知识共享"——"UGC 心智"——"上传的成就感"

6.30 上传页的"最终设计评价"

上传 + 表单 + 校验 = 完整上传页——"从结构到交互到校验的完整"——"可上线级"——"系列表单标杆"——"上传页的完成度评级"

七、总结:草绿 + 虚线上传 + 表单 + 发布

App 34 上传页一句话用草绿(#27AE60)组织一个"上传 + 表单 + 发布"的资料生产页——虚线上传区用 📤/✅ 状态切换展示文件选择,表单卡用标题 TextInput + 课程胶囊 + 说明 TextArea 收集资料信息,发布按钮用标题校验反馈"发布成功/请填写标题"。

3 个设计亮点

  1. @State fileUploaded 状态切换——📤 点击上传 → ✅ 已选择文件
  2. 3 字段表单卡——标题 TextInput + 5 课程胶囊 + 说明 TextArea
  3. 发布校验——title 非空判断"发布成功/请填写标题"

主题色设计逻辑:草绿 = 上传/成功的绿色——"上传页用草绿,因为绿色是成功与提交的象征"——与首页/资料同色——"品牌色贯穿"

与系列呼应:虚线上传区(33 扫码卡虚线)、@State 状态(33 骑行)、课程胶囊(31 Chip)、TextInput/TextArea(26 创建)、Button(系列)、Toast 反馈(系列)——"34 上传把系列的状态 + 虚线 + 表单手法组合出'上传'场景"

体验细节:状态切换、格式提示、表单字段、发布校验——"上传页的核心 = 让用户'3 秒传文件 + 5 秒填表单'"

可扩展性展望:真实文件选择、上传进度、表单校验完善、课程接口、发布到服务端、审核机制——"demo 的上传页骨架完整"

七、扩展思考:上传页的发布流程与设计哲学

7.1 上传页的"发布流程"

完整发布漏斗

上传文件 → 填标题 → 选课程 → 写说明 → 点发布 → 校验 → 发布成功

"5 步发布流程"——"从文件到发布"——"UGC 内容生产"——"完整链路"——"上传页的价值"——"内容共享的核心"

7.2 上传页的"信息架构"

4 层信息

  1. L1 标题(Header)——"上传资料"
  2. L2 文件(UploadZone)——"传什么"
  3. L3 信息(FormCard)——"叫什么"
  4. L4 提交(Button)——"发布"

"4 层渐进式"——"从文件到发布"——"内容生产的信息金字塔"——"用户逐步完成"

7.3 上传页的"业务建模"

3 个 @State(title/desc/activeCourse)——"3 状态建模"——"表单数据"——"发布内容"——加文件路径(filePath)、加标签(tags)即可扩展——"数据模型的扩展点"

7.4 上传页的"对比与统一"

统一:3 字段同结构(标签 + 控件)——"表单项的统一"对比:3 字段类型不同(TextInput/胶囊/TextArea)——"控件的差异"——"表单的多样"

7.5 上传页的"设计哲学"

上传页的 3 个设计哲学

  1. 文件优先——上传区顶部最大视觉
  2. 信息完整——标题/课程/说明齐全
  3. 校验反馈——发布前校验引导

"文件 + 信息 + 校验的上传页"——"内容生产页的设计原则"——"从哲学看设计"——"这套方法论可直接迁移到任何 UGC 类 App"

7.6 上传页的"终评"

App 34 上传页综合评估——"四区结构 + 草绿主题 + 完整发布链"——"上传页的完成度评级"——"一个可上线级的内容上传页"——"系列表单页面的标杆"——"demo 的高完成度"

八、彩蛋:上传页的细节设计

8.1 上传区"50 号 emoji"

📤/✅ 48 号——"大图标"——"上传的视觉焦点"——"48 = 大号"——"图标的醒目"——"上传区的视觉"

8.2 "复习提纲.pdf" 的示例

"复习提纲.pdf"——"高数场景"——"与首页热门资料呼应"——"示例的真实"——"demo 数据一致"——"跨页数据"

8.3 "最大 20MB" 的限制

"20MB"——"上传限制"——"文件大小"——"预知规则"——"减少失败"——"限制透明"——"上传的规范"

8.4 "其他" 课程的兜底

"其他"——"分类兜底"——"未列课程"——"Flex 换行的第 5 项"——"分类的完整"——"兜底的设计"

8.5 TextArea 的"90 高"

"90 高"——"多行输入"——"资料描述"——"3-4 行"——"说明的充分"——"TextArea 的高度"

8.6 胶囊的"14 圆角"

"14 圆角"——"胶囊形"——"7 padding 纵向"——"14 横向"——"胶囊的比例"——"柔和的视觉"

8.7 表单卡的"16 padding"

"16 padding"——"表单卡内边距"——"字段的呼吸"——"表单的舒适"——"标准 padding"

8.8 发布按钮的"48 高"

"48 高"——"大按钮"——"拇指友好"——"主操作"——"48 = 标准按钮高"——"提交的突出"

8.9 上传页的"草绿三处"

虚线 + ✅ 文字 + 按钮——"3 处绿色"——"品牌色贯穿"——"绿色的记忆"——"上传 = 绿色的联想"

8.10 上传页的"demo 完整性"

上传 + 表单 + 校验 = 完整上传页——"可发布"——"用户可操作"——"demo 的完成度"——"从文件到发布的完整链"

九、总结与展望

App 34 上传页的核心价值用草绿 + 虚线上传区 + 表单 + 校验,构建一个"3 秒传文件 + 5 秒填表单 + 1 秒发布"的内容生产页——这是 UGC 类 App 上传页的标准范式。

与系列对比

App创建/生产类页面决策
26AI PPT 创建写什么
29评价评什么
30公益帮什么
34上传资料传什么

"34 上传页的决策是'传什么资料'"——"上传页 = 内容生产"——"每个生产页面都在帮用户贡献内容"——"34 帮用户上传学习资料"

终评草绿 + 虚线上传 + 表单 + 发布 = 完整上传页——"从配色到发布链的完整设计"——"上传页的标杆"

补充说明:本篇所有代码引用均基于 34-print-share/entry/src/main/ets/pages/Func2Tab.ets 实际源码,行号与源码一一对应;4 张实机截图分别覆盖上传首屏、文件选择状态切换、课程胶囊切换、再次点击上传区 Toast 四种差异场景,全部含模拟器轮廓,图床域名统一为 imgbed.devzoo.top。上传页的虚线上传区与 @State 布尔切换设计完整演示了 UGC 表单的最小可用范式。

补充说明:上传页是 App 34 的"内容生产入口",与首页(展示)、资料(浏览)、我的(管理)构成打印资料共享的完整 UGC 闭环——用户上传的资料经审核后进入资料库供他人下载打印,体现共享平台的生态价值。@State fileUploaded 布尔状态与发布按钮的 title 校验,是表单类页面的最小可用示范,可复用于任何内容生产型 App。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐