HarmonyOS鸿蒙Next针对H5的Pura X Max应用适配指南

HarmonyOS鸿蒙Next针对H5的Pura X Max应用适配指南

概述

华为推出的Pura X Max折叠手机,其配有一块宽高比10:14的较宽外屏(折叠态)和一块宽高比14:10的内屏(展开态),相对于直板机,Pura X Max有以下明显特点:

  1. 设备屏幕尺寸可变,具有不同大小和形态的窗口。需要针对不同的应用窗口尺寸,做响应式的页面布局适配。
    • 折叠时,外屏屏幕尺寸,较直板机宽度更宽、高度更矮。
    • 展开后,内屏屏幕尺寸接近于平板,对内容的展示面积增大。
  2. 具有特殊的折叠状态和交互事件。包含三种状态:折叠态、展开态和悬停态。需保障不同状态下的应用体验一致性(如开合连续性)。
    • 展开态:Pura X Max完全展开后的形态。有更大的屏幕尺寸,可充分显示应用内容。
    • 折叠态:Pura X Max折叠后的形态。折叠后屏幕尺寸变小。
    • 悬停态:Pura X Max处于完全展开和折叠的中间状态。可平稳放置。
  3. 设备的折叠态和展开态均配置前置相机和后置相机,但是在不同折叠状态下,可用相机和相机的位置会发生变化。开发相机功能时需考虑摄像头切换与预览流重置。

本文主要内容如下:

  1. 硬件说明 :Pura X Max设备的屏幕与硬件参数详解。
  2. 体验标准 :适配Pura X Max设备的UX设计规范。
  3. 工程管理 :适配所需的工程配置指南。
  4. 窗口适配 :不同使用场景下的窗口适配方案。
  5. 界面开发 :典型布局场景和不同使用形态时的布局建议。
  6. 交互适配 :关键交互能力的适配方法。
  7. 功能开发:Pura X Max设备上相机功能的开发方案。
  8. 常见问题 :适配过程中的典型问题与解决方案。

硬件说明

本章将介绍Pura X Max的屏幕方向、屏幕尺寸、相机硬件参数和折叠状态参数等信息。

屏幕规格属性

以下是Pura X Max在折叠和展开状态下的硬件参数。

折叠态屏幕规格信息

屏幕旋转角度( rotation ) 0(0度) 1(90度) 2(180度) 3(270度)
折叠态示意图
屏幕方向Orientation 竖屏PORTRAIT 横屏LANDSCAPE 反向竖屏PORTRAIT_INVERTED 反向横屏LANDSCAPE_INVERTED
屏幕ID 0 0 0 0
分辨率(px) 1264*1848 1848*1264 1264*1848 1848*1264
分辨率(vp) 459*672 672*459 459*672 672*459
横纵断点 横向断点sm,纵向断点lg 横向断点md,纵向断点sm 横向断点sm,纵向断点lg 横向断点md,纵向断点sm

展开态屏幕规格信息

屏幕旋转角度( rotation ) 0(0度) 1(90度) 2(180度) 3(270度)
展开态示意图
屏幕方向Orientation 竖屏PORTRAIT 横屏LANDSCAPE 反向竖屏PORTRAIT_INVERTED 反向横屏LANDSCAPE_INVERTED
屏幕ID 0 0 0 0
分辨率(px) 1828*2584 2584*1828 1828*2584 2584*1828
分辨率(vp) 664*939 939*664 664*939 939*664
横纵断点 横向断点md,纵向断点lg 横向断点lg,纵向断点sm 横向断点md,纵向断点lg 横向断点lg,纵向断点sm

相机硬件信息

相机有默认的相机镜头安装角度 ,在使用时需要考虑镜头角度和设备的旋转角度,具体定义可参考预览旋转角度

折叠态相机硬件信息

Pura X Max折叠态配置前置相机和后置相机,前置和后置相机镜头安装角度以及需要设置的预览流旋转角度如下:

屏幕旋转角度( rotation ) 0(0度) 1(90度) 2(180度) 3(270度)
折叠态示意图
后置相机镜头安装角度 90度 90度 90度 90度
后置相机预览流旋转角度 90度 180度 270度 0度
前置相机镜头安装角度 270度 270度 270度 270度
前置相机预览流旋转角度 270度 0度 90度 180度

展开态相机硬件信息

