鸿蒙多端开发Breakpoint原理探秘

372 阅读1分钟

使用

引入Breakpoint
import { BreakpointSystem } from '../common/BreakpointSystem';
实例化Breakpoint声明静态属性breakpointSystem,使用StorageProp获取全局设定的currentBreakpoint,值一般是‘sm’、‘md’、‘lg’,该属性为响应式可在DOM结构中使用
private breakpointSystem: BreakpointSystem = new BreakpointSystem();
@StorageProp('currentBreakpoint') curBp: string = Constants.BREAKPOINTS[1];
监听函数注册与解绑
aboutToAppear() {
  this.breakpointSystem.register();
}
aboutToDisappear() {
  this.breakpointSystem.unregister();
}

原理

声明断点arkts类型

import { mediaquery } from "@kit.ArkUI";
import Constants from './Constants';

interface Breakpoint {
  name: string,
  size: number,
  mediaQueryListener?: mediaquery.MediaQueryListener
}

Breakpoint

export class BreakpointSystem {
  private currentBreakpoint: string = Constants.BREAKPOINTS[1];
  private breakpoints: Breakpoint[] = [
    { name: 'sm', size: 320 },
    { name: 'md', size: 600 },
    { name: 'lg', size: 840 }
  ];

  private updateCurrentBreakpoint(breakpoint: string) {
    if (this.currentBreakpoint !== breakpoint) {
      this.currentBreakpoint = breakpoint;
      AppStorage.setOrCreate<string>('currentBreakpoint', this.currentBreakpoint);
      console.log('on current breakpoint: ' + this.currentBreakpoint);
    }
  }

  public register() {
    this.breakpoints.forEach((breakpoint: Breakpoint, index) => {
      let condition: string;
      if (index === this.breakpoints.length - 1) {
        condition = '(' + breakpoint.size + 'vp<=width' + ')';
      } else {
        condition = '(' + breakpoint.size + 'vp<=width<' + this.breakpoints[index + 1].size + 'vp)';
      }
      breakpoint.mediaQueryListener = mediaquery.matchMediaSync(condition);
      breakpoint.mediaQueryListener.on('change', (mediaQueryResult) => {
        if (mediaQueryResult.matches) {
          this.updateCurrentBreakpoint(breakpoint.name);
        }
      })
    })
  }

  public unregister() {
    this.breakpoints.forEach((breakpoint: Breakpoint) => {
      if (breakpoint.mediaQueryListener) {
        breakpoint.mediaQueryListener.off('change');
      }
    })
  }
}