【鸿蒙OS】【ArkUI】鸿蒙OS UI布局适配终极攻略

news2024/11/13 15:13:25

鸿蒙OS UI布局适配终极攻略 像素适配大法,此方法也适合Android

ArkUI为开发者提供4种像素单位,框架采用vp为基准数据单位。
vp相当于Android里的dp
fp相当于Android里的sp
官方是如何定义的呢,如下图
在这里插入图片描述

今天我来教大家如何用PX做到ArkUI的终级适配,可以适配所有机型

每台设备的屏幕都有宽高,比如720*1080 就是说这台手机宽有720px,高有1080个px
鸿蒙OS获取宽高的API为

import { display } from '@kit.ArkUI'

export class DisPlayInfo {
    private screenWidth = 0;
    private screenHeight = 0;

    constructor() {
        let screenWidth = display.getDefaultDisplaySync().width;
        let screenHeight = display.getDefaultDisplaySync().height;
    }
}

而我们在写界面时,UI会给我们切一份以宽xxx 高xxx 为基准提供一套设计图给到我们,假设高为:1334 , 宽为:750

import { display } from '@kit.ArkUI'

export class DisPlayInfo {
    private screenWidth = 0;
    private screenHeight = 0;
    private static readonly STANDARD_WIDTH = 750;
    private static readonly STANDARD_HEIGHT = 1334;

    constructor() {
        let screenWidth = display.getDefaultDisplaySync().width;
        let screenHeight = display.getDefaultDisplaySync().height;
    }
}

这个时候我们就可以得到一个比例,UI设计标准和屏幕的一个宽高比

let widthRadio = screenWidth /STANDARD_WIDTH 
let heightRadio = screenHeight /STANDARD_HEIGHT 

这时,假设有一个Btn UI设计图上的宽为220, 高为64,我们就可以计算出这个btn在屏幕上的实际px

let realWidth = widthRadio *btnWidth
let realHeight = heightRadio *btnHeight

得到了实际宽高,我直接填到布局里就OK,完整代码如下,

import { display } from '@kit.ArkUI'

export class DisPlayInfo {
    private screenWidth = 0;
    private screenHeight = 0;
    private static readonly STANDARD_WIDTH = 750;
    private static readonly STANDARD_HEIGHT = 1334;

    constructor() {
        let screenWidth = display.getDefaultDisplaySync().width;
        let screenHeight = display.getDefaultDisplaySync().height;
        this.screenWidth = Math.min(screenWidth, screenHeight);
        this.screenHeight = Math.max(screenWidth, screenHeight);
        console.info("screenWidth " + screenWidth + " screenHeight " + this.screenHeight)
    }

    public getWidth(width: number): PX {
        let realWidth: number = Math.floor(width * this.screenWidth / DisPlayInfo.STANDARD_WIDTH)
        return `${realWidth}px`
    }

    public getHeight(height: number): PX {
        return `${Math.floor((this.screenHeight / DisPlayInfo.STANDARD_HEIGHT) * height)}px`
    }
}

实战

displayInfo = new DisPlayInfo()