Pura X Max展开态配置前置相机和后置相机,前置和后置相机镜头安装角度以及需要设置的预览流旋转角度如下:

屏幕旋转角度( rotation ) 0(0度) 1(90度) 2(180度) 3(270度)
展开态示意图
后置相机镜头安装角度 90度 90度 90度 90度
后置相机预览流旋转角度 90度 180度 270度 0度
前置相机镜头安装角度 270度 270度 270度 270度
前置相机预览流旋转角度 270度 0度 90度 180度

设备特有能力

Pura X Max设备为折叠屏设备,有着独特的折叠能力,在不同的折叠状态下有着不同的折叠属性,Pura X Max产品折叠状态和属性如下:

折叠态 悬停态 展开态
效果图
isFoldable true - -
FoldStatus FOLD_STATUS_FOLDED FOLD_STATUS_HALF_FOLDED FOLD_STATUS_EXPANDED
FoldDisplayMode FOLD_DISPLAY_MODE_MAIN FOLD_DISPLAY_MODE_FULL FOLD_DISPLAY_MODE_FULL

体验标准

应用体验建议分为功能与兼容性、稳定性、性能、功耗、安全和UX六个部分,详细信息如下所示。

名称 简介
应用基础功能和兼容性体验建议 应用与OS兼容、应用与设备兼容、应用升级兼容、功能体验相关等
应用稳定性体验建议 长时间运行故障率(崩溃、冻屏等)、长时间运行内存资源异常
应用性能体验建议 时延、帧率流畅体验和内存占用、CPU占用、线程数等资源占用约束
应用功耗体验建议 后台任务使用、后台硬件器件资源/软件系统资源占用管控,分布式资源占用等
应用安全隐私体验建议 基础安全、恶意软件、应用安全、隐私合规等
应用 UX 体验建议 设计规范、设计约束的符合性,UX精致体验要求等

Pura X Max设备主要在UX上有着特殊的适配体验和建议,下文主要介绍Pura X Max的UX体验建议。

UX体验建议

体验设计标准

折叠屏设备的三种形态分别为折叠态、展开态和悬停态,其多态特性使应用交互与视觉体验显著区别于直板机型,具体体验标准可参考折叠屏应用开发的UX体验建议的体验设计标准章节。

体验设计差异点

Pura X Max设备的折叠态屏幕相较于直板机手机宽度更宽、高度更矮,在适配时要额外考虑布局完整性、沉浸式等设计。可参考折叠态适配建议章节。

Pura X Max设备在折叠态和展开态之间切换时,需要保证当前任务的连续性。切换之前的任务和相关状态能保存、延续,或能够快速恢复,给用户提供连续的体验。不发生闪退、重启等异常。可参考应用界面开合连续适配建议章节。

应用设计最佳实践

根据上述UX体验标准和设计差异点,各垂域应用可根据功能和场景特点进行UX设计,例如影音娱乐类应用主要体验为沉浸式视频播放和互动,需要考虑不同折叠状态的布局完整性,更多垂域设计信息和方案可参考应用设计最佳实践

工程管理

工程配置

在Pura X Max设备上运行的应用,需要在module.json5配置文件的module字段中包含"phone"。更多详情可参考deviceTypes 标签 。更多工程部署的技术细节实现,可参考多设备工程部署

窗口适配

适配设备窗口模式

当前Pura X Max设备支持的窗口模式有全屏窗口模式、分屏窗口模式以及悬浮窗口模式,各模式的详细信息见窗口模式

鸿蒙系统赋能应用可以多窗口形态运行,为确保全场景下的体验,建议开发者使用窗口尺寸适配策略,通过监听窗口状态变化,实现界面布局的动态响应与实时重构。

全屏

Pura X Max上的应用启动时默认全屏模式。

分屏

分屏一般用于两个应用长时间并行使用的场景,例如边看购物攻略边购物的场景;应用也可以主动实现应用内分屏 。Pura X Max的展开态和折叠态均支持分屏,分屏时的窗口尺寸、断点等信息如下表所示,具体适配信息请参考分屏窗口模式适配

