harmonyOS 手机,双折叠,平板,PC端屏幕适配

由于HarmonyOS设备的屏幕尺寸和分辨率各不相同,开发者需要采取适当的措施来适配不同的屏幕。

1.EntryAbility.ets文件里:onWindowStageCreate方法里判断设备类型,
如果是pad,需全屏展示(按客户需求来,本次需求按全屏展示),功能实现如下:

	onWindowStageCreate(windowStage: window.WindowStage): void {windowStage.getMainWindow().then((windowClass) => {try {//判断是否是padif(deviceInfo.deviceType == 'tablet') {//pad//pad横屏let orientation = window.Orientation.AUTO_ROTATION_LANDSCAPE_RESTRICTED;let promise = windowClass.setPreferredOrientation(orientation);//如果是pad横屏promise.then(() => {console.info('Succeeded in setting the window orientation.');}).catch((err: BusinessError) => {console.error(`Failed to set the window orientation. Cause code: ${err.code}, message: ${err.message}`);});}}catch (exception) {console.error(`Failed to set window orientation. Cause code: ${exception.code}, message: ${exception.message}`);}// 获取窗口尺寸,存入AppStorageAppStorage.setOrCreate('winWidth', windowClass.getWindowProperties().windowRect.width);AppStorage.setOrCreate('winHeight', windowClass.getWindowProperties().windowRect.height);// 监听窗口尺寸变化windowClass.on('windowSizeChange', (windowSize) => {//监听窗口尺寸变化AppStorage.setOrCreate('winWidth', windowSize.width);//如果窗口变化了,立马更新存储值-宽AppStorage.setOrCreate('winHeight', windowSize.height);//如果窗口变化了,立马更新存储值-高console.log('宽高',String(windowSize.width), String(windowSize.height))//});});// Main window is created, set main page for this abilityconsole.info('onWindowStageCreate');AppStorage.setOrCreate('windowStage',windowStage);AppUtil.init(this.context);try {let windowClass: window.Window = windowStage.getMainWindowSync()AppStorage.setOrCreate('windowClass', windowClass)// 设置窗口全屏windowClass.setWindowLayoutFullScreen(true)let topRect = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_CUTOUT).topRect//获取顶部安全区域let bottomRect = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR).bottomRect//获取底部安全区域// 缓存window窗口对象AppStorage.setOrCreate('windowClass', windowClass);AppStorage.setOrCreate('bottomAreaRectHeight', bottomRect.height);//把height-底部安全区域存储AppStorage.setOrCreate('topAreaRectHeight', topRect.height );//height-顶部安全区域存储this.updateBreakPoint(windowClass.getWindowProperties().windowRect.width, windowClass.getWindowProperties().windowRect.height);//获取窗口的宽 度和高度,计算此时是什么场景:直板机、折叠屏、pad等windowClass.on('windowSizeChange', (windowSize: window.Size) => {console.log('windowSizeChange',windowSize.width, windowSize.height)this.updateBreakPoint(windowSize.width, windowSize.height);//})} catch (exception) {Logger.error(`Failed to obtain the main window. Cause code: ${exception.code}, message: ${exception.message}`);}windowStage.loadContent('pages/LaunchPage', (err, data) => { if (err.code) { Logger.error('Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); return; } }); }private updateBreakPoint(windowWidth: number, windowHeight: number): void {let curBp: string = '';let type = deviceInfo.deviceTypeif (type=='2in1'){//如果是电脑,直接走pad的适配(需要注意,如果是电脑,需要修改一些交互,比如键盘(onKeyEvent事件))AppStorage.setOrCreate('breakPoint', 'xl')return}// 平板,下面的就是根据当前实时屏幕尺寸,计算是处于哪种情况 md-直板机 lg-折叠屏  xl-pad(前面已提到,电脑的UI和pad的UI一致)if(type == 'tablet') {curBp = 'xl'AppStorage.setOrCreate('breakPoint', curBp)} else {console.log('windowHeight/windowWidth',windowWidth, windowHeight, windowHeight/windowWidth > 1.5)let windowWidthVp = windowWidth / display.getDefaultDisplaySync().densityPixels;if (windowWidthVp < 700) {curBp = 'md'} else {curBp = 'lg'}if(windowHeight/windowWidth > 1.5 == true) {curBp = 'md'} else {if(windowHeight<1500) {curBp = 'md'} else {curBp = 'lg'}}let ret: boolean = false;ret = display.isFoldable();console.log("curBp", curBp, windowWidthVp)if(deviceInfo.deviceType == 'phone' && ret == false) {AppStorage.setOrCreate('breakPoint', 'md')} else {AppStorage.setOrCreate('breakPoint', curBp)}}console.log('设备类型', curBp)}//以上的内容都是在应用入口完成,判断好设备类型和视口大小

2.上面是具体说明了判断设备的类型,以及监听窗口大小变化来更改视口类型,下面的内容主要是来介绍如何根据设备类型来适配UI:
其实在鸿蒙里,vp和安卓的dp单位等比,开发过程中,可以直接调成安卓单位的UI来开发,就可以兼容所有的设备(字体和组件宽高比,会自适应),我们需要关注的是,在不同设备下,布局的改变,这个时候需要根据我们计算出来的 breakPoint(xl:电脑,pad , lg:折叠屏 , md:手机)

export class BreakpointConstants{  //BreakpointConstants.ets工具类,md(直板机) lg(折叠屏) xl(电脑,平板)/*** Breakpoints that represent small device types.*/static readonly BREAKPOINT_SM: string = 'sm';/*** Breakpoints that represent middle device types.*/static readonly BREAKPOINT_MD: string = 'md';/*** Breakpoints that represent large device types.*/static readonly BREAKPOINT_LG: string = 'lg';/*** Breakpoints that represent large device types.*/static readonly BREAKPOINT_XL: string = 'xl';/*** Current breakpoints that to query the device types.*/static readonly CURRENT_BREAKPOINT: string = 'currentBreakpoint';/*** Range of the small device width.*/static readonly RANGE_SM: string = '(320vp<=width<520vp)';/*** Range of the middle device width.*/static readonly RANGE_MD: string = '(520vp<=width<840vp)';/*** Range of the large device width.*/static readonly RANGE_LG: string = '(840vp<=width)';/*** Range of the largePlus device width.*/static readonly RANGE_XL: string = '(1700vp<=width<=2720vp)';
}

使用方法如下:

 //声明一个变量,记录当前视口大小(md,lg,xl)(EntryAbility.ets存储值)@StorageLink('breakPoint') breakPoint: string = BreakpointConstants.BREAKPOINT_MD

布局兼容如下:

if (this.breakPoint=='xl') {  // pad 和 PC}else{  // 手机和双折叠}

双折叠适配如下:

①使用Flex布局

Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center, wrap: FlexWrap.Wrap }) {Column(){}.width(this.breakPoint == BreakpointConstants.BREAKPOINT_MD ? '100%' : '49%')Column(){}.width(this.breakPoint == BreakpointConstants.BREAKPOINT_MD ? '100%' : '49%')
}

②使用GridRow布局

 GridRow() {GridCol({ span: { sm: 12, md: 6, lg: 4 } }) {Column(){}}GridCol({ span: { sm: 12, md: 6, lg: 8 } }) {Column(){}}}.width('100%').height('100%')

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/78154.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

跟韩学AiOps系列之2025学MySQL系列_如何在MySQL中开启和提交事务?!

跟韩学AiOps系列之2025学MySQL系列_如何在MySQL中开启和提交事务&#xff1f;! 文章目录 一、事务的基本操作1. 开启事务2. 执行事务内操作3. 提交事务4. 回滚事务 二、验证示例&#xff08;适用于 MySQL 5.7&#xff09;步骤 1&#xff1a;准备测试表和数据步骤 2&#xff1a…

Java生成微信小程序码及小程序短链接

使用wx-java-miniapp-spring-boot-starter 生成微信小程序码及小程序短链接 在pom.xml文件中引入依赖 <dependency><groupId>com.github.binarywang</groupId><artifactId>wx-java-miniapp-spring-boot-starter</artifactId><version>4.7…

如何让通义千问大模型支持结构化输出?

之前的文章提到通义千问API无法通过with_structured_output/json schema的方式支持结构化输出&#xff0c;如果就是想使用通义千问大模型做结构化输出&#xff0c;应该怎么办呢&#xff1f;有两种办法 使用Ollama来运行通义千问大模型 从Ollama博客文章 Structured output 中…

一条 SQL 查询语句是如何执行的(MySQL)

第一讲&#xff1a;一条 SQL 查询语句是如何执行的 总览图示 MySQL 查询的执行流程可以大致分为以下步骤&#xff08;如图所示&#xff09;&#xff1a; 连接器&#xff08;Connection&#xff09;查询缓存&#xff08;Query Cache&#xff0c;MySQL 8.0 已废弃&#xff09;…

汽车OTA在线升级法规分析

摘要 本文介绍了R156法规即《关于批准车辆的软件升级和软件升级管理体系统一规定的法规》、该法规专注于汽车软件升级功能&#xff0c;并为此提出了一系列具体要求&#xff0c;旨在确保软件升级流程的安全性、可控性和合规性&#xff0c;从而顺应汽车行业智能化、联网化的发展趋…

Notepad编辑器实现换行符替换

在不同的Note编辑器中&#xff0c;批量把换行替换为空的方法有所不同&#xff0c;以下是常见编辑器的操作方法&#xff1a; Notepad 打开文件后&#xff0c;按CtrlH打开“查找和替换”对话框&#xff0c;在“查找”字段中输入\r\n&#xff0c;在“替换为”字段中输入一个空格…

Rust多线程性能优化:打破Arc+锁的瓶颈,效率提升10倍

一、引言 在 Rust 开发中&#xff0c;多线程编程是提升程序性能的重要手段。Arc&#xff08;原子引用计数&#xff09;和锁的组合是实现多线程数据共享的常见方式。然而&#xff0c;很多程序员在使用 Arc 和锁时会遇到性能瓶颈&#xff0c;导致程序运行效率低下。本文将深入剖…

【安装指南】Centos7 在 Docker 上安装 RabbitMQ4.0.x

目录 前置知识:RabbitMQ 的介绍 一、单机安装 RabbitMQ 4.0.7版本 1.1 在线拉取镜像 二、延迟插件的安装 2.1 安装延迟插件 步骤一:下载延迟插件 步骤二:将延迟插件放到插件目录 步骤三:启动延迟插件 步骤四:重启 RabbitMQ 服务 步骤五:验收成果 步骤六:手动…

【quantity】5 derive_more库 2.0 版介绍

derive_more 是一个 Rust 过程宏库&#xff0c;旨在通过派生宏自动生成常见 trait 的实现&#xff0c;减少样板代码。2.0 版本带来了多项改进和新特性。 主要特性 1. 支持的 Trait 派生 derive_more 2.0 支持派生以下 trait&#xff1a; 基本操作 trait: Display - 格式化显…

网站备份,网站数据备份的步骤

网站备份&#xff08;尤其是网站数据备份&#xff09;是保障业务连续性、防止数据丢失和应对安全威胁的关键措施。以下是系统化的备份步骤和实施建议&#xff0c;涵盖技术操作、策略规划及常见问题处理&#xff1a; 一、备份前的准备工作 明确备份范围 核心数据&#xff1a;…

OpenCV 图形API(72)图像与通道拼接函数-----根据指定的方式翻转图像(GMat)函数 flip()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 翻转一个2D矩阵&#xff0c;围绕垂直轴、水平轴或同时围绕两个轴。 该函数以三种不同的方式之一翻转矩阵&#xff08;行和列的索引是从0开始的&a…

医生视角下转录组学的生物信息学分析

医生视角下转录组学的生物信息学分析 转录组学的生物信息学分析是医生解决临床与科研问题的有力工具。这里罗列医学转录组学相关的几个概念&#xff0c;从使用者&#xff08;医生&#xff09;的角度看待理解相关技术&#xff0c;为后续使用该技术说明临床和科研问题奠定基础。…

量子机器学习中的GPU加速实践:基于CUDA Quantum的混合编程模型探索

引言&#xff1a;量子机器学习的新范式 在量子计算与经典机器学习交叉融合的前沿领域&#xff0c;量子机器学习&#xff08;Quantum Machine Learning, QML&#xff09;正经历着革命性突破。然而&#xff0c;随着量子比特规模的增长和算法复杂度的提升&#xff0c;传统计算架构…

Matplotlib核心课程-2

4.1 数据加载、储存 4.1.1 从数据文件读取数据 导入支持库&#xff1a; import numpy as np from pandas import Series,DataFrame import pandas as pd 从csv文件读取数据&#xff0c;一般方法&#xff1a; pd.read_csv(../data/ex1.csv,encodinggbk) 从csv文件读取数据&#…

new和malloc的区别

1 语义层级不同&#xff1a;语言机制 vs. 库函数 new / new[] (C 关键字)malloc / calloc / realloc (C 运行时函数)本质语言级运算符&#xff1b;可被重载库函数&#xff1b;无法重载作用分配内存 并调用构造函数仅分配原始字节块&#xff0c;不做初始化&#xff0c;也不调用…

C++11新特性_自动类型推导_auto

在 C11 标准中&#xff0c;auto关键字被赋予了全新且强大的功能&#xff0c;它用于自动类型推导&#xff0c;即编译器能够根据变量的初始化表达式自动确定其类型。 基本语法 使用auto声明变量时&#xff0c;只需给出auto关键字&#xff0c;后面紧跟变量名&#xff0c;并对其进…

[预备知识]6. 优化理论(二)

优化理论 本章节介绍深度学习中的高级优化技术&#xff0c;包括学习率衰减、梯度裁剪和批量归一化。这些技术能够显著提升模型的训练效果和稳定性。 学习率衰减&#xff08;Learning Rate Decay&#xff09; 数学原理与可视化 学习率衰减策略的数学表达&#xff1a; 步进式…

【计算机视觉】语义分割:Mask2Former:统一分割框架的技术突破与实战指南

深度解析Mask2Former&#xff1a;统一分割框架的技术突破与实战指南 技术架构与创新设计核心设计理念关键技术组件 环境配置与安装指南硬件要求安装步骤预训练模型下载 实战全流程解析1. 数据准备2. 配置文件定制3. 训练流程4. 推理与可视化 核心技术深度解析1. 掩膜注意力机制…

数字智慧方案5857丨智慧机场解决方案与应用(53页PPT)(文末有下载方式)

资料解读&#xff1a;智慧机场解决方案与应用 详细资料请看本解读文章的最后内容。 随着科技的飞速发展&#xff0c;智慧机场的建设已成为现代机场发展的重要方向。智慧机场不仅提升了旅客的出行体验&#xff0c;还极大地提高了机场的运营效率。本文将详细解读沃土数字平台在…

【C到Java的深度跃迁:从指针到对象,从过程到生态】第五模块·生态征服篇 —— 第二十章 项目实战:从C系统到Java架构的蜕变

一、跨语言重构&#xff1a;用Java重写Redis核心模块 1.1 Redis的C语言基因解析 Redis 6.0源码核心结构&#xff1a; // redis.h typedef struct redisObject { unsigned type:4; // 数据类型&#xff08;String/List等&#xff09; unsigned encoding:4; // …