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

Harmony os 技术实战|拼豆制图02:50 张图纸的 Repository 与轻量预览

Harmony os 技术实战|拼豆制图02:50 张图纸的 Repository 与轻量预览

图库从 7 张扩到 50 张后,最容易遇到的问题不是数据不够,而是页面一打开就把所有完整编号矩阵都渲染出来。拼豆图纸每张都可能有 70 x 70 个格子,如果列表页把这些格子全部创建成 UI,用户只是滑动图库,却要替详情页付出成本。

这篇文章会把问题拆到能落地的层面,重点解决:

  • 把图纸种子、资源矩阵和页面展示分开。
  • 列表页使用 previewCells,详情页才使用 chartCells。
  • 用统计函数复算颜色数量和拼豆总数,避免手填失真。
  • 保留没有真实矩阵时的程序化图纸生成能力。

问题不是 50 张图,而是 50 张完整矩阵

拼豆制图的图库包含动漫人物、游戏人物、爱豆、场景、潮玩盲盒等分类。列表页需要快速展示封面、标题、难度、色数和收藏按钮;详情页才需要每一格色号、坐标、图例和放大查看。如果把这两种需求混成一个对象,在列表页就会过度计算。

项目里已经把PatternRepository放在 services 层,这是一个正确方向。它既不是简单常量表,也不是 UI 组件;它负责把种子数据、真实矩阵资产和颜色统计拼成页面可消费的Pattern。这样图库页只管渲染卡片,编号图纸页只管展示完整施工图。

落地时可以先抓三个信号:

  1. Repository的职责是否只在一个层级里被定义,而不是页面、服务和资源各写一份。
  2. Pattern相关状态是否能从用户入口一路追到结果页,中间没有隐式副作用。
  3. 遇到空数据、取消操作或边界输入时,页面是否还能停在可继续操作的状态。

Repository 应该拥有数据组装权

Repository 的边界可以定得更清楚:它接收图纸 ID 和加载策略,返回稳定的业务对象。页面不关心矩阵来自脚本、资源文件还是程序化算法;页面只关心对象里有没有 previewCells、chartCells 和 colorStats。

决策点推荐做法避免的问题
列表展示读取previewCells列表滑动卡顿
详情展示进入编号页再取完整chartCells首屏承担全部矩阵成本
颜色统计从格子数组复算手填统计和实际图纸不一致
资源缺省保留程序化生成兜底某张图缺资源导致页面空白

这张表真正约束的是变更顺序:先固定“列表展示”的归属,再处理“详情展示”的输入输出,最后围绕“颜色统计”做回归。只要这三处没有漂移,后续增加页面、资源或参数时,改动就不会一路扩散到无关模块。实际排查时也建议按这个顺序记录结论:哪一层接收输入、哪一层生成结果、哪一层负责失败后的恢复。记录得越具体,下一轮迭代越不容易把已经稳定的路径改坏。

Pattern 模型要覆盖列表和施工图

模型要同时服务列表和详情,但不要让页面猜字段含义。previewCells是小尺寸预览,chartCells是施工图矩阵;二者都使用同一个BeadCell,这样渲染组件可以复用。

1. 模型同时覆盖预览和完整图纸

一个Pattern可以被列表页和详情页共用,但字段含义必须区分清楚。

exportinterfaceBeadCell{id:string;row:number;col:number;colorId:string;colorCode:string;hex:string;isEmpty:boolean;}exportinterfacePattern{id:string;title:string;category:string;width:number;height:number;previewCells:BeadCell[];chartCells:BeadCell[];colorStats:BeadColorStat[];}

previewCells解决列表页轻量展示,chartCells解决施工图细节。两者共用BeadCell,避免写两套渲染逻辑。

按需创建预览和完整图纸

Repository 的核心不是返回数组,而是把来源不同的数据统一成Pattern。真实矩阵存在时使用资源矩阵;没有资源时使用程序化图形,保证每张图都能进入详情页。

2. Repository 暴露列表和按 ID 查询

页面不用知道种子数组在哪里,也不用关心真实矩阵是否存在。