设备状态 分屏方式 旋转状态 分屏比例 分屏窗口尺寸(vp) 分屏窗口断点
折叠态 上下分屏 竖屏 1:1 459*312 横向断点sm,纵向断点sm
1:2 459*208 横向断点sm,纵向断点sm
2:1 459*416 横向断点sm,纵向断点md
展开态 左右分屏 横屏 1:1 465*664 横向断点sm,纵向断点lg
1.4:1 543*664 横向断点sm,纵向断点lg
1:1.4 388*664 横向断点sm,纵向断点lg
上下分屏 竖屏 1:1 664*445 横向断点md,纵向断点sm
2:1 664*593 横向断点md,纵向断点
1:2 664*296 横向断点md,纵向断点sm

悬浮窗

悬浮窗一般用于阅读新闻资讯、购物等场景,Pura X Max设备的展开态和折叠态均支持悬浮窗,悬浮窗的窗口尺寸、断点等信息如下表所示,具体适配信息请参考悬浮窗口模式适配

设备状态 悬浮窗类型 悬浮窗口尺寸(vp) 悬浮窗口断点
折叠态 纵向悬浮窗 459*672 横向断点sm,纵向断点lg
横向悬浮窗 459*258 横向断点sm,纵向断点sm
展开态 纵向悬浮窗 459*750 横向断点sm,纵向断点lg
横向悬浮窗 459*258 横向断点sm,纵向断点sm

应用进入悬浮窗模式时,默认以小悬浮窗显示;用户点击后,悬浮窗放大至大悬浮窗状态。上表所列参数均为放大后的悬浮窗口尺寸。

适配设备显示方向

可以通过设置窗口旋转策略(orientation )的方式控制应用的显示方向。窗口旋转策略(orientation)与屏幕旋转角度的关系请参考窗口的 Orientation 和屏幕 rotation 的关系 。Pura X Max开发的横竖屏旋转策略以及适配方案可参考窗口方向

折叠态设备显示方向

屏幕旋转角度( rotation ) 0(0度) 1(90度) 2(180度) 3(270度)
折叠态示意图
默认窗口旋转策略( Orientation ) 未定义UNSPECIFIED 未定义UNSPECIFIED 未定义UNSPECIFIED 未定义UNSPECIFIED
表现形式 竖屏PORTRAIT - - -

展开态设备显示方向

屏幕旋转角度( rotation ) 0(0度) 1(90度) 2(180度) 3(270度)
折叠态示意图
默认窗口旋转策略( Orientation ) 未定义UNSPECIFIED 未定义UNSPECIFIED 未定义UNSPECIFIED 未定义UNSPECIFIED
表现形式 AUTO_ROTATION_RESTRICTED:跟随传感器自动旋转,可以旋转到竖屏、横屏、反向竖屏、反向横屏四个方向,且受控制中心的旋转开关控制 - - -

表格中的参数表示屏幕属性中顺时针旋转角度(rotation)对应的窗口旋转策略。

建议应用在适配Pura X Max展开态界面时,推荐支持横竖屏自动旋转,以提供更灵活、自然的使用体验。展开态界面有足够的空间,无论横屏或竖屏,窗口均能提供充足的显示区域,确保布局自然适配、内容清晰可读,具体适配逻辑可参考兼容多设备上的旋转策略

Pura X Max设备推荐的旋转逻辑如下:

设备状态 窗口全屏时尺寸(vp) 系统是否默认支持横竖屏旋转
折叠态 459*672
展开态 939*664

适配设备沉浸式

沉浸式模式是指通过减少无关元素的干扰,使应用界面更加专注于内容呈现,以提升用户体验的设计模式,详情可参考窗口沉浸式的实现沉浸式效果章节。

Pura X Max设备使用过程中避让区会发生变化,例如:设备旋转导致横竖屏切换,像这种设备使用状态变化引起避让区的变化的适配方案可参考避让处理

在下面几种场景中避让区会发生变化:

  • 窗口模式切换(全屏/悬浮窗/分屏)。
  • 窗口方向变化(横竖屏切换)。
  • 折叠屏状态切换(展开/折叠)。

界面开发

典型布局场景

Pura X Max上典型的响应式布局方式有分栏布局、重复布局、挪移布局和缩进布局。应用可以利用不同的UI组件和断点来实现多样的布局,从而打造丰富的布局场景。

响式布局方式 典型布局场景 实现方案 折叠态效果 展开态效果
重复布局 瀑布流布局 flex布局+断点
轮播布局 动态计算样式+断点
网格布局 MultiGridVue组件+断点
分栏布局 分栏 NavigationContainer/NavigationBar/NavigationContent组件+NavigationMode
挪移布局 图文混排 MultiDiversion组件+断点
自适应导航 flex布局+断点
缩进布局 缩放居中 MultiGridRow/MultiGridCol组件+断点

