onMeasureSize和PlaceChildren
- onMeasureSize和PlaceChildren 说明
- 官方使用示例
- 参考资料
onMeasureSize和PlaceChildren 说明
在Android开发中View的测量onMeasure和布局onLayout是自定义组件必备的两个方法,HarmonyOS对自定义布局也提供了两个方法:
onMeasureSize:组件每次布局时触发,计算子组件的尺寸,其执行时间先于onPlaceChildren。注意 不允许在onMeasureSize函数中改变状态变量。
onPlaceChildren:组件每次布局时触发,设置子组件的起始位置。
两个方法的参数详细含义参考自定义组件的自定义布局
官方使用示例
以下示例中,Index页面包含一个实现了自定义布局的自定义组件,且对应自定义组件的子组件通过index页面内的builder方式传入。
而在自定义组件中,调用了onMeasureSize
和onPlaceChildren
设置子组件大小和放置位置。例如,在本示例中,在onMeasureSize
中初始化组件大小size=100,后续的每一个子组件size会加上上一个子组件大小的一半,实现组件大小递增的效果。而在onPlaceChildren
中,定义startPos=300,设置每一个子组件的位置为startPos减去子组件自身的高度,所有子组件右下角一致在顶点位置(300,300),实现一个从右下角开始展示组件的类Stack组件。
// xxx.ets
@Entry
@Component
struct Index {build() {Column() {CustomLayout({ builder: ColumnChildren })}}
}// 通过builder的方式传递多个组件,作为自定义组件的一级子组件(即不包含容器组件,如Column)
@Builder
function ColumnChildren() {ForEach([1, 2, 3], (index: number) => { // 暂不支持lazyForEach的写法Text('S' + index).fontSize(30).width(100).height(100).borderWidth(2).offset({ x: 10, y: 20 })})
}@Component
struct CustomLayout {@BuilderdoNothingBuilder() {};@BuilderParam builder: () => void = this.doNothingBuilder;@State startSize: number = 100;result: SizeResult = {width: 0,height: 0};// 第一步:计算各子组件的大小onMeasureSize(selfLayoutInfo: GeometryInfo, children: Array<Measurable>, constraint: ConstraintSizeOptions) {let size = 100;children.forEach((child) => {let result: MeasureResult = child.measure({ minHeight: size, minWidth: size, maxWidth: size, maxHeight: size })size += result.width / 2;})this.result.width = 100;this.result.height = 400;return this.result;}// 第二步:放置各子组件的位置onPlaceChildren(selfLayoutInfo: GeometryInfo, children: Array<Layoutable>, constraint: ConstraintSizeOptions) {let startPos = 300;children.forEach((child) => {let pos = startPos - child.measureResult.height;child.layout({ x: pos, y: pos })})}build() {this.builder();}
}
运行效果
参考资料
ConstraintSizeOptions
Measurable10+
自定义组件的自定义布局
自定义组件的自定义布局2