鸿蒙原生应用 ArkTS 表单工程:课本发布页的数字输入与成色胶囊

App 36「校园课本共享」发布(Func2Tab),主题色 #F2994A 琥珀橙。发布页采用"Header + 照片 + 表单 + 发布"四区布局——白色 Header("发布课本"标题) + PhotoZone 照片上传区(📷 44 号 + "上传课本照片"琥珀橙 + "清晰照片有助于快速出售"提示 + 琥珀橙虚线边框) + FormCard 表单卡(教材名称 TextInput + 售价(元)数字输入框 InputType.Number + 成色 5 胶囊 Flex 换行:全新/九五成新/九成新/八成新/七成新) + "发布课本"按钮(48 高琥珀橙,点击按 bookName 判断 Toast"发布成功"/"请填写书名")。本篇基于 36-book-share/entry/src/main/ets/pages/Func2Tab.ets(约 86 行)逐段拆解,附 4 张实机截图。

成色胶囊切换 · 点击"八成新"成色胶囊后选中态从"全新"切换为琥珀橙底白字,Flex 换行布局中 5 胶囊保持显示

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

App 36 发布页是"标题 + 照片上传 + 表单 + 提交"的卖家发布页——4 个 @Builder 块:

build() {
  Column() {
    this.Header()
    Scroll() {
      Column({ space: 16 }) {
        this.PhotoZone()
        this.FormCard()
        Button('发布课本').fontSize(15).fontColor('#FFFFFF').backgroundColor(C.primary)
          .width('100%').height(48).borderRadius(D.rMd)
          .onClick(() => { promptAction.showToast({ message: this.bookName.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. PhotoZone — 照片上传区(虚线)
  3. FormCard — 表单卡(教材名/售价/成色)
  4. 发布按钮 — 48 高琥珀橙提交

与 App 35 发布页对比:App 35 是"三列图片网格 + 表单"、App 36 是"单照片上传区 + 表单"——"35 多图网格 vs 36 单照片区"——"35 笔记多图、36 课本单照"——"两种上传形态"——"发布页的业务差异"——"35 内容发布、36 商品发布"。

与 App 34 上传页对比——App 34 是"虚线上传区 + 表单"、App 36 几乎同构——"34/36 上传页相似"——"34 资料、36 课本"——"上传表单模板复用"——"系列表单统一"。

"售价数字输入" 是 App 36 的特色——"InputType.Number"——"数字键盘"——"价格输入"——"商品发布的价格字段"——"数字输入框"。

主题色 #F2994A 琥珀橙——同首页/商品——"品牌色贯穿全 App"。

校园课本共享发布首屏 · 琥珀橙Header(发布课本)+照片上传区(📷44号+上传课本照片+清晰照片有助于快速出售+琥珀橙虚线)+表单卡(教材名称TextInput/售价元数字输入/成色5胶囊全新选中)+发布课本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"。

"发布课本" 的命名——"发布 + 课本"——"动词 + 名词"——"发布动作"——"卖家入口"——"命名的动作性"——"发布 = 卖书"——"C2C 供给端"。

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

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

三、PhotoZone:照片上传区

PhotoZone 是 📷 + 提示 + 琥珀橙虚线边框的照片上传区:

@Builder
PhotoZone() {
  Column({ space: 8 }) {
    Text('📷').fontSize(44)
    Text('上传课本照片').fontSize(14).fontColor(C.primary)
    Text('清晰照片有助于快速出售').fontSize(11).fontColor(C.textDim)
  }
  .width('100%').padding({ top: 26, bottom: 26 }).backgroundColor(C.card).borderRadius(D.rLg)
  .border({ width: 1, color: C.primary, style: BorderStyle.Dashed })
  .onClick(() => { promptAction.showToast({ message: '添加照片' }); })
}

PhotoZone 结构:Column(8 间距)+ 📷 44 号 + "上传课本照片"琥珀橙 + "清晰照片有助于快速出售"灰 + 26 padding 上下 + 白底 + 20 圆角 + 琥珀橙虚线 + 整区可点——"照片上传占位区"。

Text('📷') 44 号相机 emoji——"相机图标"——"上传的视觉"——"44 号大图标"——"拍照/上传"。

Text('上传课本照片') 14 号琥珀橙——"操作提示"——"主题色文字"——"上传动作"——"引导用户"。

Text('清晰照片有助于快速出售') 11 号灰——"提示文案"——"清晰 = 快卖"——"营销提示"——"照片价值"——"卖家的引导"。

border({ width: 1, color: C.primary, style: BorderStyle.Dashed }) 琥珀橙虚线——"虚线 = 上传区"——"主题色虚线"——"同系列虚线"——"上传区的视觉"。

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

onClick(() => promptAction.showToast({ message: '添加照片' })) 点击上传——"Toast 反馈"——"占位选图"——"真实产品调起相册"——"添加照片"。

与 App 34/35 上传区对比:

  • App 34:📤/✅ 状态切换(单文件)
  • App 35:三列网格逐步添加(多图)
  • App 36:📷 单照片区(单照)

"三种上传形态"——"34 单文件、35 多图、36 单照"——"上传的多样"——"业务适配"——"课本一张照即可"——"上传简化"。

发布按钮校验交互 · 未填写教材名称时点击"发布课本"按钮后屏幕底部弹出"请填写书名"Toast,演示 bookName 非空校验的反馈引导

四、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.bookName = v; })
    }
    Column({ space: 6 }) {
      Text('售价(元)').fontSize(13).fontColor(C.textSub).width('100%')
      TextInput({ placeholder: '请输入售价' }).type(InputType.Number)
        .backgroundColor(C.cardSoft).borderRadius(D.rSm).height(44)
        .onChange((v: string) => { this.price = v; })
    }
    Column({ space: 6 }) {
      Text('成色').fontSize(13).fontColor(C.textSub).width('100%')
      Flex({ wrap: FlexWrap.Wrap }) {
        ForEach(this.conditions, (c: string, idx: number) => {
          Text(c).fontSize(12)
            .fontColor(this.activeCond === idx ? '#FFFFFF' : C.textSub)
            .padding({ left: 14, right: 14, top: 7, bottom: 7 })
            .backgroundColor(this.activeCond === idx ? C.primary : C.cardSoft).borderRadius(14)
            .margin({ right: 10, bottom: 10 })
            .onClick(() => { this.activeCond = idx; })
        }, (c: string) => c)
      }.width('100%')
    }
  }
  .width('100%').padding(16).backgroundColor(C.card).borderRadius(D.rLg).border({ width: 1, color: C.stroke })
}

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

4.1 教材名称(TextInput)

Text('教材名称') 13 号灰标签——"字段名"——"13 号灰"。

TextInput({ placeholder: '例如:高等数学(第七版)' }) 输入框——"占位示例"——"44 高"——"浅灰底"——"10 圆角"——"书名输入"。

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

4.2 售价(数字输入)—— 本页特色

Text('售价(元)') 13 号灰标签——"售价字段"——"带单位(元)"——"价格输入"。

TextInput({ placeholder: '请输入售价' }).type(InputType.Number) 数字输入框——"InputType.Number 数字键盘"——"只能输数字"——"价格输入限制"——"数字输入框"——"系列首次数字输入"——"售价 = 核心字段"——"键盘适配"。

onChange((v: string) => { this.price = v; }) 值绑定——"price 状态"——"价格字符串"——"发布价格"。

"InputType.Number 的价值"——"数字键盘"——"快速输入"——"防误输"——"价格输入优化"——"键盘类型适配"——"表单细节"。

4.3 成色(5 胶囊)

Text('成色') 13 号灰标签——"成色字段"——"新旧程度"。

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

5 成色:全新/九五成新/九成新/八成新/七成新——"5 级成色"——"从全新到七成新"——"成色分级"——"完整成色体系"——"与商品页成色一致"——"跨页统一"。

fontColor(this.activeCond === idx ? '#FFFFFF' : C.textSub) 选中白字——"选中白、未选灰"。

backgroundColor(this.activeCond === idx ? C.primary : C.cardSoft) 选中橙底——"选中琥珀橙"——"胶囊选中态"。

borderRadius(14) 14 圆角胶囊——"胶囊形"。

margin({ right: 10, bottom: 10 }) 胶囊间距——"10 间距"——"换行间距"。

onClick(() => { this.activeCond = idx; }) 点击选成色——"单选"——"@State activeCond"——"同系列胶囊"。

与商品页成色呼应——"全新/九五/九成/八成/七成"——"商品页 ¥20 九五新、¥8 七成新"——"成色体系一致"——"跨页数据统一"——"发布即商品"。

4.4 三个字段的状态

@State bookName / @State price / @State activeCond——"3 个状态"——"书名 + 价格 + 成色"——"完整发布数据"——"商品信息"。

添加照片交互 · 点击照片上传区任意位置后屏幕底部弹出"添加照片"Toast,📷 图标与上传提示保持显示,演示虚线上传区整区可点

五、发布按钮

发布按钮是 48 高琥珀橙提交按钮:

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

Button 结构:"发布课本"白字琥珀橙 15 号 + 48 高 + 14 圆角 + 满宽——"主提交按钮"——"同 App 34/35 发布按钮"。

this.bookName.length > 0 ? '发布成功' : '请填写书名' 书名校验——"三目校验"——"bookName 非空 = 成功"——"空 = 请填写书名"——"简单校验"——"同系列"——"发布校验模板"。

fontColor('#FFFFFF').backgroundColor(C.primary) 白字琥珀橙——"品牌色按钮"——"高对比"。

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

六、发布页的交互细节与可用性分析

6.1 照片上传的"提示"

清晰照片有助于快速出售——"营销提示"——"照片价值"——"卖家引导"——"照片 = 成交"——"上传的转化"。

6.2 数字输入的"键盘"

InputType.Number——"数字键盘"——"价格输入"——"快速输入"——"防误输"——"键盘适配"——"系列首次"。

6.3 成色胶囊的"分级"

全新到七成新——"5 级成色"——"新旧程度"——"分级体系"——"与商品页一致"——"跨页统一"。

6.4 发布校验的"反馈"

"请填写书名"——"校验反馈"——"引导用户"——"表单可用性"——"同系列"。

6.5 发布页的"色彩心理学"

琥珀橙(#F2994A)——"橙色 = 交易/发布"——"发布按钮橙"——"虚线橙"——"主题色应用"——"发布的橙"。

6.6 发布页的"信息层级"

L1 标题(Header)→ L2 照片(PhotoZone)→ L3 表单(FormCard)→ L4 发布(按钮)——"4 层信息"——"从照片到发布"。

6.7 发布页的"决策路径"

传照片 → 填书名 → 填售价 → 选成色 → 点发布——"5 步发布"——"完整卖家流程"——"从照片到发布"。

6.8 发布页的"对比与统一"

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

6.9 发布页的"demo 完整性"

照片 + 表单 + 校验 = 完整发布页——"可发布"——"卖家演示"——"demo 的完成度"。

6.10 发布页的"系列创新"

数字输入框是系列亮点——"36 发布页的创新"——"InputType.Number"——"价格输入"——"商品发布范式"。

6.11 发布页的"设计哲学"

发布页的 3 个设计哲学:

  1. 照片优先——PhotoZone 顶部
  2. 价格明确——数字输入
  3. 成色分级——5 胶囊

"照片 + 价格 + 成色的发布页"——"商品发布页的设计原则"——"从哲学看设计"。

6.12 发布页的"终评"

照片区 + 表单 + 发布 = 完整发布页——"发布页的完成度"——"可上线级"——"系列商品发布标杆"。

6.13 发布页的"系列表单模板"

同 App 34/35 表单同构——"表单模板复用"——"34 资料/35 笔记/36 课本"——"系列表单统一"——"模板沉淀"。

6.14 发布页的"卖家心智"

"卖二手教材"——"学生卖家"——"闲置变现"——"发布 = 赚钱"——"C2C 供给端"——"场景驱动"。

6.15 发布页的"照片价值"

清晰照片 → 快速出售——"照片 = 成交率"——"视觉营销"——"第一印象"——"照片的转化"——"卖家引导"——"电商照片学"。

6.16 发布页的"价格输入优化"

数字键盘防误输——"输入效率"——"价格准确"——"键盘适配"——"输入体验"——"表单细节"——"数字输入的价值"。

6.17 发布页的"成色体系完整"

全新到七成新 5 级——"成色分级"——"新旧标准"——"跨页统一"——"发布与展示一致"——"成色体系"——"标准化的价值"。

6.18 发布页的"卖家激励"

清晰照片 + 快速出售——"卖家激励"——"卖得快"——"成交流程"——"供给端活跃"——"平台生态"——"激励设计"。

6.19 发布页的"与商品页联动"

发布成色 → 商品页版本——"发布即商品"——"供给到展示"——"跨页数据"——"demo 闭环"——"C2C 完整链路"。

6.20 发布页的"emoji 体系"

📷 相机——"上传符号"——"拍照上传"——"低成本图标"——"emoji = 功能"——"视觉的引导"。

6.21 发布页的"首屏信息"

首屏:照片区 + 书名 + 售价字段——"核心操作在前"——"先传图后填表"——"操作顺序"——"表单引导"。

6.22 发布页的"可滚动"

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

6.23 发布页的"数据流"

bookName/price/activeCond → 校验 → 发布——"数据流"——"从输入到发布"——"状态管理"——"声明式 UI"。

6.24 发布页的"最终设计评价"

照片区 + 表单 + 校验 = 完整发布页——"从结构到输入到校验的完整"——"可上线级"——"系列商品发布标杆"——"发布页完成度评级"。

6.25 发布页的"色彩一致性"

琥珀橙贯穿——"发布按钮 + 虚线 + 上传文字"——"3 处橙色"——"品牌记忆"——"橙色 = 发布"——"色彩辨识"。

6.27 发布页的"demo 价值"

照片 + 表单 + 校验 = 完整发布页——"可发布"——"C2C 卖家演示"——"表单模板"——"商品发布范式"——"模板沉淀"。

6.28 发布页的"学习场景"

"开学卖旧书"——"学生场景"——"教材交易"——"闲置变现"——"场景驱动"——"卖书的实用性"。

七、总结:琥珀橙 + 照片 + 表单 + 发布

App 36 发布页一句话:用琥珀橙(#F2994A)组织一个"照片 + 表单 + 发布"的卖家发布页——照片上传区用 📷 44 号 + "上传课本照片" + "清晰照片有助于快速出售"引导卖家传图,表单卡用教材名 TextInput + 售价数字输入 + 5 成色胶囊收集商品信息,发布按钮用书名校验反馈"发布成功/请填写书名"。

3 个设计亮点:

  1. 照片营销提示——"清晰照片有助于快速出售"
  2. 数字售价输入——InputType.Number 键盘(系列首次)
  3. 5 级成色胶囊——全新到七成新,跨页统一

主题色设计逻辑:琥珀橙 = 交易/发布的橙——"发布页用琥珀橙,品牌色贯穿"——"发布按钮橙 = 转化"——"主题色应用"。

与系列呼应:虚线上传区(34/35)、@State 状态(33/34/35)、成色胶囊(34 课程/35 类型)、TextInput(34/35 表单)、数字输入(系列首次)、Button(系列)、Toast 反馈(系列)——"36 发布把系列的虚线 + 状态 + 表单手法组合出'商品发布'场景"。

体验细节:照片提示、数字输入、成色分级、发布校验——"发布页的核心 = 让用户'3 秒传照片 + 5 秒填表单 + 1 秒发布'"。

可扩展性展望:相册选择、多图上传、价格范围校验、成色自动识别、发布到商品列表、聊天咨询——"demo 的发布页骨架完整"。

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

7.1 发布页的"卖家发布流程"

完整发布漏斗:

传照片(📷)→ 填书名 → 填售价(数字)→ 选成色(胶囊)→ 点发布 → 校验 → 发布成功

"5 步发布流程"——"从照片到发布"——"C2C 商品供给"——"完整链路"——"发布页的价值"——"二手交易的供给端"。

7.2 发布页的"信息架构"

4 层信息:

  1. L1 标题(Header)——"发布课本"
  2. L2 照片(PhotoZone)——"传什么图"
  3. L3 信息(FormCard)——"什么书多少钱"
  4. L4 提交(Button)——"发布"

"4 层渐进式"——"从照片到发布"——"商品发布的信息金字塔"——"卖家逐步完成"。

7.3 发布页的"业务建模"

3 个 @State(bookName/price/activeCond)——"3 状态建模"——"商品数据"——"发布内容"——加图片(image)、加描述(desc)即可扩展——"数据模型的扩展点"。

7.4 发布页的"对比与统一"

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

7.5 发布页的"设计哲学"

发布页的 3 个设计哲学:

  1. 照片优先——照片区顶部
  2. 价格明确——数字输入防误
  3. 成色分级——5 胶囊选择

"照片 + 价格 + 成色的发布页"——"商品发布页的设计原则"——"从哲学看设计"——"这套方法论可直接迁移到任何 C2C 交易类 App"。

7.6 发布页的"终评"

App 36 发布页综合评估——"四区结构 + 琥珀橙主题 + 完整卖家链"——"发布页的完成度评级"——"一个可上线级的商品发布页"——"系列商品发布的标杆"——"demo 的高完成度"。

八、彩蛋:发布页的细节设计

8.1 "清晰照片" 的营销

"清晰照片有助于快速出售"——"照片价值"——"快卖引导"——"卖家激励"——"照片 = 成交率"——"营销文案"——"上传的转化"。

8.2 InputType.Number 的"键盘"

数字键盘——"价格输入"——"防误输"——"快速输入"——"键盘适配"——"输入优化"——"系列首次"。

8.3 成色的"5 级"

全新/九五/九成/八成/七成——"5 级分级"——"新旧程度"——"成色体系"——"与商品页一致"——"跨页统一"——"发布即商品"。

8.4 "例如:高等数学(第七版)" 的占位

占位示例——"书名格式引导"——"占位 = 示例"——"输入引导"——"书名规范"——"占位文案"。

8.5 售价单位的"(元)"

"售价(元)"——"单位标注"——"价格单位"——"明确单位"——"输入规范"——"标签细节"。

8.6 发布页的"demo 一致性"

同 App 34/35 表单同构——"系列表单统一"——"标签 + 控件"——"胶囊 + 输入框"——"模板复用"——"跨 App 一致"。

8.7 发布页的"用户场景"

"卖了旧课本"——"学生卖家"——"闲置变现"——"C2C 场景"——"场景驱动"——"卖书的价值"。

8.8 发布页的"反馈体系"

添加照片 Toast + 校验 Toast——"两种反馈"——"操作反馈 + 校验反馈"——"反馈完整"——"交互确定性"。

8.10 发布页的"卖家心智"

"发布 = 赚钱"——"闲置变现"——"卖家激励"——"C2C 供给"——"发布的价值"——"交易生态"。

九、总结与展望

App 36 发布页的核心价值:用琥珀橙 + 照片区 + 数字输入 + 成色胶囊,构建一个"3 秒传照片 + 5 秒填表单 + 1 秒发布"的卖家发布页——这是 C2C 二手交易 App 发布页的标准范式。

与系列对比:

App创建/生产类页面决策
34上传资料传什么
35发布笔记发什么
36发布课本卖什么

"36 发布页的决策是'卖什么课本'"——"发布页 = 商品供给"——"每个发布页都在帮卖家上架商品"——"36 帮学生卖二手教材"。

终评:琥珀橙 + 照片 + 数字输入 + 成色 = 完整商品发布页——"从配色到发布链的完整设计"——"商品发布页的标杆"。

补充说明:本篇所有代码引用均基于 36-book-share/entry/src/main/ets/pages/Func2Tab.ets 实际源码,行号与源码一一对应;4 张实机截图分别覆盖发布首屏、添加照片 Toast、成色胶囊切换、发布按钮校验 Toast 四种差异场景,全部含模拟器轮廓,图床域名统一为 imgbed.devzoo.top。InputType.Number 数字输入框是系列首次使用的键盘类型适配,其售价输入 + 5 级成色胶囊是商品发布页的标准范式,可复用于任何 C2C 交易类发布页。

终评:App 36 发布页综合评级为"可上线级 C2C 商品发布页"。照片上传区(营销提示)+ 数字售价输入 + 5 级成色胶囊 + 发布校验的四段式结构,既简化了卖家上架流程(3 字段 + 1 图即可发布),又通过数字键盘和成色分级保证了数据准确性,是系列商品交易型发布页的完整模板。

补充说明:发布页是 App 36 的"C2C 供给端入口",与首页(浏览)、商品(购买)、我的(管理)构成二手课本交易的完整闭环——卖家发布课本进入首页低价书列表,买家在商品页选择版本购买,交易记录在我的页管理。InputType.Number 数字输入框是系列首次的键盘类型适配,售价 + 5 级成色(与商品页版本成色一致)共同构成标准的二手书发布表单,可复用于任何 C2C 交易类发布页。成色胶囊的"全新/九五/九成/八成/七成"与商品页版本卡(九五成新 ¥20 → 七成新 ¥8)严格对应,体现 demo 数据的跨页一致性。

Logo

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

更多推荐