折叠态适配建议

Pura X Max设备的外屏由于相较于直板机宽度更宽、高度更矮,所以要注重提升内容展示效率,建议使用悬浮组件和滑动隐藏功能,增加内容展示区域。

悬浮导航栏

使用透明磨砂材质的悬浮导航栏,提升可视区域的面积。

开发步骤:

步骤1: 在 Vue3 页面中,使用 fixed 悬浮容器实现“悬浮导航栏”,并将内容区设为可滚动容器(overflow-y: auto)。通过 CSS 的 backdrop-filter(以及 -webkit-backdrop-filter)实现磨砂玻璃材质。

<nav
  ref="bottomNavRef"
  class="bottom-nav"
  :class="{
    'hide-nav': isNavHidden,
    collapsed: isCollapsed
  }"
  @touchstart.passive="onTouchStart"
  @touchmove.prevent="onTouchMove"
  @touchend="onTouchEnd"
  @touchcancel="onTouchEnd"
  @mousedown.left.prevent="onMouseDown"
>
  <span class="nav-sheen" aria-hidden="true"></span>
  <button
    class="nav-item"
    :class="{ active: activeTab === 'home' }"
    @click="onNavClick('home')"
    aria-label="首页"
  >
    <span class="nav-icon"><IconHome /></span>
    <span class="nav-label">首页</span>
  </button>
  <button
    v-show="!isCollapsed"
    class="nav-item"
    :class="{ active: activeTab === 'search' }"
    @click="onNavClick('search')"
    aria-label="探索"
  >
    <span class="nav-icon"><IconSearch /></span>
    <span class="nav-label">探索</span>
  </button>
  <button
    v-show="!isCollapsed"
    class="nav-item"
    :class="{ active: activeTab === 'notify' }"
    @click="onNavClick('notify')"
    aria-label="通知"
  >
    <span class="nav-icon"><IconBell /></span>
    <span class="nav-label">通知</span>
  </button>
  <button
    v-show="!isCollapsed"
    class="nav-item"
    :class="{ active: activeTab === 'profile' }"
    @click="onNavClick('profile')"
    aria-label="我的"
  >
    <span class="nav-icon"><IconProfile /></span>
    <span class="nav-label">我的</span>
  </button>
</nav>

步骤2: 为增强界面的可玩性与功能延展性,可通过“收起/展开”交互,在悬浮导航栏中实现 miniBar 的能力(即:收起态只保留一个入口,展开态展示完整导航)。在 H5 中对应实现方式为:维护 collapsed 状态,并通过 v-show / class 控制导航项显隐与容器形态变化。

const isCollapsed = ref(false)

收起/展开的关键样式(收起态仍保留文字):

.bottom-nav.collapsed {
  padding: 8px 12px;
  border-radius: 28px;
}

步骤3: 在悬浮导航栏上实现“左右滑动收起/展开”的手势交互。H5 中使用 touchstart/touchmove 记录起点坐标,在 touchmove 中判断是否为水平滑动且超过阈值(SWIPE_THRESHOLD),并结合垂直方向比例(VERTICAL_RATIO)避免误触。触发收起/展开后,为避免滑动导致误点击按钮,引入 justSwiped 窗口期抑制点击。

const SWIPE_THRESHOLD = 25
const VERTICAL_RATIO = 1.5
let touchStartX = 0
let touchStartY = 0
let swipeTriggered = false
let justSwiped = false
function suppressClicks() {
  justSwiped = true
  window.setTimeout(() => (justSwiped = false), 350)
}
function onTouchStart(e: TouchEvent) {
  const t = e.touches[0]
  if (!t) return
  touchStartX = t.clientX
  touchStartY = t.clientY
  swipeTriggered = false
}
function onTouchMove(e: TouchEvent) {
  if (swipeTriggered) return
  const t = e.touches[0]
  if (!t) return
  const deltaX = t.clientX - touchStartX
  const deltaY = t.clientY - touchStartY
  const absX = Math.abs(deltaX)
  const absY = Math.abs(deltaY)
  if (absX > SWIPE_THRESHOLD && absX > absY * VERTICAL_RATIO) {
    if (deltaX < 0) {
      if (!isCollapsed.value) {
        isCollapsed.value = true
        swipeTriggered = true
        suppressClicks()
      }
    } else {
      if (isCollapsed.value) {
        isCollapsed.value = false
        swipeTriggered = true
        suppressClicks()
      }
    }
  }
}
function onTouchEnd() {
  swipeTriggered = false
}
function onNavClick(name: 'home' | 'search' | 'notify' | 'profile') {
  if (justSwiped) return
  // 业务处理...
}

