当前位置: 首页 > news >正文

鸿蒙 ArkTS 实战:Poetry Feihualing 从诗词飞花令到成绩记录完整解析

鸿蒙 ArkTS 实战:Poetry Feihualing 从诗词飞花令到成绩记录完整解析

前言

Poetry Feihualing 是一个面向诗词飞花令的鸿蒙 ArkTS 单页应用。项目代码集中在Index.ets,通过@State管理记录列表、输入内容、声音开关和状态提示,并用ForEach把每一轮记录渲染为可勾选列表。

这篇文章直接基于项目源码展开,不写空泛介绍,重点分析它的数据模型、默认记录、统计函数、表单提交、列表刷新和后续扩展方式。对于学习 ArkTS 单页应用的人来说,这类项目很适合用来理解状态驱动 UI 的基本路径。

轻量小游戏或训练工具不一定先做复杂玩法。先把记录、统计、反馈和列表交互搭起来,后续接入真正的游戏逻辑会更稳。

配图展示的是开发者生态入口,发布时也可以替换成应用运行截图。本文关注的结构是:顶部指标、功能标签、声音开关、录入表单和记录列表。

一、项目定位与源码入口

1.1 应用定位

围绕关键字出题、限时回答、诗词库和对战模式,记录每轮飞花令的诗句产出与得分。

当前页面不是复杂多页应用,而是一个清晰的单页面闭环:用户看到默认记录,输入新的轮次信息,点击按钮保存,再通过列表勾选需要关注的记录。

1.2 源码入口

核心文件位于entry/src/main/ets/pages/Index.ets,入口组件使用@Entry@Component标记。

@Entry@Componentstruct Index{build(){Scroll(){Column({space:14}){Text('Poetry Feihualing')}}}}
区域作用对应能力
标题呈现应用名称Poetry Feihualing
统计卡片展示Score与 Selected汇总与计数
标签区展示玩法模块Keyword prompt, Timed answer, Poem library, Battle mode
表单新增记录TextInputButton
列表管理记录状态ForEachToggle

二、数据模型设计

2.1 记录接口

项目使用GameRound描述每一条游戏记录。

interfaceGameRound{title:string;score:number;note:string;active:boolean;}

这个接口非常适合成绩类应用。title表示轮次或关卡,score保存诗句得分note用来保存补充描述,active则控制是否被选中。

2.2 字段语义

字段类型在本项目中的含义
titlestring轮次、关卡或分类名称
scorenumber诗句得分
notestring结果说明、提示状态或扩展备注
activeboolean是否作为重点记录

数据模型稳定是这类项目的关键。后续即使增加真实玩法,也可以继续把最终结果写回同一个记录结构。

三、默认数据与业务语义

3.1 默认记录

页面初始化时已经准备两条业务记录。

@Staterounds:GameRound[]=[{title:'Keyword moon',score:7,note:'Timed 60s',active:false},{title:'Battle round',score:11,note:'Poem library used',active:false}];
默认标题数值备注是否选中
Keyword moon7Timed 60sfalse
Battle round11Poem library usedfalse

3.2 默认数据的价值

默认数据让用户首次进入页面时就能理解这个应用要记录什么。比如Keyword moonBattle round分别对应不同训练或玩法场景,备注字段则补充了结果细节。

  1. 空列表会降低理解效率。
  2. 示例记录可以说明输入格式。
  3. 顶部统计从首次打开就有可读数值。

四、页面状态管理

4.1 状态字段

页面使用@State保存列表、表单、开关和提示文本。

@Staterounds:GameRound[]=[];@StatetitleText:string='';@StatescoreText:string='';@StatenoteText:string='';@StatesoundOn:boolean=true;@Statestatus:string='Game ready';

4.2 状态流转

状态触发动作结果
rounds新增或勾选记录列表和统计刷新
titleText输入轮次名称提交时写入 title
scoreText输入数值转换为 score
noteText输入备注写入 note
soundOn切换声音开关保存声音偏好
status提交表单展示错误或成功信息

