深入解析:HarmonyOS中的媒体查询技术详解

概述

媒体查询(MediaQuery)是HarmonyOS中基于ArkUI的响应式设计核心工具,它通过监听设备属性(如屏幕方向、分辨率、深浅色模式、设备类型等)的变化,动态调整页面布局与样式。媒体查询广泛应用于移动设备适配,支持两种典型场景:

  1. 匹配布局:针对设备和应用的属性信息(如显示区域、深浅色、分辨率)设计相匹配的布局。
  2. 动态更新:当屏幕发生动态改变时(如分屏、横竖屏切换),同步更新应用页面布局。

媒体查询的使用流程

1. 导入模块

在ArkTS代码中导入媒体查询模块:

import { mediaquery } from '@kit.ArkUI';

2. 设置查询条件并绑定回调

通过matchMediaSync接口设置媒体查询条件,返回条件监听句柄,并绑定回调函数:

// 监听横屏事件(orientation: landscape)
let listener: mediaquery.MediaQueryListener = this.getUIContext().getMediaQuery().matchMediaSync('(orientation: landscape)');
// 定义回调函数
onPortrait(mediaQueryResult: mediaquery.MediaQueryResult) {
  if (mediaQueryResult.matches) {
    // 设备为横屏状态,更新布局
    this.color = '#FFD700';
    this.text = 'Landscape';
  } else {
    // 设备为竖屏状态,恢复默认布局
    this.color = '#DB7093';
    this.text = 'Portrait';
  }
}
// 注册回调
listener.on('change', this.onPortrait);

3. 清理资源(可选)

在组件销毁时取消回调监听:

aboutToDisappear() {
  listener.off('change'); // 解绑回调
}

媒体查询条件语法规则

媒体查询条件由媒体类型逻辑操作符媒体特征三部分组成,语法格式为:

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

1. 媒体类型(Media Type)

  • 说明:指定查询的设备类型,默认为screen(按屏幕参数查询)。
  • 示例:screen and (min-width: 600px)

2. 逻辑操作符(Media Logic Operations)

支持以下操作符组合复杂条件:

操作符说明
and多个条件“与”连接,所有条件成立时查询成立。例:screen and (device-type: tv) and (height <= 800)
or多个条件“或”连接,任一条件成立时查询成立。例:(max-height: 1000px) or (round-screen: true)
not取反查询结果,必须搭配screen使用。例:not screen and (min-height: 50px)
only必须搭配screen使用,防止老版本浏览器歧义。例:only screen and (orientation: portrait)
,(逗号)等效于or,多个条件“或”连接。例:(min-height: 1000px), (round-screen: true)

3. 范围操作符(Level 4+)

支持直接比较符号:

  • <=(小于等于):(height <= 800px)
  • >=(大于等于):(width >= 600px)
  • <(小于):(resolution < 2)
  • >(大于):(device-height > 1000px)

4. 媒体特征(Media Feature)

常用媒体特征包括:

特征说明
height/width应用页面可绘制区域的高度/宽度(单位支持vppx,默认px)。
orientation屏幕方向:portrait(竖屏)、landscape(横屏)。
device-type设备类型:defaultphonetablettvwearable等。
dark-mode深浅色模式:true(深色)、false(浅色)。
round-screen是否圆形屏幕:true/false
resolution设备分辨率(单位:dpidppxdpcm)。

示例条件

  • 横屏适配:(orientation: landscape)
  • 平板设备且宽度大于600px:screen and (device-type: tablet) and (min-width: 600px)
  • 深色模式或圆形屏幕:(dark-mode: true) or (round-screen: true)

实际应用场景示例

场景1:横竖屏切换更新布局

@Entry
@Component
struct MediaQueryExample {
  @State color: string = '#DB7093';
  @State text: string = 'Portrait';
  // 监听横屏
  listener: mediaquery.MediaQueryListener = this.getUIContext().getMediaQuery().matchMediaSync('(orientation: landscape)');
  onPortrait(mediaQueryResult: mediaquery.MediaQueryResult) {
    if (mediaQueryResult.matches) {
      this.color = '#FFD700'; // 横屏时颜色变为金色
      this.text = 'Landscape';
    } else {
      this.color = '#DB7093'; // 竖屏时恢复原色
      this.text = 'Portrait';
    }
  }
  aboutToAppear() {
    this.listener.on('change', this.onPortrait); // 绑定回调
  }
  build() {
    Column() {
      Text(this.text).fontSize(24).fontColor(this.color)
    }
    .width('100%').height('100%')
  }
}

场景2:根据设备类型显示不同内容

// 监听平板设备
let tabletListener = mediaquery.matchMediaSync('(device-type: tablet)');
tabletListener.on('change', (result: mediaquery.MediaQueryResult) => {
  if (result.matches) {
    promptAction.showToast({ message: '请使用手机访问', duration: 1500 });
  }
});

在Web开发中的媒体查询

HarmonyOS的Web组件同样支持CSS媒体查询,用于适配多设备:

/* 断点适配示例 */
.title {
  font-size: 14px;
}
@media (320px <= width < 600px) {
  .title { font-size: 16px; } /* 小屏设备 */
}
@media (840px <= width) {
  .title { font-size: 20px; } /* 大屏设备 */
}

注意事项

  1. API版本:媒体查询从API Version 8开始支持,部分功能在后续版本增强(如Level 4范围操作符需API 9+)。
  2. 上下文依赖:需在明确的UI上下文中使用(通过UIContext.getMediaQuery()获取实例)。
  3. 卡片限制:在卡片中使用时仅支持heightwidth媒体特征。
  4. 字符限制:媒体查询条件整体长度不超过512字符,单个条件不超过32字符。

总结

媒体查询是HarmonyOS响应式布局的核心能力,通过监听设备特征变化实现动态UI适配。开发者应熟练掌握其语法规则和使用流程,结合断点、栅格布局等技术,构建跨设备一致体验的应用。

posted on 2025-10-16 15:26  ljbguanli  阅读(10)  评论(0)    收藏  举报