滑动隐藏

在用户滑动浏览内容时,自动隐藏底部导航栏与顶部标题栏,以最大化可视区域,提升有效信息的呈现面积。

开发步骤:

步骤1: 在 H5 中,通常由页面自身容器负责滚动(如本示例 content-list),因此需要给滚动容器绑定 scroll 监听。为了避免频繁触发导致卡顿,使用 requestAnimationFrame() 进行节流。

<div class="content-list" ref="contentListRef" @scroll.passive="onScroll">
  <!-- content list -->
</div>

步骤2: 定义导航栏隐藏状态 isNavHidden,并记录上一次滚动位置 lastScrollY。通过一个小阈值 SCROLL_THRESHOLD,过滤轻微抖动。

const contentListRef = ref<HTMLElement | null>(null)
const lastScrollY = ref(0)
const isNavHidden = ref(false)
const SCROLL_THRESHOLD = 8
let ticking = false

步骤3: 在 scroll 回调中判断滚动方向:

向上滚动(内容向上,scrollTop 变大)超过阈值时隐藏;向下滚动超过阈值时显示。使用 requestAnimationFrame() 合并一帧内的多次 scroll 事件,提升性能与跟手性。

function onScroll() {
  const el = contentListRef.value
  if (!el) return

  if (ticking) return
  ticking = true
  requestAnimationFrame(() => {
    const currentY = el.scrollTop
    if (currentY > lastScrollY.value + SCROLL_THRESHOLD) {
      isNavHidden.value = true
    } else if (currentY < lastScrollY.value - SCROLL_THRESHOLD) {
      isNavHidden.value = false
    }
    lastScrollY.value = currentY
    ticking = false
  })
}

步骤4: 将隐藏状态通过 class 映射到悬浮导航栏,并用 transform + opacity 做过渡动画,达到“滑动隐藏/显示”的效果。

<nav
  class="bottom-nav"
  :class="{ 'hide-nav': isNavHidden, collapsed: isCollapsed }"
>
  <!-- ... -->
</nav>

对应样式:

bottom-nav.hide-nav {
  transform: translateX(-50%) translateY(140%);
  opacity: 0;
  pointer-events: none;
  transition: transform 0.4s cubic-bezier(0.3, 0.9, 0.4, 1), opacity 0.3s;
}

步骤5: 为保证首次进入页面的滚动基线正确,在 mounted 阶段用当前 scrollTop 初始化 lastScrollY;同时禁用导航栏的 dragstart,避免桌面端调试时误触拖拽导致交互异常。

onMounted(() => {
  if (contentListRef.value) lastScrollY.value = contentListRef.value.scrollTop
  const nav = bottomNavRef.value
  if (nav) nav.addEventListener('dragstart', (ev) => ev.preventDefault())
})

步骤6: 当设备状态改变时(例如折叠态/展开态、窗口尺寸变化),H5 推荐使用响应式布局与安全区适配:

通过 CSS env(safe-area-inset-*) 或监听 resize/visualViewport 变化,动态调整 bottom 值与 padding,确保悬浮导航不会被系统手势区遮挡,页面布局完整、美观。

.bottom-nav {
  bottom: calc(22px + env(safe-area-inset-bottom, 0px));
}
.content-list {
  padding-bottom: calc(170px + env(safe-area-inset-bottom, 0px));
}

Pura X Max设备折叠态其他的布局建议,可参考直板机竖屏

展开态适配建议

页面布局

Pura X Max展开态横屏时横向断点为lg,纵向断点为sm,提供更宽广的显示视野和更强的信息承载能力。大屏横屏的布局设计与实现可参考图文混排

Pura X Max展开态竖屏时横向断点为md,纵向断点为lg,竖向上提供更大的操作空间。大屏竖屏的布局设计与实现可参考图文混排

