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

Harmony OS“一多” 详解:基于窗口变化的断点自适应实现

一、一多开发核心概念(1+8+N模式)

        目标:一次开发多端部署 解决的问题:
                1、界面级一多:适配不同屏幕尺寸
                2、功能级一多:设备功能兼容性处理(CanIUser)
                3、工程级一多:项目架构管理(三成架构HAP、HAR、HSP)

二、界面级一多解决方法

1、自适应布局

能力

核心属性/组件

代码示例

拉伸

flexGrow/flexShrink

.flexGrow(1).flexShrink(1)

均分

justifyContent: SpaceEvenly

Row().justifyContent(FlexAlign.SpaceEvenly)

占比

layoutWeight 或百分比宽高

.width('50%').layoutWeight(1)

缩放

aspectRatio

.aspectRatio(1.5)

延伸

List/Scroll + Row

List().listDirection(Axis.Horizontal)

隐藏

displayPriority

.displayPriority(2)

折行

FlexWrap.Wrap

Flex({ wrap: FlexWrap.Wrap })

2、响应式布局

        2-1、断点系统

断点

范围(vp)

典型设备

xs

[0, 320)

智能手表

sm

[320, 600)

手机竖屏

md

[600, 840)

折叠屏/横屏

lg

[840, +∞)

平板/PC

// 在Ability中监听窗口变化
windowObj.on('windowSizeChange', (size) => {
  const widthVp = size.width / density;
  AppStorage.set('currentBreakpoint', calculateBreakpoint(widthVp));
});

2-2、媒体查询

// 创建监听器
const listener = mediaquery.matchMediaSync('(320vp<=width<600vp)');
// 注册回调
listener.on('change', (res) => {
  if (res.matches) AppStorage.set('breakpoint', 'sm');
});
// 移除监听
listener.off('change');

2-3栅格布局

GridRow({
  columns: { sm: 4, md: 8, lg: 12 },
  gutter: 10
})
/*--------------------------------------------*/
//GridRow:定义行布局规则
GridRow({
  columns: { sm: 4, md: 8, lg: 12 },
  gutter: 10
})
/*--------------------------------------------*/
//GridCol:定义列占比与偏移
GridCol({
  span: { sm: 2, md: 4 },
  offset: { md: 1 }
})

场景

推荐方案

优势

微调元素尺寸

自适应布局(占比/拉伸)

简单高效,代码侵入性低

多设备显隐逻辑

响应式布局(媒体查询)

精确控制不同断点下的UI表现

复杂多列布局

栅格系统

内置响应规则,维护性强

全局断点状态管理

BreakpointSystem工具

统一管理断点,避免重复监听

3、界面级一多断点
import window from '@ohos.window'
import display from '@ohos.display'
import UIAbility from '@ohos.app.ability.UIAbility'

export default class EntryAbility extends UIAbility {
  private windowObj?: window.Window
  private curBp: string = ''
  //...
  // 根据当前窗口尺寸更新断点
  private updateBreakpoint(windowWidth: number) :void{
    // 将长度的单位由px换算为vp
    let windowWidthVp = windowWidth / display.getDefaultDisplaySync().densityPixels
    let newBp: string = ''
    if (windowWidthVp < 320) {
      newBp = 'xs' // 超小屏
    } else if (windowWidthVp < 600) {
      newBp = 'sm' // 小屏
    } else if (windowWidthVp < 840) {
      newBp = 'md' // 中屏
    } else {
      newBp = 'lg' // 大屏
    }
    if (this.curBp !== newBp) {
      this.curBp = newBp
      // 使用状态变量记录当前断点值
      AppStorage.setOrCreate('currentBreakpoint', this.curBp)
    }
  }

  onWindowStageCreate(windowStage: window.WindowStage) :void{
    windowStage.getMainWindow().then((windowObj) => {
      this.windowObj = windowObj
      // 获取应用启动时的窗口尺寸
      this.updateBreakpoint(windowObj.getWindowProperties().windowRect.width)
      // 注册回调函数,监听窗口尺寸变化
      windowObj.on('windowSizeChange', (windowSize)=>{
        this.updateBreakpoint(windowSize.width)
      })
    });
   // ...
  }
   