exportclassPatternRepository{staticgetPatterns():Pattern[]{constseeds=PatternRepository.createSeeds();constresult:Pattern[]=[];for(leti=0;i<seeds.length;i++){result.push(PatternRepository.createPattern(seeds[i],false));}returnresult;}staticgetPatternById(id:string):Pattern|null{constseeds=PatternRepository.createSeeds();for(leti=0;i<seeds.length;i++){if(seeds[i].id===id){returnPatternRepository.createPattern(seeds[i],true);}}returnnull;}}

列表读取时includeFullChart=false,详情读取时才打开完整矩阵。这个参数把性能策略放在 Repository,而不是散在页面分支里。

矩阵编码要能被脚本稳定生成

图库页的渲染策略应该克制。列表卡片用预览格子和封面信息,不直接渲染完整图纸。这样搜索和分类切换时,只需要处理轻对象。

3. 真实矩阵和程序化图纸走同一出口

不是每张图一开始都有真实矩阵,所以需要一个统一的创建函数。

privatestaticcreatePattern(seed:PatternSeed,includeFullChart:boolean):Pattern{constassetChart=PatternAssetCharts.get(seed.id);constpalette=assetChart===null?seed.palette:PatternRepository.assetPalette(seed.id,assetChart.colors);constpreviewCells=assetChart===null?PatternRepository.createCells(`${seed.id}-preview`,palette,seed.variant,16):PatternRepository.createCellsFromRows(`${seed.id}-preview`,palette,assetChart.previewRows);constchartCells=assetChart!==null&&includeFullChart?PatternRepository.createCellsFromRows(seed.id,palette,assetChart.chartRows):previewCells;returnPatternRepository.buildPattern(seed,palette,previewCells,chartCells);}

这里的重点是出口一致:页面拿到的永远是Pattern。资源矩阵、程序化兜底、轻量预览都被收在 Repository 内部。

统计结果从格子反推

统计信息不要做成静态文本。色号数量、每色颗数、总颗数都可以从格子里复算,导出图和详情页也会得到同一组数字。

4. 用字符矩阵表达颜色索引

资源矩阵适合脚本生成,字符编码比直接写 4900 个对象更容易维护。

privatestaticcreateCellsFromRows(id:string,palette:PaletteColor[],rows:string[]):BeadCell[]{constcells:BeadCell[]=[];for(letrow=0;row<rows.length;row++){constsourceRow=rows[row];for(letcol=0;col<sourceRow.length;col++){consttoken=sourceRow.substring(col,col+1);constcolorIndex=PatternRepository.assetColorIndex(token);constcolor=colorIndex<0?null:palette[colorIndex];cells.push(PatternRepository.createCell(id,row,col,color));}}returncells;}

字符.表示空格,数字和字母表示颜色索引。脚本只要输出稳定字符串,就能被 Repository 转成统一的格子对象。

页面只消费业务对象

批量生成后的矩阵资源需要有稳定命名。文件名、图纸 ID 和资源映射要保持同一套规则,否则 50 张图扩到 100 张时,最先出问题的是错配而不是算法。

5. 统计从格子反推

图例和总颗数不要手写,避免换图后忘记同步。

privatestaticcountColors(palette:PaletteColor[],cells:BeadCell[]):BeadColorStat[]{conststats:BeadColorStat[]=[];for(leti=0;i<palette.length;i++){constcolor=palette[i];letcount=0;for(letcellIndex=0;cellIndex<cells.length;cellIndex++){if(cells[cellIndex].colorId===color.id){count++;}}stats.push({colorId:color.id,colorCode:color.code,colorName:color.name,hex:color.hex,count});}returnstats;}

统计函数拥有完整格子输入,因此能服务详情页、导出图和个人页作品统计。后续如果增加材料清单,也可以从这里派生。

验证图库加载路径

实际项目里,验证不能只看页面有没有打开。更稳的做法是把入口、状态、边界数据和失败路径都走一遍,尤其是拼豆图纸这种“看起来能显示,放大后才暴露问题”的功能。

验证前建议准备一组固定样本:一条正常路径、一条空数据路径、一条失败路径,再加一条连续操作路径。这样每次改动都能比较同一批场景,不会只凭当前页面肉眼感觉判断。如果涉及屏幕尺寸、资源替换或系统能力,还要保留修改前后的截图和关键输入,方便回退时确认差异来自哪里。