交互跟手

Pura X Max设备在展开态时,由于屏幕宽度较大,为了提升交互的体验,建议设置常用组件跟手,方便用户使用时,更加方便快捷的进行交互,提升效率。

跟手弹框:展开状态下中间的弹出组件手指难以触达,弹出组件在点击的位置跟手出现,更易于交互,提升交互效率。

开发步骤:

步骤1: 应用适配响应式布局 ,监听窗口尺寸变化,使用窗口的断点值来适配不同尺寸窗口的页面布局,实现方法可参考通过断点刷新UI 。当窗口尺寸发生变化时,页面应能实时、平滑地适配不同设备或窗口宽度(如Pura X Max从折叠态切换到展开态),从而提供一致且优质的用户体验。

步骤2: 构建UI布局时,使用条件表达式判断当横向断点为sm时(即Pura X Max为折叠态),使用普通居中弹框。否则,在Pura X Max展开态时,使用跟手弹框PopoverDialog ,提升大屏设备下的操作效率。

<script setup>
import { ref } from 'vue'

const visible = ref(false)
const popoverStyle = ref({})
const btnRef = ref(null)   

function handleClick(event) {
  if (widthBp.value === 'sm') {
    popoverStyle.value = {
      position: 'fixed',
      left: '50%',
      top: '50%',
      transform: 'translate(-50%, -50%)'
    }
  } else {
    const rect = btnRef.value.getBoundingClientRect()
  
    popoverStyle.value = {
      position: 'fixed',
      left: rect.left + 'px',
      top: rect.bottom + 8 + 'px',
      transform: 'none'
    }
  }
  
  visible.value = true
}
</script>

跟手半模态:Pura X Max设备展开时,可以考虑跟手半模态窗口或者居中半模态窗口显示,具体根据业务需要选择。

开发步骤:

步骤1: 使用bindSheet 绑定半模态转场时,设置半模态属性preferType为SheetType .POPUP,设置该属性后,半模态弹框在窗口宽度小于600vp的设备上为默认底部弹框(Pura X Max折叠态),在其他设备上为跟手弹框(Pura X Max展开态)。

<script setup>
import { ref } from 'vue'

const showSheet = ref(false)
const sheetStyle = ref({})
const editBtn = ref(null)

function toggleSheet(event) {
  showSheet.value = !showSheet.value

  if (!showSheet.value) return

  if (widthBp.value === 'sm') {
    sheetStyle.value = {
      position: 'fixed',
      left: '0',
      bottom: '0',
      width: '100%'
    }
  } else {
    const rect = editBtn.value.getBoundingClientRect()

    sheetStyle.value = {
      position: 'fixed',
      left: rect.left + 'px',
      top: rect.bottom + 'px',
      width: '320px'
    }
  }
}
</script>

设备悬停态适配建议

Pura X Max设备展开态时,悬停态可以在桌面平稳放置,实现免手持体验,常用于视频通话、播放视频、拍照和听歌等不需要频繁交互的场景。这种状态下,应用需要对中间折痕区域进行避让,并且对上下两个界面进行悬停适配,重新布局。悬停态的实现方案可参考折叠屏悬停态

应用界面开合连续适配建议

开合连续指应用在各种屏幕和窗口状态间切换时页面内容连续,切换之前的任务和相关状态能保存、延续,或能够快速恢复,给用户提供连续的体验。如Pura X Max设备从折叠态到展开态,应用页面内容连续,不发生改变,保持用户的应用体验。主要标准有页面不发生改变和焦点不发生偏移,应用页面和功能相关的开合连续能力建议使用断点实现,并通过window.on(‘windowSizeChange’) 接口监听。

开合页面后刷新UI布局效果

折叠屏开合状态变化时会伴随着窗口尺寸的变化,可通过在原生侧注册on(‘windowSizeChange’)事件监听器来捕获窗口尺寸变化,确保界面始终与当前窗口尺寸保持同步。同时,在H5侧需建立与原生的交互,来获取原生侧更新的断点状态。这一机制能够有效处理设备展开/折叠、分屏模式切换以及屏幕旋转等多种场景下的界面适配需求,为用户提供流畅的折叠屏使用体验。

具体实现方面,对于Arkts部分,需要使用 runJavaScript() 方法来与H5页面进行交互,详细逻辑如下:

addDeviceStatusListener () {
  this.webController.runJavaScript(`
window.dispatchEvent(new CustomEvent('appStatusChange',{ detail: ${JSON.stringify(this.webClassProxy.getDeviceStatus())} }));
`);
  const windowInstance = AppStorage.get<window.WindowStage>('windowStage')?.getMainWindowSync()
  windowInstance?.off('windowSizeChange')
  windowInstance?.on('windowSizeChange', () => {
    this.webController.runJavaScript(`
window.dispatchEvent(new CustomEvent('appStatusChange',{ detail: ${JSON.stringify(this.webClassProxy.getDeviceStatus())} }));
`);
  })
}

对于vue3部分,如何监听断点状态与更新数据的逻辑如下:

const setAppStatus = (nextStatus: AppStatus) => {
  width.value = nextStatus.width;
  height.value = nextStatus.height;
  widthBp.value = nextStatus.widthBp;
  heightBp.value = nextStatus.heightBp;
  deviceFoldStatus.value = nextStatus.foldStatus;
  appOrientation.value = nextStatus.orientation;
  appRotation.value = nextStatus.rotation;
  deivceFoldCreaseRegion.value = nextStatus.foldCreaseRegion;
};

window.addEventListener('appStatusChange', (e: { detail: AppStatus }) => {
  setAppStatus(e.detail);
});

可滑动组件的阅读焦点不偏移

对于折叠屏开合连续使用场景,应用在完成折叠状态切换操作后,需确保H5页面的阅读焦点不发生偏移。目前,这些组件依据折叠状态改变前的滑动偏移量来维持阅读焦点位置,然而,由于折叠状态切换前后,组件内部高度可能发生变化,即便滑动相同的偏移量,也难以达成阅读焦点不偏移的目标。因此,有必要针对上述可滑动组件采取特殊处理措施。

具体的实现思路分为三步:

① 折叠前:记录阅读焦点,找到当前在视口内的元素,记录当前元素和元素在视口中的相对位置(top offset),涉及到的接口为Element.getBoundingClientRect()

② 折叠完成后:重新计算位置,获取元素新的 getBoundingClientRect(),计算它当前在视口中的位置,并计算需要滚动多少距离,涉及到的接口为Element.scrollHeight()

③ 使用 scrollTo 精准恢复至目标位置,涉及到的接口为Element.scrollTo()

例如,可滚动容器为:

<div class="scrollerContainer">
  ...
</div>

记录阅读焦点:

const scroller = document.querySelector(".scrollerContainer");

let currentEl = null;
let currentOffsetTop = 0;

const intersectionObserver = new IntersectionObserver((entries) => {
  for (const entry of entries) {
    if (entry.intersectionRatio > 0) {
      currentEl = entry.target;
      const rect = currentEl.getBoundingClientRect();
      currentOffsetTop = rect.top;
      
      return;
    }
  }
}, {
  root: scroller,
  threshold: 0.5
});

document.querySelectorAll(".observeItem").forEach(el => {
  intersectionObserver.observe(el);
});

折叠完成后恢复位置,在折叠态切换完成后(比如监听 window resize 或设备状态变化回调)执行:

function restoreScrollPosition() {
  if (!currentEl) return;
  
  const rect = currentEl.getBoundingClientRect();
  
  const newTop = rect.top;
  
  const delta = newTop - currentOffsetTop;
  
  const currentScrollTop = scroller.scrollTop;
  
  scroller.scrollTo({
    top: currentScrollTop + delta,
    behavior: "auto"
  });
}

交互适配

Pura X Max设备的交互方式为触控屏,常见的操作有点击、双击、长按、拖拽、滑动等,应用可根据这些操作进行功能适配,详情可参考H5 框架多设备适配交互归一库 。

Pura X Max设备搭载手写笔,支持无感连接与低延迟传输,开盒即用,适用于全局批注、提笔速记及按键遥控等功能场景,实现流畅自然的书写与交互体验。同时系统也提供了Pen kit能力(可参考Pen Kit 简介 ),开发者可灵活接入手写套件、全局取色、一笔成形等接口,提升书写交互的扩展性与创作效率。

常见问题

区分Pura X Max设备外屏与直板机

问题现象:Pura X Max设备外屏(折叠态)和直板机处于同一断点区间,当业务场景需要针对两款设备做对应适配时,需要区分。

