典型问题:

  • 在手机上表现正常,到了平板/PC 上布局错乱、留白严重或内容过小。
  • 键盘输入、鼠标点击、触摸滑动在不同设备/形态下行为不一致。
  • 不清楚在混合框架下,哪些适配应交给 Web,哪些应交给 ArkTS/原生。

本文结合 2048 示例,从布局适配、输入适配和窗口/形态变化三个角度,梳理 HarmonyOS + Cordova 项目的多端适配问题及解决方法。代码约占 3/10。


1. 多端适配的分层思路

在混合应用中,多端适配可以分三层考虑:

  • ArkTS 层
    • 窗口尺寸、方向、设备形态(手机/平板/PC);
    • 是否启用多窗口、分屏等能力;
  • Cordova/WebView 层
    • WebView 占屏比例、安全区处理;
  • Web 前端层
    • 响应式布局(CSS Grid/Flex);
    • 输入事件(键盘/鼠标/触摸)统一抽象。

1.1 分层示意图

窗口/方向

输入事件/布局反馈

ArkTS 层: Index/MainPage

Cordova/WebView 容器

Web 层: index.html + CSS + JS


2. 布局适配:让 WebView 和页面“占满且合理”

2.1 ArkTS 层确保 WebView 占满可用区域

Index.ets 中,我们通常这样写:

build() {
  RelativeContainer() {
    MainPage({
      isWebDebug: false,
      cordovaPlugs: this.cordovaPlugs
    });
  }
  .height('100%')
  .width('100%')
}

注意

  • 确保外层容器不要设置固定像素高度/宽度,否则在平板/PC 窗口中会出现巨大的空白区域。

2.2 Web 层使用响应式布局

2048 示例中采用 CSS Grid 实现棋盘布局:

.board { background: var(--board); padding: 10px; border-radius: 10px; position: relative; }
.grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.cell {
  background: var(--cell);
  border-radius: 6px;
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 30px;
}

实践建议

  • 使用 aspect-ratiovw/vh 或媒体查询,为不同屏幕宽度调整棋盘大小和字体;
  • 保持棋盘区域居中,余下空间用于其他信息(如分数、设置等)。

3. 输入适配:键盘、鼠标与触摸

2048 游戏支持键盘方向键和触摸滑动,典型事件代码示意:

// 键盘输入
window.addEventListener('keydown', (e) => {
  let moved = false;
  switch (e.key) {
    case 'ArrowLeft':
      e.preventDefault(); moved = moveLeft(); break;
    case 'ArrowRight':
      e.preventDefault(); moved = moveRight(); break;
    case 'ArrowUp':
      e.preventDefault(); moved = moveUp(); break;
    case 'ArrowDown':
      e.preventDefault(); moved = moveDown(); break;
    default:
      return;
  }
  afterMove(moved);
});

建议

  • PC 端:
    • 继续保留键盘支持;
    • 可增加 WASD 或鼠标点击方向按钮。
  • 移动端:
    • 保留触摸手势,设置合适的滑动阈值(如 30px)减少误触;
    • touchstart/touchmove/touchend 事件间注意 passive 选项和滚动冲突。

3.1 将输入逻辑集中封装

为了减少平台差异对业务逻辑的影响,建议将多种输入统一映射为“方向事件”:

function handleDirection(dir) {
  let moved = false;
  if (dir === 'left') moved = moveLeft();
  if (dir === 'right') moved = moveRight();
  if (dir === 'up') moved = moveUp();
  if (dir === 'down') moved = moveDown();
  afterMove(moved);
}

然后在键盘、触摸、按钮点击中分别调用 handleDirection,而不是到处直接调用 moveLeft/moveRight


4. 窗口大小变化与形态切换

在 HarmonyOS 上,不同设备/形态可能支持窗口调整、分屏、多窗口等能力。对混合应用来说,需要关注:

  • ArkTS 层是否能感知窗口变化;
  • Web 层是否能根据 viewport 变化重新布局。

4.1 Web 层监听窗口大小变化

简单的做法是在 JS 中监听 resize

window.addEventListener('resize', () => {
  console.log('[2048] window resized:', window.innerWidth, window.innerHeight);
  // 根据尺寸调整棋盘缩放/字体大小
});
``>

配合 CSS 媒体查询,可以为不同宽度区间设置不同的样式。

---

## 5. 常见适配问题与解决思路

### 问题 1:平板上棋盘太小/太大

**排查点**- 是否使用了硬编码像素值;
- 是否为平板/大屏设置了专门的样式。

**解决方案**- 使用相对单位(如 `%`, `vw`, `vh`);
- 利用媒体查询:

```css
@media (min-width: 800px) {
  .cell { font-size: 40px; }
}

问题 2:PC 上缺少触摸事件,移动端缺少键盘事件

建议

  • PC 以键盘/鼠标为主,移动端以触摸为主,但可以适度保留两种输入以增强兼容性;
  • 在 Web 入口文案中明确提示支持的操作方式(键盘/触摸/鼠标)。

问题 3:多窗口/分屏时布局异常

思路

  • 激活 resize 监听,并在每次变化后重新计算棋盘容器尺寸;
  • 避免在 JS 中写死容器宽高,将控制权交给 CSS。

6. 多端适配排查流程图

某端显示或输入异常

WebView 是否占满容器?

检查 Index/MainPage 外层布局尺寸

CSS 是否使用响应式布局?

改用 Grid/Flex/相对单位

输入逻辑是否统一抽象?

抽象 handleDirection 等统一入口

是否处理窗口/形态变化?

监听 resize+媒体查询, 调整布局


7. 小结

  • 在 HarmonyOS + Cordova 混合框架下,多端适配的关键是“分层思考”:
    • ArkTS 管窗口与形态;
    • Cordova/WebView 管容器占屏;
    • Web 层用响应式布局和统一输入抽象。
  • 多端适配问题往往不是某一层单独造成的,而是多层配置/逻辑叠加的结果;
  • 通过“统一输入入口 + 响应式布局 + 监听窗口变化”这三步,可以显著减轻在不同设备/形态下调试的复杂度。

欢迎加入开源鸿蒙PC社区:https://harmonypc.csdn.net/

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