build() {
        Row() {
            RelativeContainer() {
                Image($r('app.media.xxx'))
                    .width(this.displayInfo.getWidth(628))
                    .height(this.displayInfo.getWidth(480))
                    .alignRules({
                        top: { anchor: "__container__", align: VerticalAlign.Top },
                        left: { anchor: "__container__", align: HorizontalAlign.Start },
                        right: { anchor: "__container__", align: HorizontalAlign.End },
                        bottom: { anchor: "__container__", align: VerticalAlign.Bottom }
                    })
                    .id("bg_interior_img")
                // 标题
                Text($r('app.string.xxx'))
                    .fontSize(this.displayInfo.getWidth(34))
                    .fontColor($r('app.color.xxx'))
                    .margin({ top: this.displayInfo.getWidth(48) })
                    .textAlign(TextAlign.Center)
                    .alignRules({
                        top: { anchor: "bg_interior_img", align: VerticalAlign.Top },
                        left: { anchor: "bg_interior_img", align: HorizontalAlign.Start },
                        right: { anchor: "bg_interior_img", align: HorizontalAlign.End },
                    })
                    .id("title_text")

                // 取消
                Text($r('app.string.xxx'))
                    .width(this.displayInfo.getWidth(216))
                    .height(this.displayInfo.getWidth(64))
                    .margin({ left: this.displayInfo.getWidth(86), bottom: this.displayInfo.getWidth(55) })
                    .textAlign(TextAlign.Center)
                    .backgroundImage(this.subBtnBackgroundImg)
                    .backgroundImageSize({ width: '100%', height: '100%' })
                    .fontSize(this.displayInfo.getWidth(30))
                    .fontColor($r('app.color.xxx'))
                    .alignRules({
                        left: { anchor: "bg_interior_img", align: HorizontalAlign.Start },
                        bottom: { anchor: "bg_interior_img", align: VerticalAlign.Bottom },
                    })
                   
                    .onClick(() => {
                       
                    })
                    .id("btn_reject")

                // 确定
                Text($r('app.string.xxx'))
                    .width(this.displayInfo.getWidth(216))
                    .height(this.displayInfo.getWidth(64))
                    .margin({ right: this.displayInfo.getWidth(86), bottom: this.displayInfo.getWidth(55) })
                    .textAlign(TextAlign.Center)
                    .backgroundImage(this.mainBtnBackgroundImg)
                    .backgroundImageSize({ width: '100%', height: '100%' })
                    .fontSize(this.displayInfo.getWidth(30))
                    .fontColor($r('app.xxx'))
                    .alignRules({
                        right: { anchor: "bg_interior_img", align: HorizontalAlign.End },
                        bottom: { anchor: "bg_interior_img", align: VerticalAlign.Bottom },
                    })
                    .onClick(() => {
              
                    })
                // 内容
                Text($r('app.string.xxx'))
                    .fontSize(this.displayInfo.getWidth(22))
                    .fontColor($r('app.color.xxx'))
                    .margin({ left: this.displayInfo.getWidth(86), right: this.displayInfo.getWidth(86) })
                    .textAlign(TextAlign.Start)
                    .alignRules({
                        top: { anchor: "title_text", align: VerticalAlign.Bottom },
                        left: { anchor: "title_text", align: HorizontalAlign.Start },
                        right: { anchor: "title_text", align: HorizontalAlign.End },
                        bottom: { anchor: "btn_reject", align: VerticalAlign.Top },
                    })
            }
        }
    }

显示效果,测试多台的机显示基本一样

在这里插入图片描述

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

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

相关文章

【python】Pandas 运行报错分析:KeyError: Label not found

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…

Docker基本讲解及演示

Docker安装教程 Docker安装教程 1、Docker介绍 Docker是一个开源的应用容器引擎,允许开发者将应用程序及其依赖项打包成一个轻量级、可移植的容器,然后发布到任何支持 Docker 的环境中运行,无论是开发机、测试机还是生产环境。 Docker基于…

CentOS 7 网络配置

如想了解请查看 虚拟机安装CentOS7 第一步:查看虚拟机网络编辑器、查看NAT设置 (子网ID,网关IP) 第二步:配置VMnet8 IP与DNS 注意事项:子网掩码与默认网关与 第一步 保持一致 第三步:网络配置…

EXCEL VBA工程密码破解 工作表保护破解

这里写目录标题 破解Excel宏工程加密方法一 新建破解宏文件方法二 修改二进制文件 破解工作表保护引用 破解Excel宏工程加密 如图所示 白料数据处理已工程被加密。 方法一 新建破解宏文件 1 创建一个XLSM文件,查看代码 ALTF11 2 新建一个模块,“插…

打包一个自己的Vivado IP核

写在前面 模块复用是逻辑设计人员必须掌握的一个基本功,通过将成熟模块打包成IP核,可实现重复利用,避免重复造轮子,大幅提高我们的开发效率。 接下来将之前设计的串口接收模块和串口发送模块打包成IP核,再分别调用…

Vue+Echarts做图表展示

1.Echarts安装 终端运行安装命令: npm install echarts -s 在main.js做全局引用: //引入echarts import * as echarts from echarts //vue全局注入echarts Vue.prototype.$echarts echarts; 2.页面使用Echarts画柱状图和饼图 效果: 代码展…

Qt各个版本安装的保姆级教程

文章目录 前言Qt简介下载Qt安装包安装Qt找到Qt的快捷方式总结 前言 Qt是一款跨平台的C图形用户界面应用程序开发框架,广泛应用于桌面软件、嵌入式软件、移动应用等领域。Qt的强大之处在于其高度的模块化和丰富的工具集,可以帮助开发者快速、高效地构建出…

esplice老项目(非maven)导入idea问题