解决方案:在横向断点为sm,纵向断点为lg时,可通过额外判断窗口宽度≥440vp,针对Pura X Max设备折叠态单独做个性化适配。

实现不同折叠状态下的页面布局

问题现象:应用页面布局在不同折叠状态下不知道如何适配或适配有问题。

解决方案:推荐使用断点进行页面布局的适配,根据不同断点下页面布局的UX设计,开发不同断点下的页面布局,实现方法可参考断点能力

Pura X Max折叠态时页面弹框有截断/留白

问题现象:应用页面在直板机上弹框正常显示,在Pura X Max折叠态上出现截断/留白。

解决方案:Pura X Max设备的折叠态相较于直板机高度更矮,实现弹框时建议使用如下几种实现方式:

  • 使用自适应布局实现弹框布局,当容器组件尺寸发生变化时,可自动适应调整宽高。
  • H5使用断点判断,弹出框设置不同的高度,避免弹窗内容截断。

应用在Pura X Max上页面有截断/留白

问题现象:应用页面在直板机上显示正常,在Pura X Max折叠态上出现截断/留白。

解决方案:Pura X Max设备的折叠态和展开态,对应不同的窗口尺寸大小。在不同窗口大小上实现页面布局时建议使用响应式布局,根据窗口大小动态调整页面布局,详情可参考自适应导航

无法判断Pura X Max设备进入了自由窗口模式

问题现象:Pura X Max展开态支持悬浮窗和自由窗口(需要开启自由多窗 ),两种窗口下获取windowStatusType 的值都为FLOATING,无法判断是自由窗口还是悬浮窗。

解决方案:在H5场景下,需要通过原生的isInFreeWindowMode() 接口可判断当前是否是自由窗口模式,其中涉及到Arkts与vue3部分。

对于Arkts部分,需要使用 runJavaScript() 方法来与H5页面进行交互,详细逻辑如下:

async FreeWindowModeListener() {
  try {
    this.webController.runJavaScript(`
window.dispatchEvent(new CustomEvent('FreeWindowModeChange',{ detail: ${JSON.stringify(display.getFoldStatus())} }));
`);
    display.off('FreeWindowModeChange')
    // todo
    display.on('FreeWindowModeChange', (data) => {
      this.webController.runJavaScript(`
window.dispatchEvent(new CustomEvent('FreeWindowModeChange',{ detail: ${JSON.stringify(data)} }));
`);
    })

对于vue3部分,如何监听自由窗口模式状态与更新数据的逻辑如下:

window.addEventListener('FreeWindowModeChange', (e: { detail: FreeWindowModeStatus }) => {
  FreeWindowMode.value = e.detail;
});

Pura X Max折叠态时启动页截断

问题现象:应用配置的启动页在Pura X Max折叠态时显示不全。

解决方案:配置增强启动页后资源具备根据窗口尺寸进行缩放的能力,可解决屏幕高度较小时内容显示不全的问题。


更多关于HarmonyOS鸿蒙Next针对H5的Pura X Max应用适配指南的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

HarmonyOS Next 已移除AOSP兼容层,H5适配需使用ArkWeb组件(Chromium内核)。针对Pura X Max大屏/折叠形态,需通过CSS媒体查询或%布局实现自适应。调用系统能力时采用鸿蒙API(如媒体、定位),禁用旧WebView私有接口。确保Web资源符合CSP策略,处理多窗口分屏场景需监听屏幕尺寸变化。

更多关于HarmonyOS鸿蒙Next针对H5的Pura X Max应用适配指南的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


针对Pura X Max的H5适配,核心是响应式布局与状态感知。折叠态外屏宽高比10:14,高度较矮,需特别注意弹窗截断和内容留白,推荐使用悬浮导航栏配合滑动隐藏以扩展可视区,并通过断点(sm/lg)与窗口尺寸(≥440vp)区分直板机做专属调整。展开态横屏断点lg,适合分栏、图文混排等布局,建议弹框和半模态采用跟手定位提升操作效率。开合连续性需通过监听appStatusChange事件获取断点变化,并对可滚动容器做阅读焦点记录与恢复。相机开发需根据折叠/展开态表格设置对应预览流旋转角度(后置90/180/270/0度,前置270/0/90/180度)。全部分屏、悬浮窗等窗口尺寸及断点数据可直接参照表格适配。

回到顶部