本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
以下是鸿蒙(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帧 | 低 | 异步内容加载 |
建议:
- 优先使用
onAreaChange
+ 防抖组合 - 需要精确预计算时选择
MeasureChild
- 全屏尺寸使用窗口API