ArkTS 的声明式体验重点在于状态变化。只要状态设计清楚,UI 更新就能自然跟随数据变化。

五、统计函数拆解

5.1 累计Score

顶部左侧指标来自totalScore()

privatetotalScore():number{lettotal=0;this.rounds.forEach((item:GameRound)=>{total+=item.score;});returntotal;}

5.2 计算选中数量

右侧 Selected 来自selectedCount()

privateselectedCount():number{letcount=0;this.rounds.forEach((item:GameRound)=>{if(item.active){count++;}});returncount;}

这两个函数都只读列表状态,不修改任何数据,因此适合作为 UI 层的派生计算。

六、顶部指标卡片实现

6.1 卡片代码

顶部区域使用两个Column并排展示核心指标。

Row({space:10}){Column({space:4}){Text('Score').fontSize(13).fontColor('#475569')Text(String(this.totalScore())).fontSize(24).fontWeight(FontWeight.Bold).fontColor('#DC2626')}.layoutWeight(1).padding(14).backgroundColor('#FEE2E2').borderRadius(8)Column({space:4}){Text('Selected').fontSize(13).fontColor('#475569')Text(this.selectedCount()+'/'+this.rounds.length).fontSize(24).fontWeight(FontWeight.Bold).fontColor('#1D4ED8')}.layoutWeight(1).padding(14).backgroundColor('#DBEAFE').borderRadius(8)}

6.2 指标解释

指标数据来源产品含义
Score所有记录的 score 汇总衡量整体表现
Selectedactive 为 true 的记录数量标记当前关注记录
总数rounds.length展示记录规模

对于诗词飞花令诗句得分是最重要的结果数据,因此放在左侧主卡片。

七、功能标签区域

7.1 标签渲染

页面用四个短标签概括玩法能力。

Column({space:8}){Row({space:8}){Text('Keyword prompt').layoutWeight(1).fontSize(13).textAlign(TextAlign.Center)Text('Timed answer').layoutWeight(1).fontSize(13).textAlign(TextAlign.Center)}Row({space:8}){Text('Poem library').layoutWeight(1).fontSize(13).textAlign(TextAlign.Center)Text('Battle mode').layoutWeight(1).fontSize(13).textAlign(TextAlign.Center)}}

7.2 标签含义

序号标签说明
1Keyword prompt主玩法入口
2Timed answer交互过程
3Poem library结果反馈
4Battle mode沉淀能力

功能标签的好处是信息密度高,不需要额外说明文字,也能让用户迅速理解页面能力。

八、声音开关与配置入口

8.1 开关代码

页面提供Sound开关,状态保存在soundOn中。

Row(){Text('Sound').fontSize(16).fontColor('#374151')Blank()Toggle({type:ToggleType.Switch,isOn:this.soundOn}).onChange((checked:boolean)=>this.soundOn=checked)}

8.2 扩展方向

在当前版本中,soundOn还没有接入音频系统,但它已经占好了配置位置。后续可以根据它控制按钮音效、答题反馈音、成功提示音或错误提醒音。

九、表单录入与校验

9.1 输入区结构

表单由名称、数值、备注和按钮组成。

Column({space:10}){TextInput({placeholder:'Round name',text:this.titleText}).onChange((value:string)=>this.titleText=value)TextInput({placeholder:'Score',text:this.scoreText}).type(InputType.Number).onChange((value:string)=>this.scoreText=value)TextInput({placeholder:'Note',text:this.noteText}).onChange((value:string)=>this.noteText=value)Button('Add score').height(42).width('100%').onClick(()=>this.addRound())}

9.2 校验规则

提交时会先检查名称和数值。名称不能为空,分数必须能转换成有效数字。

constscore=Number(this.scoreText);if(this.titleText.trim().length===0||!Number.isFinite(score)){this.status='Enter round and valid score';return;}

这个校验足够直接,能避免空标题和非法分数进入列表。

十、新增记录逻辑

10.1 保存方法

新增记录由addRound()完成。

