资讯动态

HarmonyOS应用实例:ArkTS实现除法竖式分步演示组件

发布时间:2026/10/17 4:03:18 来源:尧图企业网站定制
1. 项目概述1.1 这个项目的核心是什么很多做教育类应用的开发者都会碰到同一个问题知识点明明很简单但要用代码“讲”清楚难度瞬间翻倍。就拿“除数是一位数的除法”来说成年人一眼看出答案是几但要让一个三年级的小朋友真正理解“为什么是这个数”“每一步在算什么”就必须回到竖式本身——一步一步展示“除、乘、减、落”的完整过程。HarmonyOS应用实例52这个项目做的就是这件事用ArkTS语言开发一个竖式分步演示组件通过可视化的方式把除法竖式的计算过程拆分成可交互、可回放、可暂停的步骤让学生能跟随演示节奏理解每一位商的推导逻辑也让老师在做课件时能直接复用这个交互组件。我最初看到这个标题时第一反应是“这不就是个简单的算术演示吗”真正动手梳理需求之后才发现里面的坑远比想象中多竖式的排版布局怎么处理余数什么时候带下来商的位置怎么确定“不够除”的情况如何展示每一步动画的粒度怎么划分这些细节任何一个处理不好演示就会变成一堆数字乱跳学生反而越看越糊涂。1.2 适合谁参考如果你属于下面任何一类这篇内容应该能帮上忙正在用ArkTS做HarmonyOS教育类应用的开发者需要实现数学、物理类分步解题演示功能对自定义组件布局和状态管理有需求想看看Canvas绘制和Text组件如何配合的开发者想了解如何把“教学逻辑”转换成“代码逻辑”的产品经理或前端开发者我会从需求拆解、布局方案、核心算法、分步触发机制、状态管理这几个维度把整个项目的设计思路和实现细节完整还原出来顺带分享一些调试过程中踩过的坑。文末我还会聊聊这个组件还能怎么扩展比如扩展到两位数除法、有余数的验算展示甚至结合错误标记功能。2. 需求拆解把教学逻辑翻译成代码逻辑2.1 竖式分步演示到底要演示什么在动手写第一行代码之前我花了比较多的时间去理清“分步演示”这四个字的真实含义。它不是一个简单的结果展示而是要把整个计算过程拆成符合人类认知节奏的若干个“步骤单元”。拿648 ÷ 4来举例。如果我们用计算器一秒钟就出结果 162但人脑的竖式计算过程是这样的看清被除数最高位是 6够除商 16 - 4 2把下一位 4 落下来变成 24商 624 - 24 0把下一位 8 落下来变成 8商 28 - 8 0得出最终结果 162这四步每一步其实还包含更细的动作——写商、做乘法、做减法、落数字。如果组件一次把所有数字全部显示出来学生根本看不到“过程感”但如果把每一步拆得过度细碎比如乘法、减法、落数分别做成独立步骤又会让演示显得拖沓不符合老师上课的节奏。我的处理思路是以“每一位商的完整推导”为一个主步骤每个主步骤内部再细分为“确定商值→计算乘积→做差求余→下落下一位”四个子动作。这样既保证了过程可感知又不会碎到让学生失去耐心。2.2 手动计算一遍竖式的完整过程要写出正确的算法我必须先确保自己完全“手算”了一遍完整流程。很多开发者可能觉得这没必要但实际上只有把人脑的竖式逻辑完整走一遍才能发现那些微妙的地方。以856 ÷ 4为例第一步取被除数首位 88 ÷ 4 2商第一位为 2。2 × 4 88 - 8 0余数为 0。把下一位 5 落下来。第二步当前的数字是 5因为余数 0 和下一位 5 组合成了 055 ÷ 4 1商第二位为 1。1 × 4 45 - 4 1余数为 1。把下一位 6 落下来。第三步当前的数字是 16余数 1 和下一位 6 组合成 1616 ÷ 4 4商第三位为 4。4 × 4 1616 - 16 0余数为 0。全部数字处理完毕。注意这里有个细节第二步中余数是 1下一位是 6组合成 16。竖式书写时1 写在被除数 5 的下方而 6 是“落”下来的紧挨着 1 形成 16。这个视觉关系必须在组件布局中正确体现否则学生无法建立“余数带动下一位组合成新数”的心智模型。2.3 边界情况清单除了一位一位算正常的流程还要考虑这些边界情况被除数中间有 0比如840 ÷ 6第二位商是 0要演示“0 占位”不够除的情况比如432 ÷ 5首位 4 小于 5需要取前两位 43 来除每一步刚好整除余数为 0虚线框和文字提示要特殊处理商末尾有 0比如500 ÷ 5第三位商是 0建议可以先在纸上把所有边界情况的竖式手写一遍再对照代码实现检查大部分逻辑漏洞都能在动手编码前暴露出来。3. 界面布局竖式怎么排版才像“教科书”3.1 竖式布局的核心结构分析竖式排版和普通算式排版最大的区别在于数字有多层嵌套关系。被除数在上除数在左商在最上方而每一步的乘积和差值要动态出现在被除数下方不同位置。这种“动态出现”的特性决定了我们不能用一个静态的字符串去渲染竖式而是要拆分出多个独立的文本区域每个区域分别定位。我把整个竖式区域拆分成了这样几个部分商区域位于最上方每一位商随着步骤推进逐个显示被除数区域原始被除数保持不动但在下落数字时高亮除数区域位于左侧稳定不变乘积区域每一步中商 × 除数的乘积结果显示在当前被除数位组合的下方差值区域被除数位组合减去乘积后的结果显示在乘积正下方3.2 用布局还是绘制我的方案选择我最初有两个备选方案完全用Canvas自绘整个竖式用ArkUI的Row/Column Text组件组合布局用状态控制显隐经过对比我最终选择了方案2为主、方案1为辅的混合模式。原因有三产品需要适配不同屏幕尺寸和字体缩放纯Canvas绘制需要手动计算所有字体的渲染坐标工作量较大用布局容器配合约束可以借助ArkUI的响应式能力适配成本更低分步过程中涉及大量数字的显隐切换状态驱动UI更新比手动重绘更简单但纯布局也有个问题连线、括号的绘制用Text组件实现非常别扭。所以我最终决定数字和文字用布局组件呈现竖式周边的辅助符号比如减法横线用Canvas叠加绘制。这样既保证了字体渲染的清晰度又避免了布局组件模拟线条的尴尬。3.3 竖式模块的层级结构设计竖式演算区域我设计了三个纵向层级最上层是商区所有符号位从上往下依次排列中层是被除数区包含所有下落的数字以及每一步的差值展示位底层是运算痕迹区包括乘积、余数等过程数据这三个层级在代码实现中对应三个嵌套的Row/Column。每一层里数字并不是简单横向排列而是根据“当前处理到哪一位”动态决定哪些数字可见。可视性由当前步骤的索引控制——这正是分步演示最核心的交互逻辑。实操建议调试时先把所有层的可见性设为完全显示确认整体布局不穿帮之后再逐步接入步骤控制逻辑。不要边写边调动画否则问题定位会很混乱。3.4 数字位对齐的细节处理竖式排版最重要的就是“每一位要对齐”。我的做法是为被除数的每一位固定一个等宽容器宽度为该位数字的实际渲染宽度 左右留白所有数字统一使用等宽字体。要注意的是一个隐性需求当某一位的数字从无到有显示时不能让其他位的数字发生位移。因此每一位数字的容器无论是否有内容都必须占据固定空间。我用的是显式设置width和height并在无数字时保留占位。4. 核心算法除法竖式分步计算的完整实现4.1 步骤数据结构的确定设计分步算法之前我先想清楚了一个问题每一步组件需要哪些信息才能完成渲染我定义了一个步骤对象包含以下字段currentIndex当前处理到的被除数位数索引dividendSegment当前参与计算的“被除数片段”比如 24 或 16由前一步余数拼接当前位数字组成quotientDigit当前求得的商一位数字productValue商和除数的乘积remainder当前步骤的余数needDropNext是否需要把下一位数字落下来有了这个数据结构UI层就可以根据“当前步骤的数据”决定显示哪些数字、哪些运算痕迹完全不需要计算逻辑。4.2 逐步计算逻辑的函数抽象除法竖式分步的核心算法可以用一个循环来理解初始化余数为0从左往右遍历被除数的每一位每次用当前余数 × 10 当前位数字更新被除数片段然后做整除和取余记录下商的每一位。但这里有个关键问题步骤演示要求“一步一步展示”循环一次跑完当然可以但如果一次把所有步骤全部计算出来并存入数组UI就能实现“下一步”按钮的即时切换。因此我的实现分成两个阶段预计算阶段一次性把完整步骤数组算出来播放阶段根据当前步骤索引从数组取数据渲染这样做的好处是交互响应速度快不会在每次点击下一步时重复计算并且支持用户回退到上一步。4.3 处理“商为0”和“不够除”的两种场景边界情况的处理我单独说明一下4.3.1 中间位商为0比如840 ÷ 6第一位8 ÷ 6商1余2。第二位当前片段是 24余数2拼接被除数第二位424 ÷ 6 4余0。第三位当前片段是 0余数0拼接被除数第三位00 ÷ 6 0余0。商的第二、三位分别是4和0这里的“0”不能省略必须展示。在分步演示中这种0商的步骤也要完整呈现否则学生会觉得“数字怎么莫名其妙消失了”。我在状态渲染时保留了这一步只是在UI提示文案上增加了“0除以任何数都得0”的说明。4.3.2 首位数不够除比如432 ÷ 5被除数最高位是44 5这一步不能直接上商。程序里的处理逻辑是当余数为0且当前位数字小于除数时商的该位记为0但不进入正式的“乘减”步骤而是直接把下一帧的 dividendSegment 更新为0 × 10 4也就是4不对——这里其实更准确的写法是首位的处理结果分成两种情况。我用的方法是用一个辅助逻辑如果当前轮次拼接得到的片段值小于除数并且这是第一位还没上过商则把这一位“跳过”将余数设为这位数字本身不产生商的显示。这个状态比较微妙我会在下一小节展开说明。4.4 关键代码骨架示例下面给出分步计算逻辑的核心代码骨架使用TypeScript描述关键部分带注释interface DivisionStep { segment: number; // 当前被除数片段 quotientDigit: number; // 当前位上商 product: number; // 乘积 remainder: number; // 当前余数 index: number; // 被除数位置索引 isEmptyQuotient: boolean; // 该步是否不显示商值 } function buildDivisionSteps(dividend: number, divisor: number): DivisionStep[] { const digits String(dividend).split().map(Number); let remainder 0; const steps: DivisionStep[] []; for (let i 0; i digits.length; i) { const segment remainder * 10 digits[i]; if (segment divisor steps.length 0) { // 首位不够除商位补0占位余数保留等待下一位拼接 remainder segment; steps.push({ segment, quotientDigit: 0, product: divisor * 0, remainder, index: i, isEmptyQuotient: true, // 实际显示时该位不显示数字 }); continue; } if (segment divisor) { // 非首位不够除商0 remainder segment; steps.push({ segment, quotientDigit: 0, product: 0, remainder, index: i, isEmptyQuotient: false, }); continue; } const quotientDigit Math.floor(segment / divisor); const product quotientDigit * divisor; remainder segment - product; steps.push({ segment, quotientDigit, product, remainder, index: i, isEmptyQuotient: false, }); } return steps; }注意这个骨架是一个“逻辑演示”性质的代码实际ArkTS中我会做少量类型定义上的调整。真实项目中除了计算步骤数组还需要额外记录每一步的“下落数字位置”也就是上一步余数应该和被除数的哪一位数字进行拼接这个信息在UI渲染时至关重要。4.5 预计算和分步索引的关系所有步骤在页面初始化时一次性生成分步演示的过程其实就是改变一个整数currentStepIndex的过程。组件只在当前索引变化时重新读取步骤数组中对应下标的数据并刷新局部状态。这种方案比“每步现场计算”有一个明显好处回退到上一步时不需要重新执行计算逻辑也不存在副作用。如果希望加入自动播放能力只需要一个定时器每2秒执行this.currentStepIndex直到数据结尾为止。5. 分步演示机制交互与视觉反馈5.1 下一步/上一步的状态推进模型我在项目里用一个currentStepIndex变量驱动整个演示流程。点击“下一步”时索引增加组件重新根据新索引更新当前高亮的被除数位当前位置显示的商当前乘积和差值的显隐底部文案提示这听起来很简单但实际有一个特别值得注意的地方用户可能在中途点击“上一步”此时不仅要回退数字状态还要把高亮效果、操作说明文字同步回退否则UI和数据会脱节。5.2 高亮与淡化策略让学生只看该看的地方演示类组件最忌讳的事情是界面一次性把所有信息都暴露出来。为了引导学生的视线我做了两个视觉状态当前处理位使用浅色背景高亮让视线聚焦已完成处理位使用普通颜色但叠加一个淡色透明度形成区分余数数字采用深色粗体并在下方增加一条短线模拟手写竖式的“落数”视觉。每次下落时数字从上方轻微下降并渐显这个效果我用ArkUI的animateTo实现时长控制在 400 毫秒左右既不影响整体节奏又能让学生明显感知“数字是移动下来的”。5.3 操作按钮与进度控制演示控制区域我设计了三个基础按钮上一步、下一步、重置。在步骤索引为0时禁用上一步在末尾时禁用下一步。同时增加一个步骤指示器显示当前第几步、总共几步让教师可以快速定位进度。这里有个小优化按钮的布局我放在了竖式展示区域下方而不是页面底部这样在平板等大屏设备上教师单手操作时不用跨越整个屏幕去点击。细节体验值得较真。5.4 辅助教学文案的生成为了让组件不仅“演示”还能“讲解”我还为每一步生成了一句对应的教学文案第一步生成“从被除数的最高位开始6除以4商1”第二步生成“24除以4商66乘4等于24余数为0”收尾时生成“计算结果为 162”文案放在竖式下方用简洁的短语而非完整长句避免学生读起来费劲。踩坑提醒文案生成不要用自然语言模板拼接数字时造成语义歧义。我在测试时见过“0除4余0”这种表述学生看到很困惑。后期改成更完整的“当前片段为00除以任何数都得0余0”才解决。6. 常见问题与调试经验速查6.1 竖式数字错位问题这是我在开发中遇到的最常见问题。856 ÷ 4的情况下第二位运算时余数是0下一位是5组合成05此时“0”要不要显示如果显示会导致第二行的缓冲区出现多余的一位数字视觉上看起来错位。最终方案是组合片段中高位如果为0只显示非零部分但占位宽度仍然保留。这样数字外观正确竖式结构也不会乱。6.2 动态高度变化导致布局跳动每一步显示的运算痕迹数量不同竖式模块的高度会不断变化导致下方按钮、文案区域跳动。我的做法是把竖式区域的最小高度设为可容纳全部步骤的完整高度并把未显示的区域设为透明占位。这样整体高度在播放中保持稳定。6.3 动画状态和步骤索引不同步有一次我连续快速点击“下一步”发现某些步骤的数字消失后又出现原因是动画还没结束新的状态已经渲染。解决方案是每次索引变化时取消当前动画任务再启动新任务。这也是用状态驱动动画时常见的“竞态问题”值得留意。6.4 测试用例建议建议准备一组覆盖不同边界的除法算式场景示例期望表现整除无余数648 ÷ 4每步余数均为0中间有0840 ÷ 6商第二位为0展示占位首位不够除432 ÷ 5自动取前两位 43 计算末尾为0500 ÷ 5商最末位为0大数9876 ÷ 3步数完整不卡顿我建议把这组用例固化成自动化测试每次修改算法后一键跑通能大幅降低回归成本。6.5 承载长算式的滚动适配位数较多的除法比如六位数除以一位数在手机屏幕上可能超出可视区域。我在竖式容器外层增加横向和纵向滚动能力同时调整了数字字号适配缩放保证长算式也能完整展示。竖式区域同时支持纵向滚动过程中当前步骤自动滚动到可视范围内避免学生只能看到“半截竖式”。7. 这个组件后续还能扩展的方向7.1 扩展到两位数除法当前实现的算法严格限定在“除数是一位数”扩展到两位数除法的核心逻辑其实不变但有两个新问题试商过程需要展示估值逻辑周期变长。可以考虑在步骤中加入“试商”辅助环节比如先估算一个接近的商再逐步校正。7.2 增加错误判断练习模式除了分步演示还可以在组件上增加练习模式。组件出题后让学生自己在输入框填写每一步的商、乘积、余数系统即时判断正误并给出提示。这个方向的技术点在于交互状态机会增加一个“判定态”但仍然基于原有的步骤数据结构扩展成本可控。7.3 与手写输入结合如果结合HarmonyOS的手写识别能力还能让学生直接在竖式区域书写数字系统识别后自动校对。这需要接入系统级手写识别API对输入区和数字占位布局的匹配程度要求较高适合作为进阶方向。7.4 多语言与无障碍支持考虑到教育场景的多样性把教学文案做成资源文件支持中文、英文等多语言切换同时将数字渲染的对比度提高增加无障碍标签让读屏软件也能读取当前步骤的含义。这些工作能显著扩大应用的使用人群同时技术实现并不复杂。我在实际动手的过程中最大的体会是这种“教学演示类”组件代码复杂度往往集中在两个地方——一是状态粒度如何拆分二是数据结构和状态如何严格对应。只要这两点想清楚剩下的布局、动画、交互都是可以顺着框架逐步完成的。希望这篇内容能帮准备做HarmonyOS教育应用的朋友少走弯路。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