HarmonyOS鸿蒙Next中 响应式布局是如何实现的

一次开发,多端部署旨在编写一套代码,一次开发上架,即可以将应用多端按需部署。随着HarmonyOS生态不断拓展,终端设备形态日益多样化,应用的页面布局如何在一套代码中适配不同屏幕尺寸、屏幕方向的设备类型,成为一大挑战。为了解决这一问题,系统侧提供了响应式布局供开发者学习与使用

HarmonyOS鸿蒙Next中响应式布局可以通过下面几种方法实现:

1、GridRow GridCol栅格组件实现响应式布局

2、GridRow GridCol挪移布局实现响应式布局

3、let widthBp: WidthBreakpoint = this.uiContext.getWindowWidthBreakpoint(); 断点 结合Swiper组件、Grid组件、List组件、WaterFlow组件实现响应式布局。

image-20250405205919535.png

获取断点

系统在UIContext中提供系统接口getWindowWidthBreakpoint()getWindowHeightBreakpoint(),开发者需要在windowStage.loadContent()页面加载后获取横向和纵向断点值。

配置入口

EntryAbility.ets

 private uiContext?: UIContext;
  //当页面改变的时候触发的方法
  private onWindowSizeChange: (windowSize: window.Size) => void = (windowSize: window.Size) => {
    let widthBp: WidthBreakpoint = this.uiContext!.getWindowWidthBreakpoint();
    AppStorage.setOrCreate('currentWidthBreakpoint', widthBp);
    let heightBp: HeightBreakpoint = this.uiContext!.getWindowHeightBreakpoint();
    AppStorage.setOrCreate('currentHeightBreakpoint', heightBp);
  };
  // ...
  onWindowStageCreate(windowStage: window.WindowStage): void {
    // Main window is created, set main page for this ability
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');

    windowStage.loadContent('pages/Index', (err) => {
      if (err.code) {
        hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
        return;
      }
      hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.');
      // The system interface depends on UIContext and needs to be invoked after the page is loaded. It needs to be written in the loadContent callback function.
      windowStage.getMainWindow().then((data: window.Window) => {
        this.uiContext = data.getUIContext();
        let widthBp: WidthBreakpoint = this.uiContext.getWindowWidthBreakpoint();
        let heightBp: HeightBreakpoint = this.uiContext.getWindowHeightBreakpoint();
        AppStorage.setOrCreate('currentWidthBreakpoint', widthBp);
        AppStorage.setOrCreate('currentHeightBreakpoint', heightBp);
        data.on('windowSizeChange', this.onWindowSizeChange);
      }).catch((err: BusinessError) => {
        console.error(`Failed to obtain the main window. Cause code: ${err.code}, message: ${err.message}`);
      });
    });
  }

获取值

import { BreakpointType } from '../common/BreakpointType';

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  @StorageLink("currentWidthBreakpoint") currentWidthBreakpoint: WidthBreakpoint = WidthBreakpoint.WIDTH_SM;

  @StorageLink("currentHeightBreakpoint") currentHeightBreakpoint: HeightBreakpoint = HeightBreakpoint.HEIGHT_MD;

  build() {
    Column() {
      Text("width:"+this.currentWidthBreakpoint.toString()).fontSize(20)
      Text("height:"+this.currentHeightBreakpoint.toString()).fontSize(20)

     
    }
    .height('100%')
    .width('100%')
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Center)
  }
}

封装方法根据不同尺寸适配

BreakpointType.ets
export class BreakpointType<T> {
  sm: T;
  md: T;
  lg: T;

  constructor(sm: T, md: T, lg: T) {
    this.sm = sm;
    this.md = md;
    this.lg = lg;
  }

  getValue(currentWidthBreakpoint: number): T {
    if (currentWidthBreakpoint === 1) {
      return this.sm;
    }
    if (currentWidthBreakpoint === 2) {
      return this.md;
    }
    if (currentWidthBreakpoint === 3) {
      return this.lg;
    }
    return this.sm;
  }
}
调用方法改变字体
import { BreakpointType } from '../common/BreakpointType';

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  @StorageLink("currentWidthBreakpoint") currentWidthBreakpoint: WidthBreakpoint = WidthBreakpoint.WIDTH_SM;

  @StorageLink("currentHeightBreakpoint") currentHeightBreakpoint: HeightBreakpoint = HeightBreakpoint.HEIGHT_MD;

  build() {
    Column() {
      Text("width:"+this.currentWidthBreakpoint.toString()).fontSize(20)
      Text("height:"+this.currentHeightBreakpoint.toString()).fontSize(20)

      Text('Test'+new BreakpointType('14fp', '16fp', '18fp').getValue(this.currentWidthBreakpoint))
        .fontSize(new BreakpointType('14fp', '16fp', '18fp').getValue(this.currentWidthBreakpoint))
    }
    .height('100%')
    .width('100%')
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Center)
  }
}

更多关于HarmonyOS鸿蒙Next中 响应式布局是如何实现的的实战教程也可以访问 https://www.itying.com/category-93-b0.html

回到顶部