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

HarmonyOS 小游戏《对战五子棋》开发第23篇 - 保持棋盘正方形

一个属性解决正方形问题——ArkUI布局的优雅之处

棋盘图片:

问题:如何保证棋盘永远是正方形

棋盘必须是正方形(15x15等比例),但屏幕通常是长方形。如果设置width('100%')height('100%'),棋盘会被拉伸变形。

方案对比

方案1:硬编码尺寸(不推荐)

Canvas(this.context).width(320).height(320)

问题:不同设备上尺寸固定,小屏太大、大屏太小。

方案2:手动计算(不推荐)

Canvas(this.context).width('100%').height(this.calculatedHeight)// 需要手动计算

问题:需要监听宽度变化,手动计算高度,代码复杂。

方案3:aspectRatio(本项目使用)

Canvas(this.context).width('100%').aspectRatio(1)// 宽高比1:1 → 正方形

aspectRatio详解

aspectRatio(ratio)设置组件的宽高比:

  • aspectRatio(1):宽=高(正方形)
  • aspectRatio(2):宽=2×高
  • aspectRatio(0.5):高=2×宽

工作原理:当设置了宽度(如width('100%')),aspectRatio自动计算高度。

宽度 = 父容器宽度 (如360vp) 高度 = 宽度 / aspectRatio = 360 / 1 = 360vp → 正方形!

棋盘容器的布局

Column(){ChessBoardView({boardData:this.boardData,lastMoveRow:this.lastMoveRow,lastMoveCol:this.lastMoveCol,onCellClick:(row:number,col:number)=>{this.onCellClick(row,col);}})}.width('92%')// 棋盘容器占页面92%.backgroundColor('#D4A868')// 木色背景.borderRadius(8)// 圆角.clip(true)// 裁剪超出部分

布局层次

页面 (100%) └─ Column (92%) ← 棋盘外框,有边距 └─ Canvas (100%, aspectRatio 1) ← 棋盘画布,正方形

clip(true)的作用

.clip(true)

Canvas是矩形,但外层Column有borderRadius(8)圆角。clip(true)让Canvas被裁剪为圆角矩形,避免棋盘四角超出圆角边框。

无clip: 有clip: ┌──────────┐ ╭──────────╮ │ Canvas │ │ Canvas │ │ (直角) │ │ (圆角) │ └──────────┘ ╰──────────╯

布局完整性

整个页面的布局结构:

Column(){// 顶部导航栏 (固定高度56)Row(){...}.height(56)// 状态栏 (自适应)Row(){...}.width('92%')// 状态文字 (自适应)Text(...)// 棋盘 (92%宽度,正方形)Column(){ChessBoardView(...)}.width('92%').borderRadius(8).clip(true)// 底部按钮 (自适应)Row(){...}.width('92%')}.width('100%').height('100%').backgroundColor('#F5F0E8')

垂直空间分配

  • 导航栏:固定56vp
  • 状态栏:内容高度
  • 棋盘:92%宽度的正方形
  • 底部按钮:内容高度
  • 剩余空间:自动分配

在小屏设备上的适配

如果屏幕太小,棋盘可能占满垂直空间。此时需要确保其他元素仍然可见:

Column(){Row(){...}.height(56)// 导航栏固定Row(){...}// 状态栏Text(...)// 状态文字Column(){ChessBoardView(...)}.width('92%')// 棋盘Row(){...}// 底部按钮}

ArkUI的Column默认从上到下排列,如果内容超出屏幕,可以滚动。但五子棋的布局通常不会超出——棋盘宽度92%意味着高度也是92%宽,在大多数设备上都能容纳。

http://www.cnnetsun.cn/news/3252105.html

相关文章:

  • 维度建模实战:电商数仓 6 步构建星型模型,产出 10+ 核心事实/维度表
  • 直流有刷电机驱动方案:TC78H651AFNG与PIC18F85J10实战
  • 02-01-确认环境依赖(全平台发布)
  • 延伸音(Tension)应用指南:属七和弦5种常用Tension音搭配与省略五音原则
  • 【Bug已解决】openclaw network timeout / Connection timed out — OpenClaw 网络超时解决方案
  • 你想不想用一套系统方法,把复杂的医学数据变成清晰结论?
  • QT入门篇
  • ADS131M02与PIC24EP512GU814的高精度ADC系统设计
  • 2026大直径紧固件双叠自锁垫圈怎么选型
  • 使用英特尔流式SIMD扩展优化动画模型的 渲染 流水线
  • MAX77654与PIC18LF46K40的嵌入式电源管理方案
  • 有些软件明明就是财务软件,为什么要说是ERP呢?
  • 终极指南:3分钟掌握Boss-Key老板键,一键保护你的数字隐私空间
  • MP2672A双节锂电池充电管理与STM32控制方案
  • 如何用AI快速移除图片和视频背景?BackgroundRemover完整指南
  • 夏天,死磕这 6 个燃脂行为,体脂率下降 5%!
  • Steam挂刀神器:5分钟搭建你的饰品交易监控系统,发现隐藏利润空间!
  • 终极指南:如何彻底解决MHY扫码器直播监视功能崩溃问题 [特殊字符]
  • 有没有覆盖全学段的靠谱论文 AI?整理一份不白花冤枉钱工具榜单
  • Flink 1.18.0 本地模式性能初探:WordCount作业737ms运行时间分析
  • Go入门:代码格式化与gofmt使用指南
  • TRAE:面向 Vue 3 移动端开发的 AI IDE 工作流
  • Kilo Code:面向工程落地的跨端AI编程加速器
  • EB Tresos 26.2.0 配置 TC389 CAN/LIN:从硬件原理图到通信测试的 7 步实战
  • 【Bug已解决】Claude Code MCP server connection timeout — Claude Code MCP 连接超时解决方案
  • Agent 核心原理:把关键能力落到项目里
  • Caspar:基于符号编程的GPU加速非线性优化库
  • 矢量积法与微分变换法:2 种雅可比矩阵求解方案的 MATLAB 实现与对比
  • BQ25887充电管理芯片与MCU在电池平衡系统中的应用
  • Rhino 8.20 SR20安装配置全指南:兼容性、GPU加速与插件避坑