hvigor assembleHap--no-daemonWrite-Host"手动验证:图库滚动 -> 分类切换 -> 打开编号图 -> 返回图库 -> 再打开另一张图"
  1. 图库首次打开时不应明显卡顿,分类切换后卡片高度和列数保持稳定。
  2. 随机打开 5 张图纸,确认详情页宽高、色数、总颗数与图例一致。
  3. 缺少真实矩阵的图纸也能进入编号图纸页,不能出现空白详情。
  4. 搜索结果中的图纸点击后仍能读取完整 chartCells。
  5. 批量替换资源后,图纸 ID 和矩阵资源要一一对应。

常见问题和处理

现象先看哪里处理方式
图库滑动卡顿列表页是否渲染完整矩阵列表只渲染 previewCells 或封面图
详情色号为空assetColorIndex 和 palette 长度检查矩阵字符是否越界
图例数量不对countColors 输入的是预览还是完整图详情和导出使用 chartCells 统计
某张图打不开PatternAssetCharts.get 返回值缺资源时回退程序化图纸

继续扩展图库时的做法

当图库继续扩容,可以把种子数据拆成 JSON5 或生成脚本输出的 ArkTS 文件,Repository 只保留解析和统计逻辑。若后续支持用户下载主题包,也可以把PatternAssetCharts.get替换成异步读取,本层接口仍然返回同样的Pattern

继续推进时建议保持三条约束:

  1. 先让现有主路径可回归,再拆更细的组件或服务。
  2. 新增状态必须能说明来源、更新时机和失败后的保留策略。
  3. 新增资源或配置要能从页面反查到生成来源,避免后期只靠人工记忆维护。

小结

图库稳定的核心是按场景给数据减重。列表页要快,详情页要准,统计要能复算。Repository 负责把资源和算法收成统一模型,页面就不会被 50 张图纸的矩阵细节拖住。

http://www.jsqmd.com/news/1285642/

相关文章:

  • UrbanGS:数据驱动的城市绿地规划与管理系统
  • STM32 HAL库串口收发卡死问题深度解析与四大实战解决方案
  • 固定资产管理系统技术演进解析:台账架构、标签打印、盘点模式、维保体系与信创迭代史
  • OLED透明屏驱动实战:从自发光原理到MSP430/STM32应用开发
  • Python自动化实战:200行代码打造B站UP主数据监控助手
  • Tkinter窗口图标设置全攻略:从iconbitmap到iconphoto的跨平台实践
  • 成都哪家全屋智能公司最专业
  • 工业物联网安全连接方案:NVIDIA与NXP硬件协同设计
  • Scratch编程画圆:从数学定义到算法实现,掌握计算思维与图形学基础
  • 驾照翻译件怎么弄?2026线上、线下渠道测评+办理流程
  • PLA材料遇水性能劣化解析与3D打印件防水增强方案
  • ESP32 GPIO中断编程实战:从轮询到事件驱动的实时响应优化
  • 华为云行业大模型团队AI PPT登顶PresentBench榜单
  • 08-C语言学习-字符串数组,二维整形数组
  • 手动排查木马实战指南:从进程、服务到日志的七维深度剖析
  • 上海有哪些值得选的GEO优化服务商?
  • 贵阳正规的外墙渗水企业
  • 蓝桥杯Java B组省赛:从环境配置到核心算法的实战指南
  • 2026年6月广州市南沙区二手房价格深度分析
  • 物联网硬件安全方案:SE050芯片与MK24FN微控制器的协同防护
  • Langchain框架解析:构建大语言模型应用的核心技术
  • XSS-labs靶场实战:从原理到绕过技巧的Web安全入门指南
  • 构建专属GPT-3 API代理:从架构设计到RAG集成的完整实践
  • 刷题笔记:力扣第707题-设计链表
  • STM32 PWM频率与占空比计算原理:从定时器时钟到参数配置实战
  • 2026年来内蒙古游玩必打卡 这款口碑超好的本土特色鸡品牌一定要尝
  • C语言动态内存通讯录实现:从malloc到realloc的完整项目指南
  • C++内存管理:从基础概念到智能指针与内存池实战
  • 本地部署开源远程桌面网关 Next Terminal 并实现外部访问
  • 标杆案例:仅靠3台设备,如何撑起800人的自救器盲戴考核?