privateaddRound():void{constscore=Number(this.scoreText);if(this.titleText.trim().length===0||!Number.isFinite(score)){this.status='Enter round and valid score';return;}this.rounds=[{title:this.titleText,score:Math.round(score),note:this.noteText.length>0?this.noteText:'No note yet',active:false},...this.rounds];this.titleText='';this.scoreText='';this.noteText='';this.status='Round saved';}

10.2 头部插入

新记录会插入到数组头部。这样用户提交后,最新数据立即出现在第一条,反馈路径很短。

十一、列表渲染与选中态

11.1 ForEach 渲染

列表渲染使用ForEach遍历rounds

ForEach(this.rounds,(item:GameRound,index:number)=>{Row(){Toggle({type:ToggleType.Checkbox,isOn:item.active}).onChange(()=>this.toggleActive(index))Column({space:6}){Text(item.title).fontSize(18).fontWeight(FontWeight.Bold)Text(item.note).fontSize(14).fontColor('#475569')}.layoutWeight(1).margin({left:8})Text(String(item.score)).fontSize(18).fontWeight(FontWeight.Bold).fontColor('#DC2626')}.padding(14).backgroundColor(item.active?'#DCFCE7':'#FFFFFF').borderRadius(8)})

11.2 勾选更新

切换勾选时,先修改当前项,再用展开语法生成新数组引用。

privatetoggleActive(index:number):void{this.rounds[index].active=!this.rounds[index].active;this.rounds=[...this.rounds];}

这个写法保证列表 UI 能感知状态变化。选中的记录会使用#DCFCE7背景色,视觉反馈明确。

十二、布局与视觉层次

12.1 页面容器

外层使用Scroll,内部使用Column