解决导入idea显示不正常 老项目导入idea后,显示为如下所示: 显示的不太正常,正常显示为下面这个样子: 解决 非老项目 idea的项目中所有的文件全部变成了.java(已解决) 老项目 以下内容参考:idea导入项目后java文…

阿里云CDN架构技术(一)

CDN补充 cdn内容分发网络(content delivery network,cdn) 构建在互联网TCP/IP四层模型之上对用户透明的覆盖网。 该网络通过全球范围内分布式部署边缘服务器,将互联网内容从互联网中心缓存到靠近用户的边缘服务器上,…

SymPy,一个可以做数学题的Python库,如何使用SymPy进行微积分计算?

SymPy 是一个 Python 库,用于符号数学。这意味着 SymPy 可以帮助用户执行从基本代数到微积分、方程求解、积分、极限、级数、几何、组合数学、离散数学和量子物理等广泛的数学计算。它允许用户以完全符号化的方式处理数学表达式,而无需将问题转换为数值近…

大模型的“幻觉”克星!被低估的RAG技术

1 RAG与大模型、Prompt、微调的关系 本文主要带大家深入学习一下最近AI领域的重要技术RAG,本文致力于用大白话给大家说明白RAG,但是还是需要一些大模型和微调有关的领域名词有一些基本的了解,大家选择性阅读哦!在进行正文学习之前我们先用一…

Unity Meta Quest 开发:如何在每只手指上添加 Poke 交互

XR 开发社区: SpatialXR社区:完整课程、项目下载、项目孵化宣发、答疑、投融资、专属圈子 找到玩家物体 OVRCameraRig 下的子物体 HandInteractorsRight/Left(分别管理左右手的 Interactor)下的 HandPokeInteractor 子物体&#x…

Java语言程序设计——篇五

数组 概述数组定义实例展示实战演练 二维数组定义数组元素的使用数组初始化器实战演练:矩阵计算 💫不规则二维数组实战演练:杨辉三角形 概述 ⚡️数组是相同数据类型的元素集合。各元素是有先后顺序的,它们在内存中按照这个先后顺…

计算机的错误计算(三十三)

摘要 计算机的错误计算(三十二)展示了 Python的 math库中 exp(x)的计算精度问题。本节讨论 Python 的 torch 库中的 exp(x)的计算精度问题。结果显示:与 math 库中的函数输出值具有同样的错误数字个数。 不妨仍然取(二十八&…

华为云.VPC关联概念与对等连接实践

云计算.华为云 VPC关联概念与对等连接实践 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/q…

使用SpringCloud搭建分布式配置中心

在现代的分布式系统中,配置管理是一个非常重要的组成部分。传统的做法是将配置文件放在每个服务的本地进行配置,这样的做法在规模较小的系统中还能够接受,但是当系统规模逐渐扩大时,配置管理将变得非常困难,容易出错。…

Autosar Dcm配置-0x28服务ComControl-基于ETAS软件

文章目录 前言DcmDcmDsdDcmDspBswMBswMModeRequestPortBswMModeConditionBswMLogicalExpressionBswMActionBswMActionListBswMRule总结前言 0x28服务主要用来控制非诊断报文的通讯,一般在刷写预编程过程中,用来禁止APP的通信报文,可以减少总线负载率,提高刷写成功率。本文…

vue3-tree-org实现带照片的组织架构图

官方文档&#xff1a;vue3-tree-org 显示照片需要注意的地方 使用步骤 下载 npm install vue3-tree-org --save 在main.js中引入 import "vue3-tree-org/lib/vue3-tree-org.css"; import vue3TreeOrg from vue3-tree-org;app.use(vue3TreeOrg) 实现代码 <tem…

【简历】郑州某二本学院:前端秋招简历指导,简历通过率接近于0

注&#xff1a;为保证用户信息安全&#xff0c;姓名和学校等信息已经进行同层次变更&#xff0c;内容部分细节也进行了部分隐藏 简历说明 这是一份二本前端同学的校招简历。25届的二本同学求职方向主要是在小公司&#xff0c;但是这个同学他故意把学校放在简历最后&#xff0…

R包:DiagrammeR流程图

介绍 DiagrammeR 依赖于图形描述语言 Graphviz&#xff0c;可以通过 R 包 igraph 和 visNetwork 访问。DiagrammeR 通过将有效的图规范以 DOT 语言的形式传递给 grViz() 函数来输出图。 加载R包 采用DiagrammeRR包&#xff0c;它提供了以下函数&#xff1a; 使用create_grap…