媒体查询实现响应式布局

媒体查询

媒体查询常用于下面两种场景:

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

相比于上一节演示的 通过窗口对象监听尺寸变化,媒体查询的功能会更为强大

 核心用法

咱们分 2 个角度来看看如何使用媒体查询

  1. 整合步骤(重要)

导入模块 ---> 创建监听器 ---> 注册监听器 ---> 移除监听器

  1. 调整媒体查询条件(了解)
// 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或以上版本 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值