鸿蒙布局元素篇(七)-媒体查询(mediaquery)

197 阅读4分钟

概述

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

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

使用语法

语法规则包括媒体类型(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)
  }
}

实现效果

媒体查询.gif