  //...
}
  1. 技术栈
    • 鸿蒙特定 API:基于鸿蒙系统的@ohos.window@ohos.display@ohos.app.ability.UIAbility模块进行开发,充分利用鸿蒙系统提供的窗口管理、显示信息获取以及应用能力相关的原生 API。
  2. 核心点
    • 窗口尺寸监听:在onWindowStageCreate方法中,通过windowStage.getMainWindow().then获取主窗口对象,随后利用windowObj.on('windowSizeChange', ...)注册回调函数,实时监听窗口尺寸变化,这是实现屏幕适配的关键起始步骤。
    • 断点计算与更新updateBreakpoint方法将获取到的窗口宽度从像素(px)换算为虚拟像素(vp),根据不同的vp范围确定对应的断点值(xssmmdlg)。当计算出的新断点与当前断点不同时,更新当前断点并通过AppStorage.setOrCreate方法记录在状态变量中,以便应用其他部分根据断点值进行不同的布局或功能调整。

三、总结 

        本文围绕 “一多开发” 这一核心概念展开,着重探讨了其在界面级的实现方式。“一多开发” 旨在达成一次开发多端部署,解决界面、功能及工程等层面的适配与管理问题。

        在界面级,通过自适应布局、响应式布局两种主要方式实现对不同屏幕尺寸的适配。自适应布局借助如flexGrowjustifyContent等多种属性和组件,能简单高效地微调元素尺寸;响应式布局则通过断点系统、媒体查询和栅格布局,可更精准地控制不同设备下的 UI 表现,满足多设备显隐逻辑和复杂多列布局等场景需求。

        结合提供的鸿蒙开发代码示例,其基于鸿蒙特定 API 实现了窗口尺寸监听与断点计算更新,这是界面适配的关键技术点。通过监听窗口变化获取尺寸信息,换算为vp后确定断点值并记录,为应用根据不同屏幕尺寸调整布局和功能提供依据。

http://www.dtcms.com/a/112718.html

相关文章:

  • 类的基本概念
  • 深入剖析丝杆升降机工作原理,解锁工业传动奥秘
  • 【C++】C++11<包装器没写>
  • 动态规划1——斐波那契数列模型——第 N 个泰波那契数
  • 算法题(117):字符串的展开
  • 16.2Linux自带的LED灯驱动实验(详细编写)_csdn
  • OJ系统C端UI自动化测试
  • Kubernetes 集群搭建(一):从环境准备到 Calico 网络插件部署
  • 自定义填充 cad
  • SpringCloudGateWay
  • spring security 过滤器链相关初始化过程
  • 使用 Elastic 实现端到端的大语言模型(LLM)可观测性:洞察生成式 AI 应用这个不透明的世界
  • C/C++测试框架googletest使用示例
  • 用HTML.CSS.JavaScript实现一个贪吃蛇小游戏
  • 基于Go语言实现一个网络聊天室(连接Redis版)
  • Kubernetes集群管理详解:从入门到精通
  • Eliet Chat开发日志:信令服务器注册与通信过程
  • JAVA单例模式
  • 2023-2024总结记录
  • leetcode二叉树刷题调试不方便的解决办法
  • 【Redis】服务端高并发分布式结构
  • 使用Scrapy官方开发的爬虫部署、运行、管理工具:Scrapyd
  • 网安小白筑基篇五:web后端基础之PHP
  • Springboot----@Role注解的作用
  • C++设计模式-解释器模式:从基本介绍,内部原理、应用场景、使用方法,常见问题和解决方案进行深度解析
  • 【Python使用】嘿马推荐系统全知识和项目开发教程第2篇:1.4 案例--基于协同过滤的电影推荐,1.5 推荐系统评估【附代码
  • 【Android】界面布局-线性布局LinearLayout-例子
  • 编程能力的跃迁时刻:技术革命与认知重构的交响曲
  • MySQL索引原理:从B+树手绘到EXPLAIN
  • 合肥京东运营服务商TOP5推荐