概述
媒体查询作为响应式设计的核心,在移动设备上应用十分广泛。媒体查询可根据不同设备类型或同设备不同状态修改应用的样式。媒体查询常用于下面两种场景:
- 针对设备和应用的属性信息(比如显示区域、深浅色、分辨率),设计出相匹配的布局。
- 当屏幕发生动态改变时(比如分屏、横竖屏切换),同步更新应用的页面布局。
使用语法
语法规则包括媒体类型(media-type)、媒体逻辑操作(media-logic-operations)和媒体特征(media-feature),[media-type] [media-logic-operations] [(media-feature)]。
screen and (orientation: landscape)
媒体类型(media-type)
| 类型 | 描述 |
|---|---|
| screen | 按屏幕相关参数进行媒体查询。 |
媒体逻辑操作(media-logic-operations))
| 类型 | 描述 |
|---|---|
| and | 与 |
| or | 或 |
| not | 非 |
| only | 也是与的意思,为了解决老浏览器识别问题,用only必须指定媒体类型 |
| comma(, ) | 将多个媒体特征以“或”的方式连接成一个媒体查询,例如screen and (min-height: 1000), (round-screen: true) |
媒体特征(media-feature)
| 类型 | 描述 |
|---|---|
| height | 应用页面可绘制区域的高度。 |
| min-height | 应用页面可绘制区域的最小高度。 |
| max-height | 应用页面可绘制区域的最大高度。 |
| width | 应用页面可绘制区域的宽度。 |
| min-width | 应用页面可绘制区域的最小宽度。 |
| max-width | 应用页面可绘制区域的最大宽度。 |
| resolution | 设备的分辨率 |
| min-resolution | 设备的最小分辨率。 |
| max-resolution | 设备的最大分辨率。 |
| orientation | 屏幕的方向。可选值:orientation: portrait(设备竖屏);orientation: landscape(设备横屏)。 |
| 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';
let listener = mediaquery.matchMediaSync('screen and (orientation: landscape)'); //监听横屏事件
// 注册
listener.on('change', 此处放变化的回调函数);
// 卸载
listener.off('change');
通过实现功能的方式展示以上特性的用法。包含以下功能。
- 注册两个监听器,①:监听横竖屏切换,②:监听屏幕宽度变化。基于变化修改内容
- 添加可以修改横竖屏的功能按钮
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 = 'block';
// 当设备横屏时条件成立 竖屏 Portrait 横屏 landscape
@State text: string = 'Portrait';
@State widthText: string = 'width小于1700';
// 注册监听是否为竖屏的监听器
listener = mediaquery.matchMediaSync('(orientation: landscape)');
// 注册监听是屏幕宽度是否大于1700监听器
widthListener = mediaquery.matchMediaSync('screen and (width > 1700)');
// 当满足横竖屏媒体查询条件时,触发的回调函数
onPortrait(mediaQueryResult) {
if (mediaQueryResult.matches) { // 若设备为横屏状态,更改相应的页面布局
this.text = 'Landscape竖屏';
} else {
this.text = 'Portrait横屏';
}
}
// 当满足宽度查询条件时,触发的回调函数
onWidthChange(mediaQueryResult) {
console.log(`${mediaQueryResult}`)
if (mediaQueryResult.matches) { // 若设备为横屏状态,更改相应的页面布局
this.widthText = 'width>1700++++';
} else {
this.widthText = 'width<1700----';
}
}
// 生命周期函数,在build构建函数之前绑定屏幕监听器的回调函数
aboutToAppear() {
// 绑定当前应用实例
portraitFunc = this.onPortrait.bind(this);
// 绑定回调函数
this.listener.on('change', portraitFunc);
this.widthListener.on('change', this.onWidthChange.bind(this))
}
// 改变设备横竖屏状态函数
private changeOrientation(isLandscape: boolean) {
// 获取UIAbility实例的上下文信息
let context = getContext(this) as common.UIAbilityContext;
// 调用该接口手动改变设备横竖屏状态
window.getLastWindow(context).then((lastWindow) => {
// isLandscape 为ture,改为横屏;false,改为竖屏
lastWindow.setPreferredOrientation(isLandscape ? window.Orientation.LANDSCAPE : window.Orientation.PORTRAIT)
});
}
build() {
Column({ space: 30 }) {
Text(this.text).fontSize(40).fontColor(this.color)
Text(this.widthText).fontSize(40).fontColor(this.color)
Button('Landscape-点击改为横屏').fontSize(20).fontColor(this.color).backgroundColor(Color.Orange)
.onClick(() => {
// 修改为横屏
this.changeOrientation(true);
})
Button('Portrait-点击改为竖屏').fontSize(20).fontColor(this.color).backgroundColor(Color.Orange)
.onClick(() => {
// 修改为竖屏
this.changeOrientation(false);
})
}
.width('100%').height('100%').justifyContent(FlexAlign.Center)
}
}
实现效果