Scroll(){Column({space:14}){Text('Poetry Feihualing')// stats// tags// sound switch// form// list}.padding(18).width('100%')}.height('100%').backgroundColor('#F8FAFC')

12.2 配色表

颜色使用位置作用
#F8FAFC页面背景保持浅色基底
#DC2626主指标数值强调成绩
#1D4ED8Selected 数值强调选择状态
#DCFCE7选中列表项表达活跃状态
#F1F5F9表单背景区分输入区域

十三、运行验证流程

13.1 手工验证路径

可以按以下流程验证:

  1. 打开页面,确认标题是Poetry Feihualing
  2. 查看默认两条记录是否出现。
  3. 点击Add score且不输入内容,确认提示为Enter round and valid score
  4. 输入Daily round99和备注,再点击保存。
  5. 勾选新记录,确认背景变绿且 Selected 数量增加。
this.titleText='Daily round';this.scoreText='99';this.noteText='Manual record';this.addRound();// 预期:status 更新为 Round saved// 预期:新记录位于列表第一项

13.2 验证要点

验证点预期结果
空标题提交显示错误提示
合法提交新记录插入列表顶部
数值输入保存为整数 score
勾选记录active 取反
顶部统计跟随列表变化

十四、面向真实玩法的扩展

14.1 业务扩展

后续可以接入诗词检索、关键字命中校验、对战轮换、倒计时和诗句去重。

14.2 工程扩展

后续扩展时,可以保持当前页面的状态结构不变,只把真实玩法结果接入scorenote

interfacePlayResult{roundTitle:string;finalScore:number;summary:string;}functionmapResultToRound(result:PlayResult):GameRound{return{title:result.roundTitle,score:result.finalScore,note:result.summary,active:false};}

这样可以把玩法层和记录层分开,避免页面代码随着功能增加而失控。

十五、工程复盘

15.1 当前实现的优点

  • 数据结构简单,字段语义清楚。
  • 统计函数只依赖列表数据,逻辑可预测。
  • 表单校验直接,错误提示明确。
  • 列表更新使用新数组引用,刷新路径稳定。
  • 功能标签贴合诗词飞花令的业务方向。

15.2 可复用经验

这类结构可以复用到答题、训练、学习、聚会游戏、儿童教育和轻量工具中。只要业务结果可以表达为“标题 + 数值 + 备注 + 状态”,就能套入相同的记录管理骨架。

总结

Poetry Feihualing展示了一个完整的鸿蒙 ArkTS 小应用骨架:用GameRound定义记录,用rounds保存列表,用totalScore()selectedCount()输出统计结果,用addRound()完成表单提交,再用ForEachToggle完成记录展示与选中状态更新。

它的代码不复杂,但工程链路完整。对于诗词飞花令这种玩法来说,当前版本已经完成了成绩记录层;后续只需要逐步补齐真实玩法,就能从原型平滑走向可用产品。

补充说明:当前页面把业务状态集中在组件内,适合小型训练工具快速迭代。
补充说明:记录列表采用头部插入,能让用户提交后立即看到最新结果。
补充说明:备注字段保留了足够弹性,可以承载提示、收藏、错误次数或扩展状态。
补充说明:统计卡片和列表项共享同一份数据,减少了重复状态带来的不一致风险。

补充说明:当前页面把业务状态集中在组件内,适合小型训练工具快速迭代。
补充说明:记录列表采用头部插入,能让用户提交后立即看到最新结果。
补充说明:备注字段保留了足够弹性,可以承载提示、收藏、错误次数或扩展状态。
补充说明:统计卡片和列表项共享同一份数据,减少了重复状态带来的不一致风险。


相关资源:

  • HarmonyOS 开发者官网
  • ArkTS 语言基础
  • ArkUI 组件开发
  • 状态管理概览
  • TextInput 组件
http://www.cnnetsun.cn/news/3500424.html

相关文章:

  • Qt文件对话框开发实战与性能优化指南
  • Python实现网站爬虫与倒排索引搜索引擎
  • PySpark Structured Streaming 实时处理 Kafka 数据实战指南
  • Android Activity生命周期详解与最佳实践
  • Next.js 的增量静态生成与动态路由:治愈系内容页的构建与更新策略
  • AI内容审核平台技术解析与选型指南
  • Python信号处理模块实战:从NumPy到SciPy应用
  • AI时代学习路径:编程基础与Prompt Engineering的先后顺序
  • 镇馆之宝:阶跃星辰Step AOS,AI手机操作系统的分水岭
  • 电容器动态分析:电压不变与电量不变模型全解析
  • 终极指南:如何通过Qwerty Learner同时提升英语打字速度和单词记忆能力
  • 导师反馈“AI痕迹明显”,有哪些真正闭眼可入的的降AI率工具推荐?
  • ChatGPT写部门规划全流程拆解(从战略对齐到KPI拆分,含Prompt工程黄金公式)
  • Qwerty Learner:当单词记忆遇上肌肉记忆,你的打字速度能提升多少?
  • AM62L DDR PHY寄存器配置实战:CA训练与信号完整性调优
  • 【面经】HashMap和ConcurrentHashMap区别
  • AM62L SoC CBASS防火墙配置详解:从寄存器解析到实战应用
  • 消息队列;Spring Boot 3.3 + AI Agent × RabbitMQ:让AI自动处理死信和消息路由,运维告警从每天50条降到3条
  • Node.js 26.3.0与工具链性能优化全解析
  • React Native与原生Android混合开发实践指南
  • 丝绒哑光口红代工,怎么避开“一热就化、一涂就干”的坑?
  • 金融时间序列分析与因子选股:量化交易入门完整路径
  • Android线程模型与UI更新机制详解
  • C#实现邮箱验证激活功能全流程指南
  • SpringBoot 优雅关闭与降级——生产环境必备
  • 如何设计高效的章节回顾:结构化梳理与交互式学习
  • 鸿蒙 ArkTS 实战:Menu Nutrition Advice 从智能助手到保存闭环完整解析
  • 基于遗传算法的梯级水电站群联合火电厂优化调度研究(Python代码实现)
  • TI毫米波雷达SoC中EDMA3架构解析与数据搬运实战
  • TI AWR雷达芯片CBUFF模块Linklist配置与高速数据接口实战