媒体查询常用于下面两种场景:
- 针对设备和应用的属性信息(比如显示区域、深浅色、分辨率),设计出相匹配的布局。
- 当屏幕发生动态改变时(比如分屏、横竖屏切换),同步更新应用的页面布局。
相比于上一节演示的 通过窗口对象监听尺寸变化,媒体查询的功能会更为强大
核心用法
咱们分 2 个角度来看看如何使用媒体查询
- 整合步骤(重要)
导入模块 ---> 创建监听器 ---> 注册监听器 ---> 移除监听器
- 调整媒体查询条件(了解)
// 1. 导入 模块
import { mediaquery } from '@kit.ArkUI'
// 2. 创建监听器
const listenerXS: mediaquery.MediaQueryListener = mediaquery.matchMediaSync('(0vp<=width<320vp)');
const listenerSM: mediaquery.MediaQueryListener = mediaquery.matchMediaSync('(320vp<=width<600vp)');
// 3. 注册监听器
// 组件即将创建出来
aboutToAppear(): void {
// 添加回调函数
listenerXS.on('change', (res: mediaquery.MediaQueryResult) => {
console.log('changeRes:', JSON.stringify(res))
// 执行逻辑
})
listenerSM.on('change', (res: mediaquery.MediaQueryResult) => {
console.log('changeRes:', JSON.stringify(res))
// 执行逻辑
})
}
// 4. 移除监听器
// 即将销毁
aboutToDisappear(): void {
// 移除监听 避免性能浪费
listenerXS.off('change')
listenerSM.off('change')
}
注意:
写范围的时候不要省略小括号
试一试:
参考示例代码:完成 4 个断点的监听
断点名称 | 取值范围(vp) | 设备 |
xs | [0, 320) | 手表等超小屏 |
sm | [320, 600) | 手机竖屏 |
md | [600, 840) | 手机横屏,折叠屏 |
lg | [840, +∞) | 平板,2in1 设备 |
// 1. 导入媒体查询模块
import { mediaquery } from '@kit.ArkUI'
// 2. 创建监听器
const listenerXS: mediaquery.MediaQueryListener = mediaquery.matchMediaSync('(0vp<=width<320vp)')
const listenerSM: mediaquery.MediaQueryListener = mediaquery.matchMediaSync('(320vp<=width<600vp)')
const listenerMD: mediaquery.MediaQueryListener = mediaquery.matchMediaSync('(600vp<=width<840vp)')
const listenerLG: mediaquery.MediaQueryListener = mediaquery.matchMediaSync('(840vp<=width)')
@Entry
@Component
struct Demo09 {
@State breakPoint: string = ''
@State bgColor: Color = Color.White
aboutToAppear(): void {
// 3. 注册监听器
listenerXS.on('change', (res: mediaquery.MediaQueryResult)=>{
// 尺寸符合要求则结果为true {"matches":true,"media":"(0vp<=width<320vp)"}
// console.log('mkLog', JSON.stringify(res))
if(res.matches){
this.breakPoint = 'XS'
this.bgColor = Color.Red
}
})
listenerSM.on('change', (res: mediaquery.MediaQueryResult)=>{
// console.log('mkLog', JSON.stringify(res))
if(res.matches){
this.breakPoint = 'SM'
this.bgColor = Color.Green
}
})
listenerMD.on('change', (res: mediaquery.MediaQueryResult)=>{
// console.log('mkLog', JSON.stringify(res))
if(res.matches){
this.breakPoint = 'MD'
this.bgColor = Color.Blue
}
})
listenerLG.on('change', (res: mediaquery.MediaQueryResult)=>{
// console.log('mkLog', JSON.stringify(res))
if(res.matches){
this.breakPoint = 'LG'
this.bgColor = Color.Pink
}
})
}
aboutToDisappear(): void {
// 4. 移除监听器
listenerXS.off('change')
listenerSM.off('change')
listenerMD.off('change')
listenerLG.off('change')
}
build() {
RelativeContainer() {
Text(this.breakPoint)
.id('Demo09HelloWorld')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
}
.height('100%')
.width('100%')
.expandSafeArea([SafeAreaType.SYSTEM])
.backgroundColor(this.bgColor)
}
}
效果如下
适用HarmonyOS NEXT / API12或以上版本