鸿蒙开发中组件宽高的获取

本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新

以下是鸿蒙(HarmonyOS)开发中获取组件宽高的几种核心方法,涵盖基础到高级场景,结合完整示例代码和性能对比:

一、基础获取方式

1. 链式布局回调(推荐)
@Entry
@Component
struct SizeExample {
  @State private width: number = 0;
  @State private height: number = 0;

  build() {
    Column() {
      Text('动态尺寸组件')
        .onAreaChange((oldValue, newValue) => {
          this.width = newValue.width;
          this.height = newValue.height;
          console.log(`新尺寸: ${this.width}x${this.height}`);
        })
        .borderWidth(1)
    }
  }
}

特点

  • 实时响应布局变化(旋转、折叠屏展开等)
  • 性能最优,无额外渲染开销
2. 全局窗口尺寸
import window from '@ohos.window';

async function getWindowSize() {
  const win = await window.getLastWindow(getContext(this));
  const size = await win.getWindowProperties();
  return { width: size.windowRect.width, height: size.windowRect.height };
}

适用场景

  • 全屏布局适配
  • 需要排除状态栏/导航栏区域时

二、高级测量技术

1. MeasureChild API(精确测量)
@Builder
function MeasureChild(builder: () => void) {
  Column() {
    builder()
  }.onMeasure((width, height) => {
    console.log(`预测量尺寸: ${width}x${height}`);
  });
}

// 使用示例
MeasureChild(() => {
  Text('需要测量的内容').fontSize(20)
})

原理

  • 在布局前计算理论尺寸
  • 不会触发实际渲染
2. 多帧后稳定尺寸(解决异步问题)
@State private stableWidth: number = 0;

Text('异步内容加载')
  .onAreaChange((_, newValue) => {
    setTimeout(() => {
      this.stableWidth = newValue.width; // 避免首帧错误
    }, 16); // 等待1帧
  })

三、特殊场景

1. 百分比尺寸计算
Column() {
  Row()
    .width('50%')
    .onAreaChange((_, newValue) => {
      console.log(`50%宽度实际值: ${newValue.width}px`);
    })
}

注意:百分比基于父组件尺寸

2. Flex布局剩余空间
Row() {
  Text('左侧').width(100)
  Blank() // 自动填充剩余空间
    .onAreaChange((_, newValue) => {
      console.log(`剩余宽度: ${newValue.width}`);
    })
}

四、性能优化技巧

1. 防抖测量(高频场景)
private debounceTimer: number = 0;

.onAreaChange((_, newValue) => {
  clearTimeout(this.debounceTimer);
  this.debounceTimer = setTimeout(() => {
    this.updateLayout(newValue); // 实际处理
  }, 50); // 50ms防抖
})

 五、案例:响应式图片容器

@Entry
@Component
struct ResponsiveImage {
  @State private imgHeight: number = 0;

  build() {
    Column() {
      Image($r('app.media.logo'))
        .onAreaChange((_, newValue) => {
          // 保持16:9比例
          this.imgHeight = newValue.width * 9 / 16;
        })
        .height(this.imgHeight)
    }
  }
}

六、方法对比总结

方法精度实时性性能影响适用场景
onAreaChange实时动态布局、动画
getWindowSize静态全屏适配
MeasureChild理论值预计算复杂布局预测量
多帧延迟获取延迟1帧异步内容加载

建议

  1. 优先使用onAreaChange + 防抖组合
  2. 需要精确预计算时选择MeasureChild
  3. 全屏尺寸使用窗口API

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值