【鸿蒙HarmonyOS开发笔记】使用媒体查询(mediaquery)实现不同设备响应式布局

概述

媒体查询作为响应式设计的核心,在移动设备上应用十分广泛。媒体查询可根据不同设备类型或同设备不同状态修改应用的样式。媒体查询常用于下面两种场景:

针对设备和应用的属性信息(比如显示区域深浅色分辨率),设计出相匹配的布局

当屏幕发生动态改变时(比如分屏横竖屏切换),同步更新应用的页面布局


速食版

1.定义好媒体查询的条件和保存的字段

export default class BreakpointConstants{//屏幕大小尺寸static readonly BREAKPOINT_SM:string = 'sm'static readonly BREAKPOINT_MD:string = 'md'static readonly BREAKPOINT_LG:string = 'lg'//保存进AppStorage的字段static readonly CURRENT_BREAKPOINT:string = 'currentBreakpoint'//媒体查询条件static readonly RANGE_SM:string = "(320vp <= width < 600vp)"static readonly RANGE_MD:string = "(600vp <= width < 840vp)"static readonly RANGE_LG:string = "(840vp <= width )"}

2.封装好工具类,设置查询条件以及监听句柄


import mediaQuery from '@ohos.mediaquery'
import BreakpointConstants from '../constants/BreakpointConstants'export default class BreakpointSystem{private smListener:mediaQuery.MediaQueryListener  = mediaQuery.matchMediaSync(BreakpointConstants.RANGE_SM)private mdListener:mediaQuery.MediaQueryListener  = mediaQuery.matchMediaSync(BreakpointConstants.RANGE_MD)private lgListener:mediaQuery.MediaQueryListener  = mediaQuery.matchMediaSync(BreakpointConstants.RANGE_LG)smListenerCallback(result:mediaQuery.MediaQueryResult){if (result.matches) {AppStorage.SetOrCreate(BreakpointConstants.CURRENT_BREAKPOINT,BreakpointConstants.BREAKPOINT_SM)}}mdListenerCallback(result:mediaQuery.MediaQueryResult){if (result.matches) {AppStorage.SetOrCreate(BreakpointConstants.CURRENT_BREAKPOINT,BreakpointConstants.BREAKPOINT_MD)}}lgListenerCallback(result:mediaQuery.MediaQueryResult){if (result.matches) {AppStorage.SetOrCreate(BreakpointConstants.CURRENT_BREAKPOINT,BreakpointConstants.BREAKPOINT_LG)}}register(){this.smListener.on("change",this.smListenerCallback.bind(this))this.mdListener.on("change",this.mdListenerCallback.bind(this))this.lgListener.on("change",this.lgListenerCallback.bind(this))}unregister(){this.smListener.off("change",this.smListenerCallback.bind(this))this.mdListener.off("change",this.mdListenerCallback.bind(this))this.lgListener.off("change",this.lgListenerCallback.bind(this))}}

3.使用封装的媒体查询工具类

import BreakpointSystem from '../common/utils/BreakpointSystem'
import BreakpointConstants from '../common/constants/BreakpointConstants'@StorageProp("currentBreakpoint") currentBreakpoint:string = BreakpointConstants.BREAKPOINT_SM
private breakpointSystem:BreakpointSystem = new BreakpointSystem()chooseBarPosition(){let p = {sm: BarPosition.End,md: BarPosition.Start,lg: BarPosition.Start,}return p[this.currentBreakpoint]}aboutToAppear(){this.breakpointSystem.register()}aboutToDisappear(){this.breakpointSystem.unregister()}build() {//根据不同的屏幕尺寸来改编barPosition的值实现响应式布局Tabs({ barPosition: this.chooseBarPosition() }) {TabContent() {RecordIndex()}.tabBar(this.myTabar($r("app.string.tab_record"),$r("app.media.ic_calendar"),0))TabContent() {Text("发现")}.tabBar(this.myTabar($r("app.string.tab_discover"),$r("app.media.discover"),1))TabContent() {Text("我的主页")}.tabBar(this.myTabar($r("app.string.tab_user"),$r("app.media.ic_user_portrait"),2))}.width("100%").height("100%")//根据不同的屏幕尺寸来改编vertical的值实现横向布局与纵向布局的切换.vertical({sm:false,md:true,lg:true,}[this.chooseBarPosition()])}

引入与使用流程

媒体查询通过mediaquery模块接口,设置查询条件并绑定回调函数,在对应的条件的回调函数里更改页面布局或者实现业务逻辑,实现页面的响应式设计。具体步骤如下:

首先导入媒体查询模块

import mediaquery from '@ohos.mediaquery';

通过matchMediaSync接口设置媒体查询条件,保存返回的条件监听句柄listener。例如监听横屏事件

let listener = mediaquery.matchMediaSync('(orientation: landscape)');

给条件监听句柄listener绑定回调函数onPortrait,当listener检测设备状态变化时执行回调函数。在回调函数内,根据不同设备状态更改页面布局或者实现业务逻辑

onPortrait(mediaQueryResult) {if (mediaQueryResult.matches) {// do something here} else {// do something here}
}listener.on('change', onPortrait);

语法规则包括媒体类型(media-type)、媒体逻辑操作(media-logic-operations)和媒体特征(media-feature

[media-type] [media-logic-operations] [(media-feature)]

例如:

screen and (round-screen: true) :表示当设备屏幕是圆形时条件成立。
(max-height: 800) :表示当高度小于等于800vp时条件成立。
(height <= 800) :表示当高度小于等于800vp时条件成立。
screen and (device-type: tv) or (resolution < 2) :表示包含多个媒体特征的多条件复杂语句
当设备类型为tv或设备分辨率小于2时条件成立。

媒体类型(media-type

screen:按屏幕相关参数进行媒体查询

媒体逻辑操作(media-logic-operations
媒体逻辑操作符:and、or、not、only用于构成复杂媒体查询,也可以通过comma(, )将其组合起来,详细解释说明如下

媒体逻辑操作符

and

将多个媒体特征(Media Feature)以“与”的方式连接成一个媒体查询,只有当所有媒体特征都为true,查询条件成立。另外,它还可以将媒体类型和媒体功能结合起来。例如:screen and (device-type: wearable) and (max-height: 600) 表示当设备类型是智能穿戴且应用的最大高度小于等于600个像素单位时成立。

or

将多个媒体特征以“或”的方式连接成一个媒体查询,如果存在结果为true的媒体特征,则查询条件成立。例如:screen and (max-height: 1000) or (round-screen: true) 表示当应用高度小于等于1000个像素单位或者设备屏幕是圆形时,条件成立。

not

取反媒体查询结果,媒体查询结果不成立时返回true,否则返回false。例如:not screen and (min-height: 50) and (max-height: 600) 表示当应用高度小于50个像素单位或者大于600个像素单位时成立。

使用not运算符时必须指定媒体类型。

only

当整个表达式都匹配时,才会应用选择的样式,可以应用在防止某些较早的版本的浏览器上产生歧义的场景。一些较早版本的浏览器对于同时包含了媒体类型和媒体特征的语句会产生歧义,比如:screen and (min-height: 50)。老版本浏览器会将这句话理解成screen,从而导致仅仅匹配到媒体类型(screen),就应用了指定样式,使用only可以很好地规避这种情况。

使用only时必须指定媒体类型。

comma(, )

将多个媒体特征以“或”的方式连接成一个媒体查询,如果存在结果为true的媒体特征,则查询条件成立。其效果等同于or运算符。例如:screen and (min-height: 1000), (round-screen: true) 表示当应用高度大于等于1000个像素单位或者设备屏幕是圆形时,条件成立。

媒体范围操作符包括<=,>=,<,>,详细解释说明如下表。


媒体逻辑范围操作符

<=

小于等于,例如:screen and (height <= 50)

>=

大于等于,例如:screen and (height >= 600)

<

小于,例如:screen and (height < 50)

>

大于,例如:screen and (height > 600)


媒体特征(media-feature
媒体特征包括应用显示区域的宽高、设备分辨率以及设备的宽高等属性,详细说明如下。

height

应用页面可绘制区域的高度。

min-height

应用页面可绘制区域的最小高度。

max-height

应用页面可绘制区域的最大高度。

width

应用页面可绘制区域的宽度。

min-width

应用页面可绘制区域的最小宽度。

max-width

应用页面可绘制区域的最大宽度。

resolution

设备的分辨率,支持dpidppxdpcm单位。其中:

  • dpi表示每英寸中物理像素个数,1dpi ≈ 0.39dpcm

  • dpcm表示每厘米上的物理像素个数,1dpcm ≈ 2.54dpi

  • dppx表示每个px中的物理像素数(此单位按96px = 1英寸为基准,与页面中的px单位计算方式不同),1dppx = 96dpi

min-resolution

设备的最小分辨率。

max-resolution

设备的最大分辨率。

orientation

屏幕的方向。

可选值:

  • orientation: portrait(设备竖屏);

  • orientation: landscape(设备横屏)。

device-height

设备的高度。

min-device-height

设备的最小高度。

max-device-height

设备的最大高度。

device-width

设备的宽度。

device-type

设备的类型。

可选值:default、tablet

min-device-width

设备的最小宽度。

max-device-width

设备的最大宽度。

round-screen

屏幕类型,圆形屏幕为true,非圆形屏幕为false

dark-mode

系统为深色模式时为true,否则为false


场景示例
下例中使用媒体查询,实现屏幕横竖屏切换时,给页面文本应用添加不同的内容和样式

import mediaquery from '@ohos.mediaquery';
import window from '@ohos.window';
import common from '@ohos.app.ability.common';let portraitFunc = null;@Entry
@Component
struct MediaQueryExample {@State color: string = '#DB7093';@State text: string = 'Portrait';// 当设备横屏时条件成立listener = mediaquery.matchMediaSync('(orientation: landscape)');// 当满足媒体查询条件时,触发回调onPortrait(mediaQueryResult) {if (mediaQueryResult.matches) { // 若设备为横屏状态,更改相应的页面布局this.color = '#FFD700';this.text = 'Landscape';} else {this.color = '#DB7093';this.text = 'Portrait';}}aboutToAppear() {// 绑定当前应用实例portraitFunc = this.onPortrait.bind(this);// 绑定回调函数this.listener.on('change', portraitFunc);}// 改变设备横竖屏状态函数private changeOrientation(isLandscape: boolean) {// 获取UIAbility实例的上下文信息let context = getContext(this) as common.UIAbilityContext;// 调用该接口手动改变设备横竖屏状态window.getLastWindow(context).then((lastWindow) => {lastWindow.setPreferredOrientation(isLandscape ? window.Orientation.LANDSCAPE : window.Orientation.PORTRAIT)});}build() {Column({ space: 50 }) {Text(this.text).fontSize(50).fontColor(this.color)Text('Landscape').fontSize(50).fontColor(this.color).backgroundColor(Color.Orange).onClick(() => {this.changeOrientation(true);})Text('Portrait').fontSize(50).fontColor(this.color).backgroundColor(Color.Orange).onClick(() => {this.changeOrientation(false);})}.width('100%').height('100%')}
}

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

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

相关文章

单片机之串口通信

目录 串口介绍 通信的基本概念 并行通信和串行通信 同步通信和异步通信 串行异步通信方式 串行同步通信方式 通信协议 单片机常见通信接口 串行通信三种模式 串口参数 传输速度 ​串口的连接 电平标准 串行口的组成 串口数据缓冲寄存器 串行口控制寄存器 串口…

MTK8781安卓核心板_MT8781(Helio G99)核心板性能参数

MT8781安卓核心板搭载了八核CPU&#xff0c;其中包括两个主频高达2.2GHz的高性能Arm Cortex-A76处理器。这一处理器采用了台积电6纳米级芯片生产工艺&#xff0c;以及先进的3D图形功能的高性能Arm Mali G57级GPU。通过超快LPDDR4X内存和UFS 2.2存储供电&#xff0c;不仅提高了游…

【设计模式】中介者模式的应用

文章目录 1.概述2.中介者模式的适用场景2.1.用户界面事件2.2.分布式架构多模块通信 3.总结 1.概述 中介者模式&#xff08;Mediator Pattern&#xff09;是一种行为型设计模式&#xff0c;它用于解决对象间复杂、过度耦合的问题。当多个对象&#xff08;一般是两个以上的对象&…

vue跨域iframe自适应高度

前言 项目使用iframe引入百度页面&#xff0c;要做iframe自适应宽高。 开始 如果可以约定好&#xff0c;用postmessage传过来页面高度&#xff0c;那就可以直接设置了。 如果未约定传送页面高度&#xff0c;可以自行获取。 本例中&#xff1a; 1、由于跨域iframe加载较慢&am…

el-tree 树形控件

<el-tree :indent"5" // 相邻级节点间的水平缩进&#xff0c;单位为像素:props"defaultProps" ref"tree" :data"leftList":default-expanded-keys"defaultExpandedArr" // 设置默认展开指定节点 存储默认选中节点对应的…

|行业洞察·汽车|《2024新能源汽车行业及营销趋势报告-20页》

报告的主要内容解读&#xff1a; 新能源汽车行业概述及品牌分布&#xff1a; 近年来&#xff0c;中国新能源汽车销量增速高&#xff0c;市场占有率快速提升&#xff0c;成为汽车行业的重要增量。新能源汽车消费者趋向年轻化、女性化和高端化&#xff0c;对高科技、新体验有较高…

Android Studio控制台输出中文乱码问题

控制台乱码现象 安卓在调试阶段&#xff0c;需要查看app运行时的输出信息、出错提示信息。 乱码&#xff0c;会极大的阻碍开发者前进的信心&#xff0c;不能及时的根据提示信息定位问题&#xff0c;因此我们需要查看没有乱码的打印信息。 解决步骤&#xff1a; step1: 找到st…

STM32看似无法唤醒的一种异常现象分析

1. 引言 STM32 G0 系列产品具有丰富的外设和强大的处理性能以及良好的低功耗特性&#xff0c;被广泛用于各类工业产品中&#xff0c;包括一些需要低功耗需求的应用。 2. 问题描述 用户使用 STM32G0B1 作为汽车多媒体音响控制器的控制芯片&#xff0c;用来作为收音机频道存贮…

【漏洞复现】chatgpt pictureproxy.php SSRF漏洞(CVE-2024-27564)

0x01 漏洞概述 ChatGPT pictureproxy.php接口存在服务器端请求伪造 漏洞&#xff08;SSRF&#xff09; &#xff0c;未授权的攻击者可以通过将构建的 URL 注入 url参数来强制应用程序发出任意请求。 0x02 测绘语句 fofa: icon_hash"-1999760920" 0x03 漏洞复现 G…

gstreamer udp rtp发送本地视频文件

要使用 GStreamer 通过 RTP 发送本地媒体&#xff0c;您需要创建一个管道来读取媒体文件&#xff0c;根据需要对其进行编码&#xff0c;然后通过 RTP 发送。 以下是发送音频和视频文件的示例&#xff1a; 通过 RTP 发送本地音频文件&#xff1a; gst-launch-1.0 -v filesrc loc…

云渲染中途停止渲染会保存渲染结果吗?

在数字创作领域&#xff0c;云渲染已经逐渐成为了设计师们常用的渲染工具。然而&#xff0c;很多对云渲染功能不熟的用户来说&#xff0c;一些基础的操作疑问仍然困扰着他们。例如&#xff0c;自己用的云渲染中途停止渲染会不会保存渲染结果&#xff1f; 关于这个问题&#xf…

前后端分离开发【Yapi平台】【Swagger注解自动生成接口文档平台】

前后端分离开发 介绍开发流程Yapi&#xff08;api接口文档编写平台&#xff09;介绍 Swagger使用方式1). 导入knife4j的maven坐标2). 导入knife4j相关配置类3). 设置静态资源映射4). 在LoginCheckFilter中设置不需要处理的请求路径 查看接口文档常用注解注解介绍 当前项目中&am…

洲际酒店集团持续夯实领航之势 以新高度、新策略、新方向助推行业高质量发展

“ 旅、遇&#xff0c;正当时”&#xff0c;洲际酒店集团大中华区酒店巡展圆满落幕 2024年3月28日&#xff0c;中国上海 —— 作为最早进入中国市场的国际酒店管理集团之一&#xff0c;洲际酒店集团坚守“在中国&#xff0c;为中国”的承诺&#xff0c;以行业领跑者之势&#…

22.计算机中的数据存储

文章目录 一、计算机中的数据存储二、十进制1、十进制加法2、十进制减法 三、什么是二进制&#xff1f;二进制的运算过程 四、常见的进制五、计算机为什么要用二进制存储数据&#xff1f;六、进制之间的转换1、任意进制转十进制1&#xff09;二进制101转十进制8421快速转换法 2…

.jayy勒索病毒来袭:如何有效防范与应对?

导言&#xff1a; 在数字化时代&#xff0c;网络安全问题日益突出&#xff0c;其中勒索病毒成为了最为严重的威胁之一。.jayy勒索病毒是近年来出现的一种新型网络威胁&#xff0c;其危害性和传播速度令人震惊。本文91数据恢复将对.jayy勒索病毒进行介绍&#xff0c;并探讨有效…

android:elevation=“10dp“

这个代码片段中的 android:elevation"10dp" 是用来设置 Android 视图&#xff08;View&#xff09;的 Z 轴高度的属性。这个属性影响了视图的阴影和浮动效果。具体来说&#xff0c;它会使得视图在 Z 轴方向上相对于其他视图更高&#xff0c;从而产生阴影效果&#xf…

《QT实用小工具·一》电池电量组件

1、概述 项目源码放在文章末尾 本项目实现了一个电池电量控件&#xff0c;包含如下功能&#xff1a; 可设置电池电量&#xff0c;动态切换电池电量变化。可设置电池电量警戒值。可设置电池电量正常颜色和报警颜色。可设置边框渐变颜色。可设置电量变化时每次移动的步长。可设置…

Qlib-Server:量化库数据服务器

Qlib-Server:量化库数据服务器 介绍 Qlib-Server 是 Qlib 的配套服务器系统,它利用 Qlib 进行基本计算,并提供广泛的服务器系统和缓存机制。通过 Qlib-Server,可以以集中的方式管理 Qlib 提供的数据。 框架 Qlib 的客户端/服务器框架基于 WebSocket 构建,这是因为 WebS…

免费翻译pdf格式论文

进入谷歌翻译网址https://translate.google.com/?slauto&tlzh-CN&opdocs 将需要全文翻译的pdf放进去 选择英文到中文&#xff0c;然后点击翻译 可以选择打开译文或者下载译文&#xff0c;下载译文会下载到电脑上&#xff0c;打开译文会在浏览器打开。

Redis命令-List命令

4.6 Redis命令-List命令 Redis中的List类型与Java中的LinkedList类似&#xff0c;可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索。 特征也与LinkedList类似&#xff1a; 有序元素可以重复插入和删除快查询速度一般 常用来存储一个有序数据&#xff…